@raolin2025/claude-code-node 2.2.8 → 2.2.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raolin2025/claude-code-node",
3
- "version": "2.2.8",
3
+ "version": "2.2.9",
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
@@ -228,7 +228,10 @@ Commands:
228
228
  /cost — Show API cost report
229
229
  /compact — Manually compact conversation context
230
230
  /cd PATH — Change working directory
231
- /allow [tool] — Allow a tool for the current session (default: all)
231
+ /allow [tool|all|reset] — Allow tools for this session (default: all)
232
+ /allow all — automatically allow all subsequent tools
233
+ /allow reset — reset to ask mode
234
+ /allow <tool> — allow specific tool (e.g. Bash)
232
235
  /exit — Exit (also Ctrl+C)
233
236
  /quit — Same as /exit
234
237
 
@@ -262,7 +265,7 @@ const DETAILED_HELP = {
262
265
 
263
266
  cd: "/cd <path>\n Change the working directory of cc-node.\n Affects all subsequent tool executions (Bash, Read, Write, etc.).\n\n Without path: show the current working directory.\n\n Example: /cd /home/raolin/projects\n Example: /cd ..",
264
267
 
265
- allow: "/allow [tool_name]\n Allow a tool to execute without confirmation for this session.\n Without tool name: allows ALL tools.\n\n Example: /allow\n Example: /allow Bash",
268
+ allow: "/allow [tool|all|reset]\n Manage tool permissions for this session.\n\n Options:\n <tool> — allow a specific tool (e.g. Bash, Write, Read)\n all — automatically allow ALL remaining tools for this session\n reset — reset to ask mode (ask for each tool)\n (no arg) — same as /allow all\n\n When asked to confirm a tool, you can also type:\n y — allow this once\n a — allow all for the rest of the session\n\n Example: /allow Bash\n Example: /allow all\n Example: /allow reset",
266
269
 
267
270
  exit: "/exit\n Exit cc-node. Same as Ctrl+C or /quit.",
268
271
  quit: "/quit\n Exit cc-node. Same as Ctrl+C or /exit.",
@@ -442,10 +445,19 @@ export async function main() {
442
445
  // 将 readline 注入引擎配置,用于 ask 模式确认和 AskUserQuestion 工具
443
446
  if (permissionMode === 'ask') {
444
447
  engine.config.onConfirmTool = async (toolName, input) => {
448
+ // 如果已经启用会话全局自动允许,直接通过
449
+ if (engine.permissionChecker.sessionAllowAll) return true
450
+
451
+ const snippet = JSON.stringify(input).slice(0, 120) || '(no params)'
445
452
  return new Promise((resolve) => {
446
- const snippet = JSON.stringify(input).slice(0, 120) || '(no params)'
447
- rl.question(`\n⚠️ Allow tool "${toolName}"?\n Input: ${snippet}\n (y/N) `, (answer) => {
448
- resolve(answer.toLowerCase().startsWith('y'))
453
+ rl.question(`\n⚠️ Allow tool "${toolName}"?\n Input: ${snippet}\n (y/N/a) a=all session `, (answer) => {
454
+ const a = answer.toLowerCase()
455
+ if (a === 'a') {
456
+ engine.permissionChecker.allowAllForSession()
457
+ resolve(true)
458
+ } else {
459
+ resolve(a === 'y')
460
+ }
449
461
  })
450
462
  })
451
463
  }
@@ -583,9 +595,18 @@ export async function main() {
583
595
  break
584
596
  }
585
597
  case 'allow': {
586
- const allowTool = rest.join(' ') || '*'
587
- engine.permissionChecker.allowForSession(allowTool, '*')
588
- console.log(`✅ Tool "${allowTool}" allowed for this session`)
598
+ const arg = rest.join(' ').toLowerCase()
599
+ if (arg === 'all') {
600
+ engine.permissionChecker.allowAllForSession()
601
+ console.log('✅ All tools allowed for the rest of this session')
602
+ } else if (arg === 'reset') {
603
+ engine.permissionChecker.resetSessionAllow()
604
+ console.log('✅ Session permission reset to normal (ask mode)')
605
+ } else {
606
+ const tool = arg || '*'
607
+ engine.permissionChecker.allow(tool)
608
+ console.log(`✅ Tool "${tool}" allowed for this session`)
609
+ }
589
610
  break
590
611
  }
591
612
  case 'cost':
@@ -9,21 +9,20 @@ export class PermissionChecker {
9
9
  this.alwaysAllow = new Set()
10
10
  this.alwaysDeny = new Set()
11
11
  this.askRules = new Set()
12
+ this.sessionAllowAll = false // 整个会话自动允许
12
13
  }
13
14
 
14
15
  /**
15
16
  * 检查工具调用是否被允许
16
17
  */
17
18
  async check(toolName, input = {}) {
18
- if (this.mode === 'always-allow') return true
19
+ if (this.mode === 'always-allow' || this.sessionAllowAll) return true
19
20
  if (this.mode === 'deny') return false
20
21
 
21
22
  if (this.alwaysAllow.has(toolName)) return true
22
23
  if (this.alwaysDeny.has(toolName)) return false
23
24
 
24
- // 'ask' 模式 需要用户确认(简化版直接允许)
25
- // 完整版应该在终端显示确认对话框
26
- return true
25
+ return true // 'ask' 模式下由 onConfirmTool 决定
27
26
  }
28
27
 
29
28
  allow(toolName) {
@@ -33,5 +32,15 @@ export class PermissionChecker {
33
32
  deny(toolName) {
34
33
  this.alwaysDeny.add(toolName)
35
34
  }
35
+
36
+ // 会话剩余时间全部工具自动允许
37
+ allowAllForSession() {
38
+ this.sessionAllowAll = true
39
+ }
40
+
41
+ // 重置会话允许状态
42
+ resetSessionAllow() {
43
+ this.sessionAllowAll = false
44
+ }
36
45
  }
37
46