chainlesschain 0.37.8 → 0.37.10

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 (59) hide show
  1. package/README.md +403 -8
  2. package/bin/chainlesschain.js +4 -0
  3. package/package.json +7 -2
  4. package/src/commands/agent.js +30 -0
  5. package/src/commands/ask.js +114 -0
  6. package/src/commands/audit.js +286 -0
  7. package/src/commands/auth.js +387 -0
  8. package/src/commands/browse.js +184 -0
  9. package/src/commands/chat.js +35 -0
  10. package/src/commands/db.js +152 -0
  11. package/src/commands/did.js +376 -0
  12. package/src/commands/encrypt.js +233 -0
  13. package/src/commands/export.js +125 -0
  14. package/src/commands/git.js +215 -0
  15. package/src/commands/import.js +259 -0
  16. package/src/commands/instinct.js +202 -0
  17. package/src/commands/llm.js +288 -0
  18. package/src/commands/mcp.js +302 -0
  19. package/src/commands/memory.js +282 -0
  20. package/src/commands/note.js +489 -0
  21. package/src/commands/org.js +505 -0
  22. package/src/commands/p2p.js +274 -0
  23. package/src/commands/plugin.js +398 -0
  24. package/src/commands/search.js +237 -0
  25. package/src/commands/session.js +238 -0
  26. package/src/commands/skill.js +479 -0
  27. package/src/commands/sync.js +249 -0
  28. package/src/commands/tokens.js +214 -0
  29. package/src/commands/wallet.js +416 -0
  30. package/src/index.js +65 -0
  31. package/src/lib/audit-logger.js +364 -0
  32. package/src/lib/bm25-search.js +322 -0
  33. package/src/lib/browser-automation.js +216 -0
  34. package/src/lib/crypto-manager.js +246 -0
  35. package/src/lib/did-manager.js +270 -0
  36. package/src/lib/ensure-utf8.js +59 -0
  37. package/src/lib/git-integration.js +220 -0
  38. package/src/lib/instinct-manager.js +190 -0
  39. package/src/lib/knowledge-exporter.js +302 -0
  40. package/src/lib/knowledge-importer.js +293 -0
  41. package/src/lib/llm-providers.js +325 -0
  42. package/src/lib/mcp-client.js +413 -0
  43. package/src/lib/memory-manager.js +211 -0
  44. package/src/lib/note-versioning.js +244 -0
  45. package/src/lib/org-manager.js +424 -0
  46. package/src/lib/p2p-manager.js +317 -0
  47. package/src/lib/pdf-parser.js +96 -0
  48. package/src/lib/permission-engine.js +374 -0
  49. package/src/lib/plan-mode.js +333 -0
  50. package/src/lib/platform.js +15 -0
  51. package/src/lib/plugin-manager.js +312 -0
  52. package/src/lib/response-cache.js +156 -0
  53. package/src/lib/session-manager.js +189 -0
  54. package/src/lib/sync-manager.js +347 -0
  55. package/src/lib/token-tracker.js +200 -0
  56. package/src/lib/wallet-manager.js +348 -0
  57. package/src/repl/agent-repl.js +912 -0
  58. package/src/repl/chat-repl.js +262 -0
  59. package/src/runtime/bootstrap.js +159 -0
package/README.md CHANGED
@@ -102,6 +102,386 @@ chainlesschain doctor
102
102
 
103
103
  Checks: Node.js version, npm, Docker, Docker Compose, Git, config directory, binary installation, setup status, port availability, disk space.
104
104
 
