azerclaw 1.0.2 → 1.1.1

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 (73) hide show
  1. package/bin/azerclaw.ts +294 -19
  2. package/dist/bin/azerclaw.d.ts +14 -8
  3. package/dist/bin/azerclaw.d.ts.map +1 -1
  4. package/dist/bin/azerclaw.js +259 -18
  5. package/dist/bin/azerclaw.js.map +1 -1
  6. package/dist/src/cli/animations/fish.d.ts +9 -8
  7. package/dist/src/cli/animations/fish.d.ts.map +1 -1
  8. package/dist/src/cli/animations/fish.js +105 -132
  9. package/dist/src/cli/animations/fish.js.map +1 -1
  10. package/dist/src/cli/commands/chat.d.ts +16 -0
  11. package/dist/src/cli/commands/chat.d.ts.map +1 -1
  12. package/dist/src/cli/commands/chat.js +156 -35
  13. package/dist/src/cli/commands/chat.js.map +1 -1
  14. package/dist/src/cli/commands/config.d.ts +1 -0
  15. package/dist/src/cli/commands/config.d.ts.map +1 -1
  16. package/dist/src/cli/commands/config.js +28 -11
  17. package/dist/src/cli/commands/config.js.map +1 -1
  18. package/dist/src/cli/commands/onboard.d.ts +12 -1
  19. package/dist/src/cli/commands/onboard.d.ts.map +1 -1
  20. package/dist/src/cli/commands/onboard.js +384 -92
  21. package/dist/src/cli/commands/onboard.js.map +1 -1
  22. package/dist/src/cli/commands/run.d.ts.map +1 -1
  23. package/dist/src/cli/commands/run.js +2 -2
  24. package/dist/src/cli/commands/run.js.map +1 -1
  25. package/dist/src/cli/commands/settings.d.ts +31 -0
  26. package/dist/src/cli/commands/settings.d.ts.map +1 -0
  27. package/dist/src/cli/commands/settings.js +566 -0
  28. package/dist/src/cli/commands/settings.js.map +1 -0
  29. package/dist/src/cli/commands/tui.d.ts +3 -0
  30. package/dist/src/cli/commands/tui.d.ts.map +1 -1
  31. package/dist/src/cli/commands/tui.js +211 -71
  32. package/dist/src/cli/commands/tui.js.map +1 -1
  33. package/dist/src/config/manager.d.ts +121 -9
  34. package/dist/src/config/manager.d.ts.map +1 -1
  35. package/dist/src/config/manager.js +363 -11
  36. package/dist/src/config/manager.js.map +1 -1
  37. package/dist/src/config/schema.d.ts +217 -1
  38. package/dist/src/config/schema.d.ts.map +1 -1
  39. package/dist/src/config/schema.js +55 -7
  40. package/dist/src/config/schema.js.map +1 -1
  41. package/dist/src/core/runtime.d.ts +8 -0
  42. package/dist/src/core/runtime.d.ts.map +1 -1
  43. package/dist/src/core/runtime.js +29 -13
  44. package/dist/src/core/runtime.js.map +1 -1
  45. package/dist/src/core/server.d.ts +15 -0
  46. package/dist/src/core/server.d.ts.map +1 -0
  47. package/dist/src/core/server.js +127 -0
  48. package/dist/src/core/server.js.map +1 -0
  49. package/dist/src/providers/router.d.ts.map +1 -1
  50. package/dist/src/providers/router.js +16 -0
  51. package/dist/src/providers/router.js.map +1 -1
  52. package/dist/src/tools/advanced.d.ts.map +1 -1
  53. package/dist/src/tools/advanced.js +3 -0
  54. package/dist/src/tools/advanced.js.map +1 -1
  55. package/dist/src/tools/filesystem.d.ts.map +1 -1
  56. package/dist/src/tools/filesystem.js +4 -0
  57. package/dist/src/tools/filesystem.js.map +1 -1
  58. package/dist/src/tools/index.d.ts +9 -0
  59. package/dist/src/tools/index.d.ts.map +1 -0
  60. package/dist/src/tools/index.js +73 -0
  61. package/dist/src/tools/index.js.map +1 -0
  62. package/dist/src/tools/loader.d.ts +14 -0
  63. package/dist/src/tools/loader.d.ts.map +1 -0
  64. package/dist/src/tools/loader.js +115 -0
  65. package/dist/src/tools/loader.js.map +1 -0
  66. package/dist/src/tools/registry.d.ts +27 -0
  67. package/dist/src/tools/registry.d.ts.map +1 -1
  68. package/dist/src/tools/registry.js +80 -5
  69. package/dist/src/tools/registry.js.map +1 -1
  70. package/dist/src/tools/shell.d.ts.map +1 -1
  71. package/dist/src/tools/shell.js +1 -0
  72. package/dist/src/tools/shell.js.map +1 -1
  73. package/package.json +2 -1
