blun-king-cli 7.0.0 → 7.0.2
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/lib/chat.js +29 -78
- package/lib/ui.js +17 -39
- package/package.json +1 -1
package/lib/chat.js
CHANGED
|
@@ -14,7 +14,7 @@ var localMode = false;
|
|
|
14
14
|
var permissionMode = "normal"; // safe, normal, god
|
|
15
15
|
|
|
16
16
|
function showPrompt(rl, username, model) {
|
|
17
|
-
ui.
|
|
17
|
+
ui.setCurrentPerm(permissionMode);
|
|
18
18
|
rl.prompt();
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -22,6 +22,7 @@ function cyclePermission() {
|
|
|
22
22
|
var modes = ui.PERMISSION_MODES;
|
|
23
23
|
var idx = modes.indexOf(permissionMode);
|
|
24
24
|
permissionMode = modes[(idx + 1) % modes.length];
|
|
25
|
+
ui.setCurrentPerm(permissionMode);
|
|
25
26
|
return permissionMode;
|
|
26
27
|
}
|
|
27
28
|
|
|
@@ -271,91 +272,41 @@ function startChat() {
|
|
|
271
272
|
return;
|
|
272
273
|
}
|
|
273
274
|
|
|
274
|
-
//
|
|
275
|
+
// Send message
|
|
275
276
|
var spinner = ui.renderSpinner("Thinking...");
|
|
276
277
|
client
|
|
277
|
-
.
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
278
|
+
.sendMessage(input, { model: settings.model || "auto" })
|
|
279
|
+
.then(function (res) {
|
|
280
|
+
ui.stopSpinner(true, "Response received");
|
|
281
|
+
if (res.status === 200 && res.data) {
|
|
282
|
+
var text =
|
|
283
|
+
res.data.answer ||
|
|
284
|
+
res.data.response ||
|
|
285
|
+
res.data.text ||
|
|
286
|
+
res.data.message ||
|
|
287
|
+
JSON.stringify(res.data);
|
|
288
|
+
ui.renderResponse(text, "agent");
|
|
289
|
+
var tok = res.data.tokens || res.data.usage || {};
|
|
290
|
+
var tokTotal = tok.total || tok.total_tokens || 0;
|
|
291
|
+
if (!tokTotal && text) {
|
|
292
|
+
tokTotal = Math.ceil(text.length / 4) + Math.ceil(input.length / 4);
|
|
284
293
|
}
|
|
285
|
-
ui.
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
if (spinner) {
|
|
290
|
-
// No streaming happened, fallback to non-stream
|
|
291
|
-
ui.stopSpinner(true, "Response received");
|
|
292
|
-
ui.renderResponse(result.text || "(empty response)", "agent");
|
|
294
|
+
if (tokTotal) ui.addTokens(tokTotal);
|
|
295
|
+
ui.renderMiniStatus(settings.model || "chat", tokTotal);
|
|
296
|
+
} else if (res.status === 401 || res.status === 403) {
|
|
297
|
+
ui.renderResponse("Auth error. Use /login to re-authenticate.", "error");
|
|
293
298
|
} else {
|
|
294
|
-
ui.
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Token tracking
|
|
298
|
-
var tokTotal = 0;
|
|
299
|
-
if (result.usage) {
|
|
300
|
-
tokTotal =
|
|
301
|
-
result.usage.total ||
|
|
302
|
-
result.usage.total_tokens ||
|
|
303
|
-
(result.usage.input || 0) + (result.usage.output || 0) ||
|
|
304
|
-
0;
|
|
305
|
-
}
|
|
306
|
-
// Estimate tokens from text length if no usage data
|
|
307
|
-
if (!tokTotal && result.text) {
|
|
308
|
-
tokTotal = Math.ceil(result.text.length / 4) + Math.ceil(input.length / 4);
|
|
299
|
+
ui.renderResponse("Error: " + JSON.stringify(res.data), "error");
|
|
309
300
|
}
|
|
310
|
-
if (tokTotal) ui.addTokens(tokTotal);
|
|
311
|
-
|
|
312
|
-
var usedModel = settings.model || "chat";
|
|
313
|
-
ui.renderMiniStatus(usedModel, tokTotal);
|
|
314
301
|
showPrompt(rl, username, model);
|
|
315
302
|
})
|
|
316
303
|
.catch(function (e) {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
ui.renderResponse("Stream failed, trying non-stream...", "system");
|
|
324
|
-
return client
|
|
325
|
-
.sendMessage(input, { model: settings.model || "auto" })
|
|
326
|
-
.then(function (res) {
|
|
327
|
-
if (res.status === 200 && res.data) {
|
|
328
|
-
var text =
|
|
329
|
-
res.data.answer ||
|
|
330
|
-
res.data.response ||
|
|
331
|
-
res.data.text ||
|
|
332
|
-
res.data.message ||
|
|
333
|
-
JSON.stringify(res.data);
|
|
334
|
-
ui.renderResponse(text, "agent");
|
|
335
|
-
var tok = res.data.tokens || res.data.usage || {};
|
|
336
|
-
var tokTotal = tok.total || tok.total_tokens || 0;
|
|
337
|
-
if (tokTotal) ui.addTokens(tokTotal);
|
|
338
|
-
ui.renderMiniStatus(settings.model || "chat", tokTotal);
|
|
339
|
-
} else if (res.status === 401 || res.status === 403) {
|
|
340
|
-
ui.renderResponse(
|
|
341
|
-
"Auth error. Use /login to re-authenticate.",
|
|
342
|
-
"error"
|
|
343
|
-
);
|
|
344
|
-
} else {
|
|
345
|
-
ui.renderResponse(
|
|
346
|
-
"Error: " + JSON.stringify(res.data),
|
|
347
|
-
"error"
|
|
348
|
-
);
|
|
349
|
-
}
|
|
350
|
-
showPrompt(rl, username, model);
|
|
351
|
-
})
|
|
352
|
-
.catch(function (e2) {
|
|
353
|
-
ui.renderResponse(
|
|
354
|
-
"Request failed: " + e2.message + "\n Try /login if auth expired.",
|
|
355
|
-
"error"
|
|
356
|
-
);
|
|
357
|
-
showPrompt(rl, username, model);
|
|
358
|
-
});
|
|
304
|
+
ui.stopSpinner(false, e.message);
|
|
305
|
+
ui.renderResponse(
|
|
306
|
+
"Request failed: " + e.message + "\n Try /login if auth expired.",
|
|
307
|
+
"error"
|
|
308
|
+
);
|
|
309
|
+
showPrompt(rl, username, model);
|
|
359
310
|
});
|
|
360
311
|
});
|
|
361
312
|
|
package/lib/ui.js
CHANGED
|
@@ -60,31 +60,20 @@ function getInputBoxWidth() {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
function renderInputBox(username, model, permMode) {
|
|
63
|
-
|
|
64
|
-
var u = username || "user";
|
|
65
|
-
var m = model || "auto";
|
|
66
|
-
var pm = permMode || "normal";
|
|
67
|
-
var hints = "/help \u2502 /settings \u2502 /model \u2502 /exit";
|
|
68
|
-
var labelText = " " + u + " [" + m + "] ";
|
|
69
|
-
var hintsText = " " + hints + " ";
|
|
70
|
-
var topFill = w - labelText.length - hintsText.length;
|
|
71
|
-
if (topFill < 2) topFill = 2;
|
|
72
|
-
var topLine =
|
|
73
|
-
chalk.dim("\u256d") +
|
|
74
|
-
chalk.cyan(labelText) +
|
|
75
|
-
chalk.dim("\u2500".repeat(topFill)) +
|
|
76
|
-
chalk.dim(hintsText) +
|
|
77
|
-
chalk.dim("\u256e");
|
|
78
|
-
console.log(topLine);
|
|
63
|
+
// Claude Code style - no box, just clean space
|
|
79
64
|
}
|
|
80
65
|
|
|
66
|
+
var currentPermMode = "normal";
|
|
67
|
+
function setCurrentPerm(pm) { currentPermMode = pm; }
|
|
68
|
+
|
|
81
69
|
function renderInputBoxClose() {
|
|
82
|
-
|
|
83
|
-
|
|
70
|
+
// Show permission line after input (like Claude Code)
|
|
71
|
+
var label = permissionLabels[currentPermMode] || permissionLabels.normal;
|
|
72
|
+
console.log(chalk.dim(" \u276f\u276f ") + chalk.dim("bypass permissions ") + label + chalk.dim(" (shift+tab to cycle)"));
|
|
84
73
|
}
|
|
85
74
|
|
|
86
75
|
function renderPrompt() {
|
|
87
|
-
return chalk.
|
|
76
|
+
return chalk.bold.green("> ");
|
|
88
77
|
}
|
|
89
78
|
|
|
90
79
|
function renderPermissionLine(permMode) {
|
|
@@ -114,27 +103,15 @@ function renderResponse(text, type) {
|
|
|
114
103
|
var rendered = renderMarkdown(text);
|
|
115
104
|
|
|
116
105
|
if (type === "agent") {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
borderStyle: "round",
|
|
124
|
-
borderColor: "green",
|
|
125
|
-
})
|
|
126
|
-
);
|
|
106
|
+
// Claude Code style - plain text with green prefix, no box
|
|
107
|
+
var lines = rendered.split("\n");
|
|
108
|
+
lines.forEach(function (line) {
|
|
109
|
+
console.log(" " + chalk.green(line));
|
|
110
|
+
});
|
|
111
|
+
console.log();
|
|
127
112
|
} else if (type === "error") {
|
|
128
|
-
console.log(
|
|
129
|
-
|
|
130
|
-
title: chalk.red.bold(" \u2718 Error "),
|
|
131
|
-
titleAlignment: "left",
|
|
132
|
-
padding: { top: 0, bottom: 0, left: 1, right: 1 },
|
|
133
|
-
margin: { top: 0, bottom: 0, left: 1, right: 1 },
|
|
134
|
-
borderStyle: "round",
|
|
135
|
-
borderColor: "red",
|
|
136
|
-
})
|
|
137
|
-
);
|
|
113
|
+
console.log(chalk.red(" \u2718 " + rendered));
|
|
114
|
+
console.log();
|
|
138
115
|
} else if (type === "system") {
|
|
139
116
|
console.log(chalk.yellow.bold(" [SYS] ") + chalk.yellow(rendered));
|
|
140
117
|
console.log();
|
|
@@ -381,6 +358,7 @@ module.exports = {
|
|
|
381
358
|
renderPrompt: renderPrompt,
|
|
382
359
|
renderInputBox: renderInputBox,
|
|
383
360
|
renderInputBoxClose: renderInputBoxClose,
|
|
361
|
+
setCurrentPerm: setCurrentPerm,
|
|
384
362
|
renderWelcomeInfo: renderWelcomeInfo,
|
|
385
363
|
renderPermissionLine: renderPermissionLine,
|
|
386
364
|
renderMiniStatus: renderMiniStatus,
|