105
+ ---
106
+
107
+ ## Headless Commands
108
+
109
+ These commands work without the desktop GUI, using core packages directly.
110
+
111
+ ### `chainlesschain db <action>`
112
+
113
+ Database management.
114
+
115
+ ```bash
116
+ chainlesschain db init # Initialize the database
117
+ chainlesschain db init --path ./my.db # Custom database path
118
+ chainlesschain db info # Show database info (driver, tables, size)
119
+ chainlesschain db info --json # JSON output
120
+ chainlesschain db backup [output] # Create backup
121
+ chainlesschain db restore <backup> # Restore from backup
122
+ ```
123
+
124
+ ### `chainlesschain note <action>`
125
+
126
+ Note and knowledge base management.
127
+
128
+ ```bash
129
+ chainlesschain note add "My Note" -c "Content here" -t "tag1,tag2"
130
+ chainlesschain note list # List recent notes
131
+ chainlesschain note list --category dev --tag important
132
+ chainlesschain note show <id> # Show note by ID prefix
133
+ chainlesschain note search "keyword" # Full-text search
134
+ chainlesschain note delete <id> # Soft delete
135
+ chainlesschain note history <id> # Version history
136
+ chainlesschain note diff <id> <v1> <v2> # Diff between versions
137
+ chainlesschain note revert <id> <ver> # Revert to a version
138
+ ```
139
+
140
+ ### `chainlesschain chat`
141
+
142
+ Start an interactive AI chat session with streaming output.
143
+
144
+ ```bash
145
+ chainlesschain chat # Default: Ollama qwen2:7b
146
+ chainlesschain chat --model llama3 # Use different model
147
+ chainlesschain chat --provider openai --api-key sk-...
148
+ chainlesschain chat --agent # Agentic mode (can read/write files)
149
+ ```
150
+
151
+ Slash commands in chat: `/exit`, `/model`, `/provider`, `/clear`, `/history`, `/help`
152
+
153
+ ### `chainlesschain ask <question>`
154
+
155
+ Single-shot AI question (non-interactive).
156
+
157
+ ```bash
158
+ chainlesschain ask "What is WebRTC?"
159
+ chainlesschain ask "Explain this code" --model gpt-4o --provider openai
160
+ chainlesschain ask "Hello" --json # JSON output with question/answer/model
161
+ ```
162
+
163
+ ### `chainlesschain llm <action>`
164
+
165
+ LLM provider management.
166
+
167
+ ```bash
168
+ chainlesschain llm models # List installed Ollama models
169
+ chainlesschain llm models --json # JSON output
170
+ chainlesschain llm test # Test Ollama connectivity
171
+ chainlesschain llm test --provider openai --api-key sk-...
172
+ chainlesschain llm providers # List 7 built-in LLM providers
173
+ chainlesschain llm add-provider <name> # Add custom provider
174
+ chainlesschain llm switch <name> # Switch active provider
175
+ ```
176
+
177
+ ### `chainlesschain agent` (alias: `a`)
178
+
179
+ Start an agentic AI session — the AI can read/write files, run shell commands, search the codebase, and invoke 138 built-in skills.
180
+
181
+ ```bash
182
+ chainlesschain agent # Default: Ollama qwen2:7b
183
+ chainlesschain a --model llama3 # Short alias
184
+ chainlesschain agent --provider openai --api-key sk-...
185
+ ```
186
+
187
+ Built-in tools: `read_file`, `write_file`, `edit_file`, `run_shell`, `search_files`, `list_dir`, `run_skill`, `list_skills`
188
+
189
+ ### `chainlesschain skill <action>`
190
+
191
+ Manage and run 138 built-in AI skills.
192
+
193
+ ```bash
194
+ chainlesschain skill list # List all skills grouped by category
195
+ chainlesschain skill list --category automation
196
+ chainlesschain skill list --tag code --runnable
197
+ chainlesschain skill list --json # JSON output
198
+ chainlesschain skill categories # Show category breakdown
199
+ chainlesschain skill info code-review # Detailed skill info + docs
200
+ chainlesschain skill info code-review --json
201
+ chainlesschain skill search "browser" # Search by keyword
202
+ chainlesschain skill run code-review "Review this function..."
203
+ ```
204
+
205
+ ---
206
+
207
+ ## Phase 1: AI Intelligence Layer
208
+
209
+ ### `chainlesschain search <query>`
210
+
211
+ BM25 hybrid keyword search across notes.
212
+
213
+ ```bash
214
+ chainlesschain search "machine learning"
215
+ chainlesschain search "API design" --mode bm25 --top-k 10
216
+ chainlesschain search "security" --json
217
+ ```
218
+
219
+ ### `chainlesschain tokens <action>`
220
+
221
+ Token usage tracking and cost analysis.
222
+
223
+ ```bash
224
+ chainlesschain tokens show # Current usage summary
225
+ chainlesschain tokens breakdown # Per-model breakdown
226
+ chainlesschain tokens recent # Recent usage entries
227
+ chainlesschain tokens cache # Cache hit/miss stats
228
+ ```
229
+
230
+ ### `chainlesschain memory <action>`
231
+
232
+ Persistent memory management.
233
+
234
+ ```bash
235
+ chainlesschain memory show # Show all memories
236
+ chainlesschain memory add "Always use TypeScript"
237
+ chainlesschain memory search "coding" # Search memories
238
+ chainlesschain memory delete <id> # Delete by ID prefix
239
+ chainlesschain memory daily # Today's daily note
240
+ chainlesschain memory file # Show memory file path
241
+ ```
242
+
243
+ ### `chainlesschain session <action>`
244
+
245
+ Session persistence and management.
246
+
247
+ ```bash
248
+ chainlesschain session list # List saved sessions
249
+ chainlesschain session show <id> # Show session details
250
+ chainlesschain session resume <id> # Resume a session
251
+ chainlesschain session export <id> # Export as Markdown
252
+ chainlesschain session delete <id> # Delete a session
253
+ ```
254
+
255
+ ---
256
+
257
+ ## Phase 2: Knowledge & Content Management
258
+
259
+ ### `chainlesschain import <format>`
260
+
261
+ Import knowledge from external sources.
262
+
263
+ ```bash
264
+ chainlesschain import markdown ./docs # Import markdown directory
265
+ chainlesschain import evernote backup.enex # Import Evernote ENEX
266
+ chainlesschain import notion ./export # Import Notion export
267
+ chainlesschain import pdf document.pdf # Import PDF text
268
+ ```
269
+
270
+ ### `chainlesschain export <format>`
271
+
272
+ Export knowledge base.
273
+
274
+ ```bash
275
+ chainlesschain export markdown -o ./output # Export as Markdown files
276
+ chainlesschain export site -o ./site # Export as static HTML site
277
+ ```
278
+
279
+ ### `chainlesschain git <action>`
280
+
281
+ Git integration for knowledge versioning.
282
+
283
+ ```bash
284
+ chainlesschain git status # Show git status
285
+ chainlesschain git init # Initialize git repo
286
+ chainlesschain git auto-commit # Auto-commit all changes
287
+ chainlesschain git hooks # Install pre-commit hooks
288
+ chainlesschain git history-analyze # Analyze repo history
289
+ ```
290
+
291
+ ### Note Versioning
292
+
293
+ ```bash
294
+ chainlesschain note history <id> # Show version history
295
+ chainlesschain note diff <id> <v1> <v2> # Diff between versions
296
+ chainlesschain note revert <id> <ver> # Revert to version
297
+ ```
298
+
299
+ ---
300
+
301
+ ## Phase 3: MCP & External Integration
302
+
303
+ ### `chainlesschain mcp <action>`
304
+
305
+ MCP (Model Context Protocol) server management.
306
+
307
+ ```bash
308
+ chainlesschain mcp servers # List configured servers
309
+ chainlesschain mcp add <name> -c <cmd> # Add a server
310
+ chainlesschain mcp remove <name> # Remove a server
311
+ chainlesschain mcp connect <name> # Connect to server
312
+ chainlesschain mcp disconnect <name> # Disconnect
313
+ chainlesschain mcp tools # List available tools
314
+ chainlesschain mcp call <server> <tool> # Call a tool
315
+ ```
316
+
317
+ ### `chainlesschain browse <action>`
318
+
319
+ Browser automation (headless fetch-based).
320
+
321
+ ```bash
322
+ chainlesschain browse fetch <url> # Fetch page content
323
+ chainlesschain browse scrape <url> -s "h2" # Scrape CSS selector
324
+ chainlesschain browse screenshot <url> # Take screenshot (requires playwright)
325
+ ```
326
+
327
+ ### `chainlesschain instinct <action>`
328
+
329
+ Instinct learning — tracks user preferences over time.
330
+
331
+ ```bash
332
+ chainlesschain instinct show # Show learned instincts
333
+ chainlesschain instinct categories # List 6 instinct categories
334
+ chainlesschain instinct prompt # Generate system prompt from instincts
335
+ chainlesschain instinct delete <id> # Delete an instinct
336
+ chainlesschain instinct reset # Clear all instincts
337
+ chainlesschain instinct decay # Decay old instincts
338
+ ```
339
+
340
+ ---
341
+
342
+ ## Phase 4: Security & Identity
343
+
344
+ ### `chainlesschain did <action>`
345
+
346
+ DID identity management (Ed25519).
347
+
348
+ ```bash
349
+ chainlesschain did create --label "My Identity"
350
+ chainlesschain did list
351
+ chainlesschain did show <did>
352
+ chainlesschain did sign <did> "message"
353
+ chainlesschain did verify <did> "message" <signature>
354
+ chainlesschain did export <did>
355
+ chainlesschain did set-default <did>
356
+ chainlesschain did delete <did>
357
+ ```
358
+
359
+ ### `chainlesschain encrypt / decrypt`
360
+
361
+ AES-256-GCM file encryption.
362
+
363
+ ```bash
364
+ chainlesschain encrypt file <input> -o <output>
365
+ chainlesschain encrypt db
366
+ chainlesschain encrypt info <file>
367
+ chainlesschain encrypt status
368
+ chainlesschain decrypt file <input> -o <output>
369
+ chainlesschain decrypt db
370
+ ```
371
+
372
+ ### `chainlesschain auth <action>`
373
+
374
+ RBAC permission engine.
375
+
376
+ ```bash
377
+ chainlesschain auth roles # List roles
378
+ chainlesschain auth create-role <name> # Create custom role
379
+ chainlesschain auth grant <user> <role> # Assign role
380
+ chainlesschain auth check <user> <scope> # Check permission
381
+ chainlesschain auth permissions <user> # List user permissions
382
+ chainlesschain auth scopes # List all 26 scopes
383
+ ```
384
+
385
+ ### `chainlesschain audit <action>`
386
+
387
+ Audit logging and compliance.
388
+
389
+ ```bash
390
+ chainlesschain audit log # Recent events
391
+ chainlesschain audit search --type security # Search by type
392
+ chainlesschain audit stats # Statistics
393
+ chainlesschain audit export --format json # Export logs
394
+ chainlesschain audit purge --before 90 # Purge old logs
395
+ chainlesschain audit types # List event types
396
+ ```
397
+
398
+ ---
399
+
400
+ ## Phase 5: P2P, Blockchain & Enterprise
401
+
402
+ ### `chainlesschain p2p <action>`
403
+
404
+ Peer-to-peer messaging and device pairing.
405
+
406
+ ```bash
407
+ chainlesschain p2p status # P2P network status
408
+ chainlesschain p2p peers # List known peers
409
+ chainlesschain p2p send <peer-id> "message" # Send message
410
+ chainlesschain p2p inbox # View inbox
411
+ chainlesschain p2p pair <device-name> # Pair a device
412
+ chainlesschain p2p devices # List paired devices
413
+ chainlesschain p2p unpair <device-id> # Unpair a device
414
+ ```
415
+
416
+ ### `chainlesschain sync <action>`
417
+
418
+ File and knowledge synchronization.
419
+
420
+ ```bash
421
+ chainlesschain sync status # Sync status
422
+ chainlesschain sync push # Push local changes
423
+ chainlesschain sync pull # Pull remote changes
424
+ chainlesschain sync conflicts # List conflicts
425
+ chainlesschain sync resolve <id> --strategy local # Resolve conflict
426
+ chainlesschain sync log # Sync history
427
+ chainlesschain sync clear # Clear sync state
428
+ ```
429
+
430
+ ### `chainlesschain wallet <action>`
431
+
432
+ Digital wallet and asset management.
433
+
434
+ ```bash
435
+ chainlesschain wallet create --name "My Wallet" # Create wallet
436
+ chainlesschain wallet list # List wallets
437
+ chainlesschain wallet balance <address> # Check balance
438
+ chainlesschain wallet set-default <address> # Set default wallet
439
+ chainlesschain wallet delete <address> # Delete wallet
440
+ chainlesschain wallet asset <address> <type> <name> # Create asset
441
+ chainlesschain wallet assets [address] # List assets
442
+ chainlesschain wallet transfer <asset-id> <to> # Transfer asset
443
+ chainlesschain wallet history [address] # Transaction history
444
+ chainlesschain wallet summary # Overall summary
445
+ ```
446
+
447
+ ### `chainlesschain org <action>`
448
+
449
+ Organization management and workflows.
450
+
451
+ ```bash
452
+ chainlesschain org create <name> # Create organization
453
+ chainlesschain org list # List organizations
454
+ chainlesschain org show <id> # Organization details
455
+ chainlesschain org delete <id> # Delete organization
456
+ chainlesschain org invite <org-id> <user-id> # Invite member
457
+ chainlesschain org members <org-id> # List members
458
+ chainlesschain org team-create <org-id> <name> # Create team
459
+ chainlesschain org teams <org-id> # List teams
460
+ chainlesschain org approval-submit <org-id> <title> # Submit approval
461
+ chainlesschain org approvals <org-id> # List approvals
462
+ chainlesschain org approve <request-id> # Approve request
463
+ chainlesschain org reject <request-id> # Reject request
464
+ ```
465
+
466
+ ### `chainlesschain plugin <action>`
467
+
468
+ Plugin marketplace management.
469
+
470
+ ```bash
471
+ chainlesschain plugin list # List installed plugins
472
+ chainlesschain plugin install <name> --version <v> # Install plugin
473
+ chainlesschain plugin remove <name> # Remove plugin
474
+ chainlesschain plugin enable <name> # Enable plugin
475
+ chainlesschain plugin disable <name> # Disable plugin
476
+ chainlesschain plugin update <name> --version <v> # Update plugin
477
+ chainlesschain plugin info <name> # Plugin details
478
+ chainlesschain plugin search <query> # Search registry
479
+ chainlesschain plugin registry # List all registry plugins
480
+ chainlesschain plugin summary # Installation summary
481
+ ```
482
+
483
+ ---
484
+
105
485
  ## Global Options
