@raolin2025/claude-code-node 2.2.4 → 2.2.6

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/core/cli.js +52 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raolin2025/claude-code-node",
3
- "version": "2.2.4",
3
+ "version": "2.2.6",
4
4
  "description": "Node.js AI Code Agent CLI - Zero dependencies, pure JavaScript, security hardened, multi-channel notifications",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/core/cli.js CHANGED
@@ -129,6 +129,7 @@ const HELP_TEXT = `
129
129
  Commands:
130
130
  /help — Show this help
131
131
  /model NAME — Switch model
132
+ /models — List available models from current API
132
133
  /tools — List available tools
133
134
  /session — Show session info
134
135
  /sessions — List all sessions
@@ -138,6 +139,7 @@ Commands:
138
139
  /channel CMD — Manage notification channels (list|send|test)
139
140
  /cost — Show API cost report
140
141
  /compact — Manually compact conversation context
142
+ /cd PATH — Change working directory
141
143
  /allow [tool] — Allow a tool for the current session (default: all)
142
144
  /exit — Exit (also Ctrl+C)
143
145
  /quit — Same as /exit
@@ -355,6 +357,41 @@ export async function main() {
355
357
  if (rest[0]) { engine.config.model = rest.join(' '); console.log(`Model → ${engine.config.model}`) }
356
358
  else console.log(`Model: ${engine.config.model}`)
357
359
  break
360
+ case 'models': {
361
+ const apiBase = engine.config.apiBase
362
+ const apiKey = engine.config.apiKey
363
+ if (!apiKey) { console.log('❌ API key not configured'); break }
364
+ const modelsUrl = apiBase.replace(/\/+$/, '') + '/models'
365
+ console.log(`📡 Fetching models from ${modelsUrl}...`)
366
+ try {
367
+ const res = await fetch(modelsUrl, { headers: { 'Authorization': `Bearer ${apiKey}` } })
368
+ if (!res.ok) { console.log(`❌ API error: ${res.status}`); break }
369
+ const data = await res.json()
370
+ const models = data.data || []
371
+ if (models.length === 0) { console.log('No models returned'); break }
372
+ console.log(`\nAvailable models (${models.length}):`)
373
+ models.forEach((m, i) => {
374
+ const id = m.id || m
375
+ console.log(` ${(i + 1).toString().padStart(2)}. ${id}`)
376
+ })
377
+ console.log('\nType a number to select, or model name directly:')
378
+ const answer = await new Promise(resolve => rl.question('> ', resolve))
379
+ const num = parseInt(answer, 10)
380
+ let selected
381
+ if (!isNaN(num) && num >= 1 && num <= models.length) {
382
+ selected = models[num - 1].id || models[num - 1]
383
+ } else if (answer.trim()) {
384
+ selected = answer.trim()
385
+ }
386
+ if (selected) {
387
+ engine.config.model = selected
388
+ console.log(`Model → ${selected}`)
389
+ }
390
+ } catch (err) {
391
+ console.log(`❌ ${err.message}`)
392
+ }
393
+ break
394
+ }
358
395
  case 'tools':
359
396
  console.log('Available tools:')
360
397
  for (const name of registry.getNames()) {
@@ -423,6 +460,21 @@ export async function main() {
423
460
  case 'cost':
424
461
  console.log(engine.costTracker.formatReport())
425
462
  break
463
+ case 'cd':
464
+ if (rest.length === 0) {
465
+ console.log(`Current directory: ${process.cwd()}`)
466
+ } else {
467
+ const target = rest.join(' ')
468
+ try {
469
+ process.chdir(target)
470
+ const newCwd = process.cwd()
471
+ engine.config.cwd = newCwd
472
+ console.log(`📂 ${newCwd}`)
473
+ } catch (err) {
474
+ console.log(`❌ ${err.message}`)
475
+ }
476
+ }
477
+ break
426
478
  case 'compact': {
427
479
  if (engine.tokenBudget) {
428
480
  const { compacted, messages } = autoCompact(engine.state.messages, engine.tokenBudget, { keepRecentTurns: 4 })