package/bin/azerclaw.ts CHANGED
@@ -7,14 +7,20 @@
7
7
  * Inspired by OpenClaw, themed with a fish 🐟 instead of a lobster.
8
8
  *
9
9
  * Usage:
10
- * azerclaw — Launch TUI (or onboard if first run)
11
- * azerclaw chat — Interactive chat
12
- * azerclaw run "task" — Execute a task
13
- * azerclaw tui — Premium terminal UI
14
- * azerclaw onboard — Setup wizard
15
- * azerclaw config — Manage configuration
16
- * azerclaw models Manage AI models
17
- * azerclaw doctor Health check
10
+ * azerclaw — Launch interactive session (or onboard if first run)
11
+ * azerclaw chat — Interactive chat
12
+ * azerclaw run "task" — Execute a task
13
+ * azerclaw tui — Premium terminal UI
14
+ * azerclaw onboard — Setup wizard
15
+ * azerclaw config — Manage configuration
16
+ * azerclaw config provider Switch provider
17
+ * azerclaw config model Switch model
18
+ * azerclaw config apikey — Set API key
19
+ * azerclaw config fallback — Configure fallback
20
+ * azerclaw init — Initialize project (AZERCLAW.md)
21
+ * azerclaw models — Manage AI models
22
+ * azerclaw doctor — Health check
23
+ * azerclaw status — Show current status
18
24
  */
19
25
 
20
26
  const { Command } = require('commander');
@@ -22,25 +28,52 @@ const chalk = require('chalk');
22
28
  const { playSplashScreen, printQuickSplash, fishError, fishInfo, fishSuccess } = require('../src/cli/animations/fish');
23
29
  const { getConfigManager } = require('../src/config/manager');
24
30
 
25
- const VERSION = '1.0.0';
31
+ const VERSION = '1.1.1';
26
32
  const program = new Command();
27
33
 
28
34
  // ─── Program Setup ──────────────────────────────────────────────
29
35
 
30
36
  program
31
37
  .name('azerclaw')
32
- .description('🐟 AZERCLAW — Your AI, Your Keys, Your Way')
38
+ .description('🐟 AZERCLAW — Diabolical AI · Scorched Earth · Your Way')
33
39
  .version(VERSION, '-v, --version', 'Display version')
34
40
  .option('--no-splash', 'Skip the splash screen')
35
- .option('--no-color', 'Disable colors');
41
+ .option('--no-color', 'Disable colors')
42
+ .hook('preAction', async () => {
43
+ // Global initialization
44
+ const { registerAllTools } = require('../src/tools');
45
+ await registerAllTools();
46
+ });
36
47
 
37
48
  // ─── Default Action (no command) ────────────────────────────────
38
49
 
39
50
  program
