sharkcode 0.3.4 → 0.3.5
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/dist/cli.mjs +174 -69
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -33,6 +33,7 @@ function serializeConfig(mc) {
|
|
|
33
33
|
"",
|
|
34
34
|
"[default]",
|
|
35
35
|
`provider = "${mc.activeProvider}"`,
|
|
36
|
+
`permission_mode = "${mc.permissionMode}"`,
|
|
36
37
|
"",
|
|
37
38
|
"[providers.deepseek]",
|
|
38
39
|
"# API key from https://platform.deepseek.com",
|
|
@@ -53,6 +54,7 @@ function ensureConfig() {
|
|
|
53
54
|
if (!existsSync(CONFIG_FILE)) {
|
|
54
55
|
const initial = {
|
|
55
56
|
activeProvider: "deepseek",
|
|
57
|
+
permissionMode: "prompt",
|
|
56
58
|
providers: {
|
|
57
59
|
deepseek: { key: "", model: PROVIDERS.deepseek.defaultModel },
|
|
58
60
|
ark: { key: "", model: PROVIDERS.ark.defaultModel }
|
|
@@ -75,8 +77,10 @@ function readMultiConfig() {
|
|
|
75
77
|
const deepseekKey = process.env.DEEPSEEK_API_KEY || providersRaw.deepseek?.key || legacy?.key || "";
|
|
76
78
|
const arkKey = process.env.ARK_API_KEY || providersRaw.ark?.key || "";
|
|
77
79
|
const activeProvider = defaultSection.provider || (legacy ? "deepseek" : "deepseek");
|
|
80
|
+
const permissionMode = defaultSection.permission_mode === "full-access" ? "full-access" : "prompt";
|
|
78
81
|
return {
|
|
79
82
|
activeProvider,
|
|
83
|
+
permissionMode,
|
|
80
84
|
providers: {
|
|
81
85
|
deepseek: {
|
|
82
86
|
key: deepseekKey,
|
|
@@ -200,19 +204,57 @@ import { exec } from "child_process";
|
|
|
200
204
|
|
|
201
205
|
// src/permission.ts
|
|
202
206
|
import chalk from "chalk";
|
|
207
|
+
var PURPLE = chalk.hex("#a855f7");
|
|
208
|
+
var GRAY = chalk.gray;
|
|
209
|
+
var GREEN = chalk.green;
|
|
210
|
+
var RED = chalk.red;
|
|
211
|
+
var YELLOW = chalk.yellow;
|
|
212
|
+
var DIM = chalk.dim;
|
|
213
|
+
var _permissionMode = "prompt";
|
|
214
|
+
function setPermissionMode(mode) {
|
|
215
|
+
_permissionMode = mode;
|
|
216
|
+
}
|
|
217
|
+
function getPermissionMode() {
|
|
218
|
+
return _permissionMode;
|
|
219
|
+
}
|
|
203
220
|
async function askPermission(command) {
|
|
221
|
+
if (_permissionMode === "full-access") {
|
|
222
|
+
process.stdout.write(
|
|
223
|
+
PURPLE(" \u25C6 ") + DIM("auto-approved") + GRAY(" \u203A ") + chalk.white(command) + "\n"
|
|
224
|
+
);
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
const width = Math.min(72, process.stdout.columns ?? 80);
|
|
228
|
+
const innerWidth = width - 4;
|
|
229
|
+
const line = (s) => ` ${s}
|
|
230
|
+
`;
|
|
231
|
+
const bar = PURPLE("\u2500".repeat(width));
|
|
232
|
+
const label = YELLOW(" \u26A1 \u6267\u884C\u547D\u4EE4");
|
|
233
|
+
const cmd = chalk.white.bold(command.length > innerWidth ? command.slice(0, innerWidth - 1) + "\u2026" : command);
|
|
234
|
+
process.stderr.write("\n");
|
|
235
|
+
process.stderr.write(bar + "\n");
|
|
236
|
+
process.stderr.write(line(label));
|
|
237
|
+
process.stderr.write(line(" " + cmd));
|
|
238
|
+
process.stderr.write(bar + "\n");
|
|
204
239
|
process.stderr.write(
|
|
205
|
-
|
|
206
|
-
\u26A0\uFE0F Will execute: `) + chalk.white(command) + "\n"
|
|
240
|
+
" " + GREEN("[ y ] \u5141\u8BB8") + " " + RED("[ n ] \u62D2\u7EDD") + " " + DIM("[ a ] \u672C\u6B21\u5168\u90E8\u5141\u8BB8") + "\n\n"
|
|
207
241
|
);
|
|
208
|
-
process.stderr.write(
|
|
242
|
+
process.stderr.write(PURPLE(" \u25C6 ") + GRAY("\u6309\u952E\u51B3\u5B9A \u203A "));
|
|
209
243
|
return new Promise((resolve4) => {
|
|
210
244
|
const onData = (chunk) => {
|
|
211
|
-
const ch = chunk.toString("utf8")[0] ?? "";
|
|
245
|
+
const ch = chunk.toString("utf8")[0]?.toLowerCase() ?? "";
|
|
212
246
|
process.stdin.removeListener("data", onData);
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
247
|
+
if (ch === "y") {
|
|
248
|
+
process.stderr.write(GREEN("y \u5141\u8BB8\n\n"));
|
|
249
|
+
resolve4(true);
|
|
250
|
+
} else if (ch === "a") {
|
|
251
|
+
process.stderr.write(YELLOW("a \u5DF2\u5207\u6362\u4E3A Full Access\uFF08\u672C\u6B21\u4F1A\u8BDD\uFF09\n\n"));
|
|
252
|
+
_permissionMode = "full-access";
|
|
253
|
+
resolve4(true);
|
|
254
|
+
} else {
|
|
255
|
+
process.stderr.write(RED("n \u62D2\u7EDD\n\n"));
|
|
256
|
+
resolve4(false);
|
|
257
|
+
}
|
|
216
258
|
};
|
|
217
259
|
process.stdin.once("data", onData);
|
|
218
260
|
});
|
|
@@ -272,8 +314,14 @@ function createProvider(config) {
|
|
|
272
314
|
}
|
|
273
315
|
|
|
274
316
|
// src/agent.ts
|
|
275
|
-
var
|
|
276
|
-
|
|
317
|
+
var PURPLE2 = chalk2.hex("#a855f7");
|
|
318
|
+
var TOOL_LABELS = {
|
|
319
|
+
read_file: { icon: "\u{1F4D6}", verb: "reading file" },
|
|
320
|
+
write_file: { icon: "\u270D\uFE0F ", verb: "writing file" },
|
|
321
|
+
edit_file: { icon: "\u270F\uFE0F ", verb: "editing file" },
|
|
322
|
+
bash: { icon: "\u2699\uFE0F ", verb: "running command" }
|
|
323
|
+
};
|
|
324
|
+
function createSpinner(label) {
|
|
277
325
|
const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
278
326
|
let i = 0;
|
|
279
327
|
let timer = null;
|
|
@@ -282,10 +330,13 @@ function createSpinner() {
|
|
|
282
330
|
process.stdout.write("\n");
|
|
283
331
|
timer = setInterval(() => {
|
|
284
332
|
process.stdout.write(
|
|
285
|
-
`\r${
|
|
333
|
+
`\r${PURPLE2(frames[i++ % frames.length])} ${chalk2.gray(label)}`
|
|
286
334
|
);
|
|
287
335
|
}, 80);
|
|
288
336
|
},
|
|
337
|
+
update(newLabel) {
|
|
338
|
+
label = newLabel;
|
|
339
|
+
},
|
|
289
340
|
stop() {
|
|
290
341
|
if (timer) {
|
|
291
342
|
clearInterval(timer);
|
|
@@ -325,36 +376,54 @@ async function runAgent(messages, config) {
|
|
|
325
376
|
stopWhen: stepCountIs(30)
|
|
326
377
|
});
|
|
327
378
|
let currentStep = 0;
|
|
328
|
-
const
|
|
329
|
-
let
|
|
330
|
-
|
|
379
|
+
const thinkingSpinner = createSpinner("thinking...");
|
|
380
|
+
let thinkingDone = false;
|
|
381
|
+
let toolSpinner = null;
|
|
382
|
+
let currentToolName = "";
|
|
383
|
+
let currentToolArgs = null;
|
|
384
|
+
thinkingSpinner.start();
|
|
331
385
|
for await (const event of result.fullStream) {
|
|
332
|
-
if (!
|
|
333
|
-
|
|
334
|
-
|
|
386
|
+
if (!thinkingDone && (event.type === "text-delta" || event.type === "tool-call" || event.type === "error")) {
|
|
387
|
+
thinkingSpinner.stop();
|
|
388
|
+
thinkingDone = true;
|
|
335
389
|
}
|
|
336
390
|
switch (event.type) {
|
|
337
391
|
case "text-delta":
|
|
338
392
|
process.stdout.write(event.text);
|
|
339
393
|
break;
|
|
340
|
-
case "tool-call":
|
|
394
|
+
case "tool-call": {
|
|
395
|
+
const meta = TOOL_LABELS[event.toolName] ?? { icon: "\u{1F527}", verb: "running" };
|
|
396
|
+
currentToolName = event.toolName;
|
|
397
|
+
currentToolArgs = event.input;
|
|
398
|
+
const argHint = getArgHint(event.toolName, event.input);
|
|
399
|
+
const spinLabel = `${meta.verb}${argHint ? ` \u203A ${argHint}` : ""}`;
|
|
341
400
|
process.stdout.write(
|
|
342
|
-
chalk2.cyan(`
|
|
343
|
-
\u{1F527} ${event.toolName}`) + chalk2.gray(`(${formatArgs(event.input)})
|
|
344
|
-
`)
|
|
401
|
+
"\n" + chalk2.cyan(`${meta.icon} ${event.toolName}`) + chalk2.gray(argHint ? ` ${argHint}` : "") + "\n"
|
|
345
402
|
);
|
|
403
|
+
toolSpinner = createSpinner(spinLabel);
|
|
404
|
+
toolSpinner.start();
|
|
346
405
|
break;
|
|
347
|
-
|
|
406
|
+
}
|
|
407
|
+
case "tool-result": {
|
|
408
|
+
if (toolSpinner) {
|
|
409
|
+
toolSpinner.stop();
|
|
410
|
+
toolSpinner = null;
|
|
411
|
+
}
|
|
412
|
+
const meta = TOOL_LABELS[currentToolName] ?? { icon: "\u{1F527}", verb: "done" };
|
|
413
|
+
const summary = truncate(String(event.output), 100);
|
|
348
414
|
process.stdout.write(
|
|
349
|
-
chalk2.green(
|
|
350
|
-
|
|
351
|
-
`)
|
|
415
|
+
chalk2.green(` \u2713 done`) + chalk2.gray(` ${summary}`) + "\n\n"
|
|
352
416
|
);
|
|
353
417
|
break;
|
|
418
|
+
}
|
|
354
419
|
case "tool-error":
|
|
420
|
+
if (toolSpinner) {
|
|
421
|
+
toolSpinner.stop();
|
|
422
|
+
toolSpinner = null;
|
|
423
|
+
}
|
|
355
424
|
process.stderr.write(
|
|
356
425
|
chalk2.red(`
|
|
357
|
-
\
|
|
426
|
+
\u2717 Tool error [${event.toolName}]: ${String(event.error)}
|
|
358
427
|
`)
|
|
359
428
|
);
|
|
360
429
|
break;
|
|
@@ -362,22 +431,25 @@ async function runAgent(messages, config) {
|
|
|
362
431
|
currentStep++;
|
|
363
432
|
break;
|
|
364
433
|
case "error":
|
|
434
|
+
if (toolSpinner) {
|
|
435
|
+
toolSpinner.stop();
|
|
436
|
+
toolSpinner = null;
|
|
437
|
+
}
|
|
438
|
+
thinkingSpinner.stop();
|
|
365
439
|
process.stderr.write(chalk2.red(`
|
|
366
440
|
\u274C Error: ${String(event.error)}
|
|
367
441
|
`));
|
|
368
442
|
break;
|
|
369
443
|
}
|
|
370
444
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
}
|
|
445
|
+
thinkingSpinner.stop();
|
|
446
|
+
if (toolSpinner) toolSpinner.stop();
|
|
374
447
|
process.stdout.write("\n");
|
|
375
448
|
const usage = await result.totalUsage;
|
|
376
449
|
if (usage) {
|
|
377
450
|
process.stderr.write(
|
|
378
451
|
chalk2.gray(
|
|
379
|
-
|
|
380
|
-
\u{1F4CA} Tokens: ${usage.inputTokens} in / ${usage.outputTokens} out | Steps: ${currentStep}
|
|
452
|
+
`\u{1F4CA} ${usage.inputTokens} in / ${usage.outputTokens} out | steps: ${currentStep}
|
|
381
453
|
`
|
|
382
454
|
)
|
|
383
455
|
);
|
|
@@ -389,25 +461,33 @@ async function runAgent(messages, config) {
|
|
|
389
461
|
return messages;
|
|
390
462
|
}
|
|
391
463
|
}
|
|
392
|
-
function
|
|
393
|
-
if (typeof args !== "object" || args === null) return
|
|
464
|
+
function getArgHint(toolName, args) {
|
|
465
|
+
if (typeof args !== "object" || args === null) return "";
|
|
394
466
|
const obj = args;
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
467
|
+
switch (toolName) {
|
|
468
|
+
case "read_file":
|
|
469
|
+
case "write_file":
|
|
470
|
+
case "edit_file":
|
|
471
|
+
return truncate(String(obj.path ?? obj.file_path ?? ""), 50);
|
|
472
|
+
case "bash":
|
|
473
|
+
return truncate(String(obj.command ?? ""), 50);
|
|
474
|
+
default: {
|
|
475
|
+
const first = Object.values(obj).find((v) => typeof v === "string");
|
|
476
|
+
return first ? truncate(first, 50) : "";
|
|
477
|
+
}
|
|
478
|
+
}
|
|
399
479
|
}
|
|
400
480
|
function truncate(str, max) {
|
|
401
|
-
const oneLine = str.replace(/\n/g, "
|
|
481
|
+
const oneLine = str.replace(/\n/g, "\u21B5");
|
|
402
482
|
return oneLine.length > max ? oneLine.slice(0, max) + "\u2026" : oneLine;
|
|
403
483
|
}
|
|
404
484
|
|
|
405
485
|
// src/cli.ts
|
|
406
|
-
var
|
|
407
|
-
var
|
|
408
|
-
var
|
|
409
|
-
var
|
|
410
|
-
var
|
|
486
|
+
var PURPLE3 = chalk3.hex("#a855f7");
|
|
487
|
+
var GRAY2 = chalk3.gray;
|
|
488
|
+
var YELLOW2 = chalk3.yellow;
|
|
489
|
+
var GREEN2 = chalk3.green;
|
|
490
|
+
var RED2 = chalk3.red;
|
|
411
491
|
var CYAN = chalk3.cyan;
|
|
412
492
|
var GLYPHS = {
|
|
413
493
|
S: [[0, 1, 1, 1, 1], [1, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 1], [1, 1, 1, 1, 0]],
|
|
@@ -432,18 +512,21 @@ function renderWord(word, padLeft = 2) {
|
|
|
432
512
|
}
|
|
433
513
|
if (i < letters.length - 1) line += " ";
|
|
434
514
|
}
|
|
435
|
-
rows.push(
|
|
515
|
+
rows.push(PURPLE3(line));
|
|
436
516
|
}
|
|
437
517
|
return rows;
|
|
438
518
|
}
|
|
439
519
|
var BANNER = ["", ...renderWord("shark", 2), "", ...renderWord("code", 8), ""].join("\n");
|
|
440
520
|
async function showCommandMenu(multiConfig) {
|
|
441
521
|
console.log();
|
|
522
|
+
const permMode = getPermissionMode();
|
|
523
|
+
const permLabel = permMode === "full-access" ? "\u26A1 \u6743\u9650\u6A21\u5F0F\uFF1AFull Access " + chalk3.dim("(\u70B9\u51FB\u5207\u6362\u56DE\u9ED8\u8BA4)") : "\u{1F510} \u6743\u9650\u6A21\u5F0F\uFF1A\u9ED8\u8BA4 " + chalk3.dim("(\u70B9\u51FB\u5F00\u542F Full Access)");
|
|
442
524
|
try {
|
|
443
525
|
const action = await select({
|
|
444
|
-
message:
|
|
526
|
+
message: PURPLE3("\u25C6 \u9009\u62E9\u64CD\u4F5C"),
|
|
445
527
|
choices: [
|
|
446
528
|
{ name: "\u{1F50C} \u5207\u6362 / \u914D\u7F6E Provider", value: "provider" },
|
|
529
|
+
{ name: permLabel, value: "permission" },
|
|
447
530
|
{ name: "\u{1F5D1}\uFE0F \u6E05\u7A7A\u5BF9\u8BDD\u5386\u53F2", value: "clear" },
|
|
448
531
|
{ name: "\u{1F6AA} \u9000\u51FA", value: "exit" }
|
|
449
532
|
]
|
|
@@ -451,35 +534,54 @@ async function showCommandMenu(multiConfig) {
|
|
|
451
534
|
switch (action) {
|
|
452
535
|
case "provider":
|
|
453
536
|
return showSetupFlow(multiConfig);
|
|
537
|
+
case "permission":
|
|
538
|
+
return togglePermissionMode(multiConfig);
|
|
454
539
|
case "clear":
|
|
455
|
-
console.log(
|
|
540
|
+
console.log(GRAY2("\n \u2713 \u5BF9\u8BDD\u5DF2\u6E05\u7A7A\n"));
|
|
456
541
|
return { multiConfig, config: resolveConfig(multiConfig), clearHistory: true };
|
|
457
542
|
case "exit":
|
|
458
|
-
console.log(
|
|
543
|
+
console.log(GRAY2("\nBye! \u{1F988}"));
|
|
459
544
|
return { multiConfig, config: resolveConfig(multiConfig), exit: true };
|
|
460
545
|
}
|
|
461
546
|
} catch {
|
|
462
|
-
console.log(
|
|
547
|
+
console.log(GRAY2("\n \u53D6\u6D88\n"));
|
|
463
548
|
}
|
|
464
549
|
return { multiConfig, config: resolveConfig(multiConfig) };
|
|
465
550
|
}
|
|
551
|
+
async function togglePermissionMode(multiConfig) {
|
|
552
|
+
const current = getPermissionMode();
|
|
553
|
+
const next = current === "full-access" ? "prompt" : "full-access";
|
|
554
|
+
setPermissionMode(next);
|
|
555
|
+
const updated = { ...multiConfig, permissionMode: next };
|
|
556
|
+
saveMultiConfig(updated);
|
|
557
|
+
if (next === "full-access") {
|
|
558
|
+
console.log(
|
|
559
|
+
chalk3.yellow("\n \u26A1 Full Access \u5DF2\u5F00\u542F") + GRAY2(" \u2014 agent \u5C06\u81EA\u52A8\u6279\u51C6\u6240\u6709\u5DE5\u5177\u64CD\u4F5C\n")
|
|
560
|
+
);
|
|
561
|
+
} else {
|
|
562
|
+
console.log(
|
|
563
|
+
chalk3.green("\n \u{1F510} \u5DF2\u6062\u590D\u9ED8\u8BA4\u6743\u9650") + GRAY2(" \u2014 \u6BCF\u6B21\u5DE5\u5177\u8C03\u7528\u524D\u4F1A\u8BE2\u95EE\n")
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
return { multiConfig: updated, config: resolveConfig(updated) };
|
|
567
|
+
}
|
|
466
568
|
async function showSetupFlow(multiConfig) {
|
|
467
569
|
console.log();
|
|
468
570
|
try {
|
|
469
571
|
const providerChoices = Object.entries(PROVIDERS).map(([id, meta]) => {
|
|
470
572
|
const hasKey = !!multiConfig.providers[id]?.key;
|
|
471
|
-
const badge = hasKey ?
|
|
573
|
+
const badge = hasKey ? GREEN2("\u2713 \u5DF2\u914D\u7F6E") : YELLOW2("\u2717 \u672A\u914D\u7F6E");
|
|
472
574
|
return { name: `${meta.label} ${badge}`, value: id };
|
|
473
575
|
});
|
|
474
576
|
const selectedProvider = await select({
|
|
475
|
-
message:
|
|
577
|
+
message: PURPLE3("\u25C6 \u9009\u62E9 Provider"),
|
|
476
578
|
choices: providerChoices,
|
|
477
579
|
default: multiConfig.activeProvider
|
|
478
580
|
});
|
|
479
581
|
const currentKey = multiConfig.providers[selectedProvider]?.key ?? "";
|
|
480
|
-
const hint = currentKey ?
|
|
582
|
+
const hint = currentKey ? GRAY2("(\u56DE\u8F66\u4FDD\u7559 " + currentKey.slice(0, 6) + "\u2022\u2022\u2022)") : GRAY2("(\u5FC5\u586B)");
|
|
481
583
|
const rawKey = await input({
|
|
482
|
-
message:
|
|
584
|
+
message: PURPLE3("\u25C6 API Key ") + hint,
|
|
483
585
|
default: currentKey || void 0
|
|
484
586
|
});
|
|
485
587
|
const newKey = rawKey.trim() || currentKey;
|
|
@@ -500,14 +602,14 @@ async function showSetupFlow(multiConfig) {
|
|
|
500
602
|
saveMultiConfig(updated);
|
|
501
603
|
const newConfig = resolveConfig(updated);
|
|
502
604
|
const keyMsg = newKey && newKey !== currentKey ? "\uFF0CAPI Key \u5DF2\u4FDD\u5B58" : "";
|
|
503
|
-
console.log(
|
|
605
|
+
console.log(GREEN2(`
|
|
504
606
|
\u2713 \u5DF2\u5207\u6362\u5230 ${PROVIDERS[selectedProvider].label}${keyMsg}`) + "\n");
|
|
505
607
|
if (!newConfig.apiKey) {
|
|
506
|
-
console.log(
|
|
608
|
+
console.log(YELLOW2(" \u26A0 \u8FD8\u672A\u586B\u5199 API Key\uFF0C\u65E0\u6CD5\u53D1\u9001\u6D88\u606F\n"));
|
|
507
609
|
}
|
|
508
610
|
return { multiConfig: updated, config: newConfig };
|
|
509
611
|
} catch {
|
|
510
|
-
console.log(
|
|
612
|
+
console.log(GRAY2("\n \u53D6\u6D88\n"));
|
|
511
613
|
return { multiConfig, config: resolveConfig(multiConfig) };
|
|
512
614
|
}
|
|
513
615
|
}
|
|
@@ -574,31 +676,33 @@ async function readLineRaw(promptStr) {
|
|
|
574
676
|
}
|
|
575
677
|
function statusLine(config) {
|
|
576
678
|
const label = PROVIDERS[config.providerName]?.label ?? config.providerName;
|
|
577
|
-
|
|
679
|
+
const permMode = getPermissionMode();
|
|
680
|
+
const permBadge = permMode === "full-access" ? chalk3.yellow(" \u26A1 Full Access") : GRAY2(" \u{1F510} \u9ED8\u8BA4\u6743\u9650");
|
|
681
|
+
return PURPLE3(" \u25C6") + GRAY2(` ${label}`) + CYAN(` [${config.model}]`) + permBadge + GRAY2(" \u8F93\u5165 / \u8C03\u51FA\u6307\u4EE4\u83DC\u5355\n");
|
|
578
682
|
}
|
|
579
683
|
async function main() {
|
|
580
684
|
const args = process.argv.slice(2);
|
|
581
685
|
if (args[0] === "--help" || args[0] === "-h") {
|
|
582
686
|
console.log(BANNER);
|
|
583
|
-
console.log(
|
|
584
|
-
console.log(" " +
|
|
585
|
-
console.log(" " +
|
|
586
|
-
console.log(
|
|
687
|
+
console.log(PURPLE3(" Usage:"));
|
|
688
|
+
console.log(" " + PURPLE3("sharkcode") + GRAY2(" \u2014 \u4EA4\u4E92\u6A21\u5F0F\uFF08\u76F4\u63A5\u542F\u52A8\uFF09"));
|
|
689
|
+
console.log(" " + PURPLE3("sharkcode") + YELLOW2(' "prompt"') + GRAY2(" \u2014 \u5355\u6B21\u6267\u884C"));
|
|
690
|
+
console.log(GRAY2("\n \u4EA4\u4E92\u6A21\u5F0F\u5185\u8F93\u5165 / \u8C03\u51FA\u6307\u4EE4\u83DC\u5355\n"));
|
|
587
691
|
return;
|
|
588
692
|
}
|
|
589
693
|
if (args[0] === "--version" || args[0] === "-v") {
|
|
590
|
-
console.log("sharkcode v0.3.
|
|
694
|
+
console.log("sharkcode v0.3.5");
|
|
591
695
|
return;
|
|
592
696
|
}
|
|
593
697
|
if (args.length > 0) {
|
|
594
698
|
const mc = readMultiConfig();
|
|
595
699
|
const config2 = resolveConfig(mc);
|
|
596
700
|
if (!config2.apiKey) {
|
|
597
|
-
console.error(
|
|
701
|
+
console.error(RED2("\u274C \u672A\u914D\u7F6E API Key\u3002\u8BF7\u5148\u8FD0\u884C sharkcode \u5E76\u8F93\u5165 / \u914D\u7F6E Provider\u3002"));
|
|
598
702
|
process.exit(1);
|
|
599
703
|
}
|
|
600
704
|
console.log(
|
|
601
|
-
|
|
705
|
+
PURPLE3("\n\u{1F988} SharkCode") + GRAY2(` | ${PROVIDERS[config2.providerName]?.label ?? config2.providerName} | ${config2.model}
|
|
602
706
|
`)
|
|
603
707
|
);
|
|
604
708
|
await runAgent([{ role: "user", content: args.join(" ") }], config2);
|
|
@@ -607,6 +711,7 @@ async function main() {
|
|
|
607
711
|
console.log(BANNER);
|
|
608
712
|
let multiConfig = readMultiConfig();
|
|
609
713
|
let config = resolveConfig(multiConfig);
|
|
714
|
+
setPermissionMode(multiConfig.permissionMode ?? "prompt");
|
|
610
715
|
try {
|
|
611
716
|
process.stdin.setRawMode(true);
|
|
612
717
|
process.stdin.resume();
|
|
@@ -615,20 +720,20 @@ async function main() {
|
|
|
615
720
|
console.log(statusLine(config));
|
|
616
721
|
if (!config.apiKey) {
|
|
617
722
|
console.log(
|
|
618
|
-
|
|
723
|
+
YELLOW2(" \u26A0 \u5C1A\u672A\u914D\u7F6E API Key\u3002") + GRAY2("\u8F93\u5165 / \u7136\u540E\u9009\u62E9\u300C\u5207\u6362 / \u914D\u7F6E Provider\u300D\n")
|
|
619
724
|
);
|
|
620
725
|
}
|
|
621
726
|
let messages = [];
|
|
622
727
|
while (true) {
|
|
623
|
-
const raw = await readLineRaw(
|
|
728
|
+
const raw = await readLineRaw(PURPLE3("\n\u25C6 "));
|
|
624
729
|
if (raw === null) {
|
|
625
|
-
console.log(
|
|
730
|
+
console.log(GRAY2("\nBye! \u{1F988}"));
|
|
626
731
|
break;
|
|
627
732
|
}
|
|
628
733
|
const trimmed = raw.trim();
|
|
629
734
|
if (!trimmed) continue;
|
|
630
735
|
if (trimmed === "exit" || trimmed === "quit") {
|
|
631
|
-
console.log(
|
|
736
|
+
console.log(GRAY2("Bye! \u{1F988}"));
|
|
632
737
|
break;
|
|
633
738
|
}
|
|
634
739
|
if (trimmed === "/") {
|
|
@@ -659,11 +764,11 @@ async function main() {
|
|
|
659
764
|
continue;
|
|
660
765
|
}
|
|
661
766
|
if (trimmed.startsWith("/")) {
|
|
662
|
-
console.log(
|
|
767
|
+
console.log(GRAY2(" \u672A\u77E5\u547D\u4EE4\u3002\u8F93\u5165 / \u8C03\u51FA\u6307\u4EE4\u83DC\u5355\n"));
|
|
663
768
|
continue;
|
|
664
769
|
}
|
|
665
770
|
if (!config.apiKey) {
|
|
666
|
-
console.log(
|
|
771
|
+
console.log(YELLOW2(" \u26A0 \u8FD8\u672A\u586B\u5199 API Key\u3002\u8F93\u5165 / \u2192 \u5207\u6362 / \u914D\u7F6E Provider\n"));
|
|
667
772
|
continue;
|
|
668
773
|
}
|
|
669
774
|
messages.push({ role: "user", content: trimmed });
|
|
@@ -675,7 +780,7 @@ async function main() {
|
|
|
675
780
|
} catch {
|
|
676
781
|
}
|
|
677
782
|
} catch (err) {
|
|
678
|
-
console.error(
|
|
783
|
+
console.error(RED2(`
|
|
679
784
|
\u274C ${String(err)}
|
|
680
785
|
`));
|
|
681
786
|
messages.pop();
|