106
486
 
107
487
  ```bash
@@ -146,13 +526,16 @@ Configuration is stored at `~/.chainlesschain/config.json`. The CLI creates and
146
526
 
147
527
  ### Supported LLM Providers
148
528
 
149
- | Provider | Default Model | API Key Required |
150
- | ------------------- | ------------- | ---------------- |
151
- | Ollama (Local) | qwen2:7b | No |
152
- | OpenAI | gpt-4o | Yes |
153
- | DashScope (Alibaba) | qwen-max | Yes |
154
- | DeepSeek | deepseek-chat | Yes |
155
- | Custom | | Yes |
529
+ | Provider | Default Model | API Key Required |
530
+ | ------------------- | ----------------- | ---------------- |
531
+ | Ollama (Local) | qwen2:7b | No |
532
+ | OpenAI | gpt-4o | Yes |
533
+ | Anthropic | claude-sonnet-4-6 | Yes |
534
+ | DashScope (Alibaba) | qwen-max | Yes |
535
+ | DeepSeek | deepseek-chat | Yes |
536
+ | Gemini (Google) | gemini-pro | Yes |
537
+ | Mistral | mistral-large | Yes |
538
+ | Custom | — | Yes |
156
539
 
157
540
  ## File Structure
158
541
 
@@ -171,12 +554,24 @@ Configuration is stored at `~/.chainlesschain/config.json`. The CLI creates and
171
554
  ```bash
