@raolin2025/claude-code-node 2.2.7 → 2.2.8
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 +1 -1
- package/src/core/cli.js +97 -9
package/package.json
CHANGED
package/src/core/cli.js
CHANGED
|
@@ -116,14 +116,102 @@ function startSocketServer(engine, session, sessionManager, channelManager, verb
|
|
|
116
116
|
// Banner & Help
|
|
117
117
|
// ============================================================
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
119
|
+
// ============================================================
|
|
120
|
+
// Banner & Help
|
|
121
|
+
// ============================================================
|
|
122
|
+
|
|
123
|
+
// 版本号(从 package.json 读取或手动更新)
|
|
124
|
+
let CC_NODE_VERSION = '2.2.7'
|
|
125
|
+
try {
|
|
126
|
+
const pkgPath = new URL('../../package.json', import.meta.url)
|
|
127
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'))
|
|
128
|
+
CC_NODE_VERSION = pkg.version || CC_NODE_VERSION
|
|
129
|
+
} catch {}
|
|
130
|
+
|
|
131
|
+
// 生成 Claude Code 风格的三栏 Banner
|
|
132
|
+
function buildBanner({ model, permissionMode, session, maxTokens }) {
|
|
133
|
+
const width = 112
|
|
134
|
+
const inner = width - 2
|
|
135
|
+
const leftLabel = ` CC-Node v${CC_NODE_VERSION} `
|
|
136
|
+
const top = `╭${leftLabel}${'─'.repeat(inner - leftLabel.length)}╮`
|
|
137
|
+
const bottom = `╰${'─'.repeat(inner)}╯`
|
|
138
|
+
|
|
139
|
+
const col1 = 30 // 机器人列
|
|
140
|
+
const col2 = 42 // 标题列
|
|
141
|
+
const col3 = inner - col1 - col2 - 2 // 信息列
|
|
142
|
+
|
|
143
|
+
// ANSI 颜色
|
|
144
|
+
const BLUE = '\x1b[34m'
|
|
145
|
+
const CYAN = '\x1b[36m'
|
|
146
|
+
const RESET = '\x1b[0m'
|
|
147
|
+
|
|
148
|
+
// 原始机器人(宽21)
|
|
149
|
+
const robotRaw = [
|
|
150
|
+
' ╭───────╮ ',
|
|
151
|
+
'┌───────────────────┐',
|
|
152
|
+
'│ ██ ██ │',
|
|
153
|
+
'│ │',
|
|
154
|
+
'│ ██████ │',
|
|
155
|
+
'└───────────────────┘'
|
|
156
|
+
]
|
|
157
|
+
|
|
158
|
+
// 颜色化:边框蓝,眼睛/嘴巴青
|
|
159
|
+
const colorize = (line) =>
|
|
160
|
+
line
|
|
161
|
+
.replace(/[┌└─╭╮]/g, BLUE + '$&' + RESET)
|
|
162
|
+
.replace(/[█]/g, CYAN + '$&' + RESET)
|
|
163
|
+
|
|
164
|
+
const robotColored = robotRaw.map(colorize)
|
|
165
|
+
|
|
166
|
+
// 在 col1 内居中(考虑 ESC 序列不看长度,按可见长度21 计算)
|
|
167
|
+
const leftPad = 4 // (30 - 21) / 2 = 4.5 => 4 left, 5 right
|
|
168
|
+
const rightPad = 5
|
|
169
|
+
const robotLines = robotColored.map(line => ' '.repeat(leftPad) + line + ' '.repeat(rightPad))
|
|
170
|
+
|
|
171
|
+
// 标题列(居中)
|
|
172
|
+
const pad = (s, w, align = 'center') => {
|
|
173
|
+
if (s.length >= w) return s
|
|
174
|
+
const sp = w - s.length
|
|
175
|
+
if (align === 'center') {
|
|
176
|
+
const l = Math.floor(sp / 2)
|
|
177
|
+
return ' '.repeat(l) + s + ' '.repeat(sp - l)
|
|
178
|
+
}
|
|
179
|
+
return s + ' '.repeat(sp)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const titleLines = [
|
|
183
|
+
pad('AI Code Agent', col2, 'center'),
|
|
184
|
+
pad('Node.js Edition', col2, 'center'),
|
|
185
|
+
pad('', col2, 'center'),
|
|
186
|
+
pad('─'.repeat(col2 - 2), col2, 'center'),
|
|
187
|
+
pad('/help — commands · /exit — quit', col2, 'center'),
|
|
188
|
+
pad('', col2, 'center')
|
|
189
|
+
]
|
|
190
|
+
|
|
191
|
+
// 信息列(右对齐)
|
|
192
|
+
const sessionId = session?.id || '??????'
|
|
193
|
+
const infoLines = [
|
|
194
|
+
pad(`Turns: ${session?.state?.turnCount ?? 0} • Tools: 0`, col3, 'right'),
|
|
195
|
+
pad(`Model: ${model}`, col3, 'right'),
|
|
196
|
+
pad(`Permission: ${permissionMode}`, col3, 'right'),
|
|
197
|
+
pad(`Budget: 0 / ${maxTokens ?? 200000}`, col3, 'right'),
|
|
198
|
+
pad(`Session: ${sessionId?.toString().slice(-6)}`, col3, 'right'),
|
|
199
|
+
pad('', col3, 'right')
|
|
200
|
+
]
|
|
201
|
+
|
|
202
|
+
// 构建每行:│ col1 │ col2 │ col3 │
|
|
203
|
+
const lines = [top]
|
|
204
|
+
const empty = `│${' '.repeat(inner)}│`
|
|
205
|
+
lines.push(empty)
|
|
206
|
+
|
|
207
|
+
for (let i = 0; i < robotLines.length; i++) {
|
|
208
|
+
lines.push(`│${robotLines[i]}│${titleLines[i]}│${infoLines[i]}│`)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
lines.push(empty)
|
|
212
|
+
lines.push(bottom)
|
|
213
|
+
return lines.join('\n')
|
|
214
|
+
}
|
|
127
215
|
|
|
128
216
|
const HELP_TEXT = `
|
|
129
217
|
Commands:
|
|
@@ -364,7 +452,7 @@ export async function main() {
|
|
|
364
452
|
}
|
|
365
453
|
engine.config.readline = rl
|
|
366
454
|
|
|
367
|
-
console.log(
|
|
455
|
+
console.log(buildBanner({ model, permissionMode, session, maxTokens: tokenBudget.maxTokens }))
|
|
368
456
|
console.log(`Model: ${model} | Permission: ${permissionMode} | Tools: ${registry.getNames().join(', ')}`)
|
|
369
457
|
console.log(`Socket: ${SOCK_PATH} (cc-notify can connect)`)
|
|
370
458
|
if (channelManager.list().length > 0) {
|