40
- .action(async (opts: any) => {
51
+ .argument('[task]', 'Optional task to execute immediately (one-off mode)')
52
+ .action(async (task: string | undefined, opts: any) => {
41
53
  const config = getConfigManager();
42
54
  config.resolveEnvOverrides();
43
55
 
56
+ // Check for positional task
57
+ if (task) {
58
+ const { runTask } = require('../src/cli/commands/run');
59
+ await runTask(task.trim(), opts);
60
+ return;
61
+ }
62
+
63
+ // Check for piped input (stdin)
64
+ if (!process.stdin.isTTY) {
65
+ let input = '';
66
+ process.stdin.setEncoding('utf-8');
67
+ for await (const chunk of process.stdin) {
68
+ input += chunk;
69
+ }
70
+ if (input.trim()) {
71
+ const { runTask } = require('../src/cli/commands/run');
72
+ await runTask(input.trim(), opts);
73
+ return;
74
+ }
75
+ }
76
+
44
77
  if (config.isFirstRun()) {
45
78
  // First run: show full splash + onboard
46
79
  await playSplashScreen(VERSION);
@@ -60,16 +93,30 @@ program
60
93
  .description('Start an interactive chat session')
61
94
  .option('-m, --model <model>', 'Override the default model')
62
95
  .option('-p, --provider <provider>', 'Override the default provider')
96
+ .option('-f, --file <path>', 'Include a file in the conversation context')
63
97
  .action(async (opts: any) => {
64
98
  const config = getConfigManager();
65
99
  config.resolveEnvOverrides();
66
100
 
101
+ // Apply CLI flag overrides
102
+ if (opts.model || opts.provider) {
103
+ config.applyRuntimeOverrides(opts);
104
+ }
105
+
106
+ if (opts.file) {
107
+ const fs = require('fs');
108
+ if (fs.existsSync(opts.file)) {
109
+ const content = fs.readFileSync(opts.file, 'utf-8');
110
+ opts.initialMessage = `I've attached the file: ${opts.file}\n\n\`\`\`\n${content}\n\`\`\``;
111
+ }
112
+ }
113
+
67
114
  if (!opts.parent?.splash === false) {
68
115
  printQuickSplash(VERSION);
69
116
  }
70
117
 
71
118
  if (config.isFirstRun()) {
72
- fishInfo('First time? Run `azerclaw onboard` to configure your AI providers.');
119
+ fishInfo('First time? Running setup wizard...');
73
120
  const { runOnboard } = require('../src/cli/commands/onboard');
74
121
  await runOnboard();
75
122
  return;
@@ -82,17 +129,61 @@ program
82
129
  // ─── Run Command ────────────────────────────────────────────────
83
130
 
84
131
  program
85
- .command('run <task>')
132
+ .command('run [task]')
86
133
  .description('Execute a single task')
87
134
  .option('-m, --model <model>', 'Override the default model')
135
+ .option('-p, --provider <provider>', 'Override the default provider')
136
+ .option('-f, --file <path>', 'Include a file in the task context')
88
137
  .option('-V, --verbose', 'Show tool calls in detail')
89
- .action(async (task: string, opts: any) => {
138
+ .action(async (task: string | undefined, opts: any) => {
90
139
  const config = getConfigManager();
91
140
  config.resolveEnvOverrides();
141
+
142
+ if (opts.model || opts.provider) {
143
+ config.applyRuntimeOverrides(opts);
144
+ }
145
+
146
+ let finalTask = task || '';
147
+
148
+ // Handle piped input if task is missing
149
+ if (!finalTask && !process.stdin.isTTY) {
150
+ process.stdin.setEncoding('utf-8');
151
+ for await (const chunk of process.stdin) {
152
+ finalTask += chunk;
153
+ }
154
+ }
155
+
156
+ if (!finalTask.trim()) {
157
+ fishError('No task provided. Usage: azerclaw run "your task" or echo "task" | azerclaw run');
158
+ return;
159
+ }
160
+
161
+ if (opts.file) {
162
+ const fs = require('fs');
163
+ if (fs.existsSync(opts.file)) {
164
+ const content = fs.readFileSync(opts.file, 'utf-8');
165
+ finalTask = `Context from file ${opts.file}:\n\`\`\`\n${content}\n\`\`\`\n\nTask: ${finalTask}`;
166
+ }
167
+ }
168
+
92
169
  printQuickSplash(VERSION);
93
170
 
94
171
  const { runTask } = require('../src/cli/commands/run');
95
- await runTask(task, opts);
172
+ await runTask(finalTask.trim(), opts);
173
+ });
174
+
175
+ // ─── Serve Command ──────────────────────────────────────────────
176
+
177
+ program
178
+ .command('serve')
179
+ .description('Start the AZERCLAW local WebSocket daemon for desktop apps')
180
+ .option('-p, --port <port>', 'Port to listen on', '8080')
181
+ .action((opts: any) => {
182
+ printQuickSplash(VERSION);
183
+ const { AzerclawServer } = require('../src/core/server');
184
+ const port = parseInt(opts.port, 10) || 8080;
185
+ const server = new AzerclawServer(port);
186
+ server.start();
96
187
  });
97
188
 
98
189
  // ─── TUI Command ────────────────────────────────────────────────
@@ -100,10 +191,16 @@ program
100
191
  program
101
192
  .command('tui')
102
193
  .description('Launch the premium terminal UI')
103
- .action(async () => {
194
+ .option('-m, --model <model>', 'Override the default model')
195
+ .option('-p, --provider <provider>', 'Override the default provider')
196
+ .action(async (opts: any) => {
104
197
  const config = getConfigManager();
105
198
  config.resolveEnvOverrides();
106
199
 
200
+ if (opts.model || opts.provider) {
201
+ config.applyRuntimeOverrides(opts);
202
+ }
203
+
107
204
  const { runTUI } = require('../src/cli/commands/tui');
108
205
  await runTUI();
109
206
  });
@@ -119,6 +216,28 @@ program
119
216
  await runOnboard();
120
217
  });
121
218
 
219
+ // ─── Init Command (Project) ────────────────────────────────────
220
+
221
+ program
222
+ .command('init')
223
+ .description('Initialize AZERCLAW for this project (creates AZERCLAW.md + .azerclaw/)')
224
+ .action(() => {
225
+ const { initProject } = require('../src/cli/commands/settings');
226
+ initProject();
227
+ });
228
+
229
+ // ─── Status Command ─────────────────────────────────────────────
230
+
231
+ program
232
+ .command('status')
233
+ .description('Show current model, provider, auth, and project status')
234
+ .action(() => {
235
+ const config = getConfigManager();
236
+ config.resolveEnvOverrides();
237
+ const { showStatus } = require('../src/cli/commands/settings');
238
+ showStatus();
239
+ });
240
+
122
241
  // ─── Config Command ─────────────────────────────────────────────
123
242
 
124
243
  const configCmd = program
@@ -157,6 +276,67 @@ configCmd
157
276
  configReset();
158
277
  });
159
278
 
279
+ configCmd
280
+ .command('provider [name]')
281
+ .description('Switch the active AI provider (interactive if no name given)')
282
+ .action(async (name?: string) => {
283
+ if (name) {
284
+ const { cliSwitchProvider } = require('../src/cli/commands/settings');
285
+ cliSwitchProvider(name);
286
+ } else {
287
+ const { interactiveProviderSwitch } = require('../src/cli/commands/settings');
288
+ await interactiveProviderSwitch();
289
+ }
290
+ });
291
+
292
+ configCmd
293
+ .command('model [id]')
294
+ .description('Switch the default model (interactive if no id given)')
295
+ .option('-p, --provider <provider>', 'Target provider (defaults to active)')
296
+ .action(async (id?: string, opts?: any) => {
297
+ if (id) {
298
+ const { cliSwitchModel } = require('../src/cli/commands/settings');
299
+ cliSwitchModel(id, opts?.provider);
300
+ } else {
301
+ const { interactiveModelSwitch } = require('../src/cli/commands/settings');
302
+ await interactiveModelSwitch();
303
+ }
304
+ });
305
+
306
+ configCmd
307
+ .command('apikey [provider] [key]')
308
+ .description('Set or change an API key (interactive if no args given)')
309
+ .action(async (provider?: string, key?: string) => {
310
+ if (provider && key) {
311
+ const { cliSetApiKey } = require('../src/cli/commands/settings');
312
+ cliSetApiKey(provider, key);
313
+ } else {
314
+ const { interactiveApiKeyChange } = require('../src/cli/commands/settings');
315
+ await interactiveApiKeyChange();
316
+ }
317
+ });
318
+
319
+ configCmd
320
+ .command('fallback [provider]')
321
+ .description('Set or change the fallback provider (interactive if no arg given)')
322
+ .action(async (provider?: string) => {
323
+ if (provider) {
324
+ const { cliSetFallback } = require('../src/cli/commands/settings');
325
+ cliSetFallback(provider);
326
+ } else {
327
+ const { interactiveFallbackConfig } = require('../src/cli/commands/settings');
328
+ await interactiveFallbackConfig();
329
+ }
330
+ });
331
+
332
+ configCmd
333
+ .command('settings')
334
+ .description('Open the full interactive settings menu')
335
+ .action(async () => {
336
+ const { interactiveSettingsMenu } = require('../src/cli/commands/settings');
337
+ await interactiveSettingsMenu();
338
+ });
339
+
160
340
  // Default config action (no sub-command) shows list
161
341
  configCmd.action(() => {
162
342
  const { configList } = require('../src/cli/commands/config');
@@ -329,8 +509,6 @@ workflowCmd
329
509
  .action(async (id: string, token: string) => {
330
510
  printQuickSplash(VERSION);
331
511
  const { FishboneEngine } = require('../src/workflow/engine');
332
- // Note: In a real system, the engine state needs to be persisted to resume across process boundaries.
333
- // For now, this invokes the API.
334
512
  const engine = new FishboneEngine();
335
513
  const resumed = await engine.resume(id, token);
336
514
  if (resumed) {
@@ -340,6 +518,103 @@ workflowCmd
340
518
  }
341
519
  });
342
520
 
521
+ // ─── Tools Command ──────────────────────────────────────────────
522
+
523
+ const toolsCmd = program
524
+ .command('tools')
525
+ .description('Manage AZERCLAW tools and plugins');
526
+
527
+ toolsCmd
528
+ .command('list')
529
+ .description('List all registered tools')
530
+ .action(() => {
531
+ const { getToolRegistry } = require('../src/tools/registry');
532
+ const registry = getToolRegistry();
533
+ const tools = registry.getAll();
534
+
535
+ console.log('');
536
+ fishInfo(`Registered Tools (${tools.length})`);
537
+ console.log('');
538
+
539
+ const Table = require('cli-table3');
540
+ const table = new Table({
541
+ head: [chalk.hex('#60a5fa')('Name'), chalk.hex('#60a5fa')('Version'), chalk.hex('#60a5fa')('Description')],
542
+ colWidths: [20, 10, 50],
543
+ wordWrap: true,
544
+ });
545
+
546
+ tools.forEach((tool: any) => {
547
+ table.push([
548
+ chalk.hex('#34d399')(tool.name),
549
+ chalk.dim(tool.version),
550
+ tool.description.slice(0, 100) + (tool.description.length > 100 ? '...' : '')
551
+ ]);
552
+ });
553
+
554
+ console.log(table.toString());
555
+ });
556
+
557
+ toolsCmd
558
+ .command('info <name>')
559
+ .description('Show detailed information about a tool')
560
+ .action((name: string) => {
561
+ const { getToolRegistry } = require('../src/tools/registry');
562
+ const tool = getToolRegistry().get(name);
563
+ if (!tool) {
564
+ fishError(`Tool not found: ${name}`);
565
+ return;
566
+ }
567
+
568
+ console.log('');
569
+ console.log(chalk.hex('#60a5fa').bold(`Tool: ${tool.name}`));
570
+ console.log(chalk.dim(`Version: ${tool.version}`));
571
+ if (tool.author) console.log(chalk.dim(`Author: ${tool.author}`));
572
+ console.log('');
573
+ console.log(tool.description);
574
+ console.log('');
575
+ console.log(chalk.hex('#fbbf24')('Parameters:'));
576
+ console.log(JSON.stringify(tool.parameters, null, 2));
577
+ });
578
+
579
+ toolsCmd
580
+ .command('docs')
581
+ .description('Generate markdown documentation for all tools')
582
+ .option('-o, --output <file>', 'Output file path', 'TOOLS.md')
583
+ .action(async (opts: any) => {
584
+ const { getToolRegistry } = require('../src/tools/registry');
585
+ const fs = require('fs');
586
+ const path = require('path');
587
+
588
+ const tools = getToolRegistry().getAll();
589
+ let markdown = `# 🐟 AZERCLAW Tools Documentation\n\n`;
590
+ markdown += `Generated on ${new Date().toLocaleDateString()}\n\n`;
591
+
592
+ tools.forEach((tool: any) => {
593
+ markdown += `## ${tool.name} (v${tool.version})\n\n`;
594
+ markdown += `${tool.description}\n\n`;
595
+ markdown += `### Parameters\n\n\`\`\`json\n${JSON.stringify(tool.parameters, null, 2)}\n\`\`\`\n\n`;
596
+ markdown += `---\n\n`;
597
+ });
598
+
599
+
600
+ const outputPath = path.resolve(process.cwd(), opts.output);
601
+ fs.writeFileSync(outputPath, markdown);
602
+ fishSuccess(`Documentation generated at ${outputPath}`);
603
+ });
604
+
605
+ toolsCmd
606
+ .command('install <url_or_path>')
607
+ .description('Install a tool plugin from a URL or local file (coming soon)')
608
+ .action((src: string) => {
609
+ fishInfo(`Plugin installation for '${src}' will be available in the next release.`);
610
+ fishInfo('For now, manually place your .js/.ts files in the ./plugins directory.');
611
+ });
612
+
613
+ toolsCmd.action(() => {
614
+ program.helpInformation();
615
+ });
616
+
343
617
  // ─── Parse & Run ────────────────────────────────────────────────
344
618
 
619
+
345
620
  program.parse(process.argv);
@@ -6,14 +6,20 @@
6
6
  * Inspired by OpenClaw, themed with a fish 🐟 instead of a lobster.
7
7
  *
8
8
  * Usage:
9
- * azerclaw — Launch TUI (or onboard if first run)
10
- * azerclaw chat — Interactive chat
11
- * azerclaw run "task" — Execute a task
12
- * azerclaw tui — Premium terminal UI
13
- * azerclaw onboard — Setup wizard
14
- * azerclaw config — Manage configuration
15
- * azerclaw models Manage AI models
16
- * azerclaw doctor Health check
9
+ * azerclaw — Launch interactive session (or onboard if first run)
10
+ * azerclaw chat — Interactive chat
11
+ * azerclaw run "task" — Execute a task
12
+ * azerclaw tui — Premium terminal UI
13
+ * azerclaw onboard — Setup wizard
14
+ * azerclaw config — Manage configuration
15
+ * azerclaw config provider Switch provider
16
+ * azerclaw config model Switch model
17
+ * azerclaw config apikey — Set API key
18
+ * azerclaw config fallback — Configure fallback
19
+ * azerclaw init — Initialize project (AZERCLAW.md)
20
+ * azerclaw models — Manage AI models
21
+ * azerclaw doctor — Health check
22
+ * azerclaw status — Show current status
17
23
  */
18
24
  export {};
19
25
  //# sourceMappingURL=azerclaw.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"azerclaw.d.ts","sourceRoot":"","sources":["../../bin/azerclaw.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;GAeG"}
1
+ {"version":3,"file":"azerclaw.d.ts","sourceRoot":"","sources":["../../bin/azerclaw.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG"}