172
555
  cd packages/cli
173
556
  npm install
174
- npm test # Run all tests
557
+ npm test # Run all tests (903 tests across 47 files)
175
558
  npm run test:unit # Unit tests only
176
559
  npm run test:integration # Integration tests
177
560
  npm run test:e2e # End-to-end tests
178
561
  ```
179
562
 
563
+ ### Test Coverage
564
+
565
+ | Category | Files | Tests | Status |
566
+ | ------------------------ | ------ | ------- | --------------- |
567
+ | Unit — lib modules | 25 | 578 | All passing |
568
+ | Unit — commands | 2 | 43 | All passing |
569
+ | Unit — runtime | 1 | 6 | All passing |
570
+ | Integration | 3 | 7 | All passing |
571
+ | E2E | 9 | 88 | All passing |
572
+ | Core packages (external) | — | 118 | All passing |
573
+ | **CLI Total** | **47** | **903** | **All passing** |
574
+
180
575
  ## License
181
576
 
182
577
  MIT
@@ -1,5 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // Ensure UTF-8 encoding on Windows to prevent Chinese character garbling (乱码)
4
+ import { ensureUtf8 } from "../src/lib/ensure-utf8.js";
5
+ ensureUtf8();
6
+
3
7
  import { createProgram } from "../src/index.js";
4
8
 
5
9
  const program = createProgram();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chainlesschain",
3
- "version": "0.37.8",
3
+ "version": "0.37.10",
4
4
  "description": "CLI for ChainlessChain - install, configure, and manage your personal AI management system",
5
5
  "type": "module",
6
6
  "bin": {
@@ -45,7 +45,12 @@
45
45
  "@inquirer/prompts": "^7.2.0",
46
46
  "chalk": "^5.4.1",
47
47
  "ora": "^8.1.1",
48
- "semver": "^7.6.3"
48
+ "semver": "^7.6.3",
49
+ "@chainlesschain/core-env": "0.1.0",
50
+ "@chainlesschain/shared-logger": "0.1.0",
51
+ "@chainlesschain/core-db": "0.1.0",
52
+ "@chainlesschain/core-config": "0.1.0",
53
+ "@chainlesschain/core-infra": "0.1.0"
49
54
  },
50
55
  "devDependencies": {
51
56
  "vitest": "^3.1.1"
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Agentic AI assistant - Claude Code style
3
+ * chainlesschain agent [--model] [--provider]
4
+ *
5
+ * User describes what they want in natural language.
6
+ * AI reads files, writes code, runs commands, and explains what it's doing.
7
+ */
8
+
9
+ import { startAgentRepl } from "../repl/agent-repl.js";
10
+
11
+ export function registerAgentCommand(program) {
12
+ program
13
+ .command("agent")
14
+ .alias("a")
15
+ .description(
16
+ "Start an agentic AI session (reads/writes files, runs commands)",
17
+ )
18
+ .option("--model <model>", "Model name", "qwen2:7b")
19
+ .option("--provider <provider>", "LLM provider (ollama, openai)", "ollama")
20
+ .option("--base-url <url>", "API base URL")
21
+ .option("--api-key <key>", "API key")
22
+ .action(async (options) => {
23
+ await startAgentRepl({
24
+ model: options.model,
25
+ provider: options.provider,
26
+ baseUrl: options.baseUrl,
27
+ apiKey: options.apiKey,
28
+ });
29
+ });
30
+ }
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Single-shot AI question command
3
+ * chainlesschain ask "What is..." [--model qwen2:7b] [--provider ollama] [--json]
4
+ */
5
+
6
+ import ora from "ora";
7
+ import chalk from "chalk";
8
+ import { logger } from "../lib/logger.js";
9
+
10
+ /**
11
+ * Send a single question to an LLM provider
12
+ * @param {string} question
13
+ * @param {object} options
14
+ * @returns {Promise<string>}
15
+ */
16
+ async function queryLLM(question, options = {}) {
17
+ const provider = options.provider || "ollama";
18
+ const model = options.model || "qwen2:7b";
19
+ const baseUrl = options.baseUrl || "http://localhost:11434";
20
+
21
+ if (provider === "ollama") {
22
+ const response = await fetch(`${baseUrl}/api/generate`, {
23
+ method: "POST",
24
+ headers: { "Content-Type": "application/json" },
25
+ body: JSON.stringify({
26
+ model,
27
+ prompt: question,
28
+ stream: false,
29
+ }),
30
+ });
31
+
32
+ if (!response.ok) {
33
+ throw new Error(
34
+ `Ollama error: ${response.status} ${response.statusText}`,
35
+ );
36
+ }
37
+
38
+ const data = await response.json();
39
+ return data.response;
40
+ } else if (provider === "openai") {
41
+ const apiKey = options.apiKey || process.env.OPENAI_API_KEY;
42
+ if (!apiKey)
43
+ throw new Error("OpenAI API key required (--api-key or OPENAI_API_KEY)");
44
+
45
+ const apiBase = options.baseUrl || "https://api.openai.com/v1";
46
+ const response = await fetch(`${apiBase}/chat/completions`, {
47
+ method: "POST",
48
+ headers: {
49
+ "Content-Type": "application/json",
50
+ Authorization: `Bearer ${apiKey}`,
51
+ },
52
+ body: JSON.stringify({
53
+ model: model || "gpt-4o-mini",
54
+ messages: [{ role: "user", content: question }],
55
+ }),
56
+ });
57
+
58
+ if (!response.ok) {
59
+ throw new Error(
60
+ `OpenAI error: ${response.status} ${response.statusText}`,
61
+ );
62
+ }
63
+
64
+ const data = await response.json();
65
+ return data.choices[0].message.content;
66
+ }
67
+
68
+ throw new Error(`Unsupported provider: ${provider}`);
69
+ }
70
+
71
+ export function registerAskCommand(program) {
72
+ program
73
+ .command("ask")
74
+ .description("Ask a question to the AI (single-shot)")
75
+ .argument("<question>", "The question to ask")
76
+ .option("--model <model>", "Model name", "qwen2:7b")
77
+ .option("--provider <provider>", "LLM provider (ollama, openai)", "ollama")
78
+ .option("--base-url <url>", "API base URL")
79
+ .option("--api-key <key>", "API key")
80
+ .option("--json", "Output as JSON")
81
+ .action(async (question, options) => {
82
+ const spinner = ora("Thinking...").start();
83
+ try {
84
+ const answer = await queryLLM(question, {
85
+ model: options.model,
86
+ provider: options.provider,
87
+ baseUrl: options.baseUrl,
88
+ apiKey: options.apiKey,
89
+ });
90
+
91
+ spinner.stop();
92
+
93
+ if (options.json) {
94
+ console.log(
95
+ JSON.stringify(
96
+ {
97
+ question,
98
+ answer,
99
+ model: options.model,
100
+ provider: options.provider,
101
+ },
102
+ null,
103
+ 2,
104
+ ),
105
+ );
106
+ } else {
107
+ logger.log(answer);
108
+ }
109
+ } catch (err) {
110
+ spinner.fail(`Failed: ${err.message}`);
111
+ process.exit(1);
112
+ }
113
+ });
114
+ }