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.
Files changed (2) hide show
  1. package/dist/cli.mjs +174 -69
  2. 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
- chalk.yellow(`
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(chalk.yellow(" Allow? [y/N] "));
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
- const yes = ch.toLowerCase() === "y";
214
- process.stderr.write(yes ? "y\n" : "N\n");
215
- resolve4(yes);
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 PURPLE = chalk2.hex("#a855f7");
276
- function createSpinner() {
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${PURPLE(frames[i++ % frames.length])} ${chalk2.gray("thinking...")}`
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 spinner = createSpinner();
329
- let spinnerStopped = false;
330
- spinner.start();
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 (!spinnerStopped && (event.type === "text-delta" || event.type === "tool-call" || event.type === "error")) {
333
- spinner.stop();
334
- spinnerStopped = true;
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
- case "tool-result":
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(`\u2705 done`) + chalk2.gray(` \u2192 ${truncate(String(event.output), 120)}
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
- \u274C Tool error [${event.toolName}]: ${String(event.error)}
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
- if (!spinnerStopped) {
372
- spinner.stop();
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 formatArgs(args) {
393
- if (typeof args !== "object" || args === null) return String(args);
464
+ function getArgHint(toolName, args) {
465
+ if (typeof args !== "object" || args === null) return "";
394
466
  const obj = args;
395
- return Object.entries(obj).map(([k, v]) => {
396
- const val = typeof v === "string" ? truncate(v, 60) : String(v);
397
- return `${k}: ${val}`;
398
- }).join(", ");
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, "\\n");
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 PURPLE2 = chalk3.hex("#a855f7");
407
- var GRAY = chalk3.gray;
408
- var YELLOW = chalk3.yellow;
409
- var GREEN = chalk3.green;
410
- var RED = chalk3.red;
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(PURPLE2(line));
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: PURPLE2("\u25C6 \u9009\u62E9\u64CD\u4F5C"),
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(GRAY("\n \u2713 \u5BF9\u8BDD\u5DF2\u6E05\u7A7A\n"));
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(GRAY("\nBye! \u{1F988}"));
543
+ console.log(GRAY2("\nBye! \u{1F988}"));
459
544
  return { multiConfig, config: resolveConfig(multiConfig), exit: true };
460
545
  }
461
546
  } catch {
462
- console.log(GRAY("\n \u53D6\u6D88\n"));
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 ? GREEN("\u2713 \u5DF2\u914D\u7F6E") : YELLOW("\u2717 \u672A\u914D\u7F6E");
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: PURPLE2("\u25C6 \u9009\u62E9 Provider"),
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 ? GRAY("(\u56DE\u8F66\u4FDD\u7559 " + currentKey.slice(0, 6) + "\u2022\u2022\u2022)") : GRAY("(\u5FC5\u586B)");
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: PURPLE2("\u25C6 API Key ") + hint,
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(GREEN(`
605
+ console.log(GREEN2(`
504
606
  \u2713 \u5DF2\u5207\u6362\u5230 ${PROVIDERS[selectedProvider].label}${keyMsg}`) + "\n");
505
607
  if (!newConfig.apiKey) {
506
- console.log(YELLOW(" \u26A0 \u8FD8\u672A\u586B\u5199 API Key\uFF0C\u65E0\u6CD5\u53D1\u9001\u6D88\u606F\n"));
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(GRAY("\n \u53D6\u6D88\n"));
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
- return PURPLE2(" \u25C6") + GRAY(` ${label}`) + CYAN(` [${config.model}]`) + GRAY(" \u8F93\u5165 / \u8C03\u51FA\u6307\u4EE4\u83DC\u5355\n");
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(PURPLE2(" Usage:"));
584
- console.log(" " + PURPLE2("sharkcode") + GRAY(" \u2014 \u4EA4\u4E92\u6A21\u5F0F\uFF08\u76F4\u63A5\u542F\u52A8\uFF09"));
585
- console.log(" " + PURPLE2("sharkcode") + YELLOW(' "prompt"') + GRAY(" \u2014 \u5355\u6B21\u6267\u884C"));
586
- console.log(GRAY("\n \u4EA4\u4E92\u6A21\u5F0F\u5185\u8F93\u5165 / \u8C03\u51FA\u6307\u4EE4\u83DC\u5355\n"));
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.4");
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(RED("\u274C \u672A\u914D\u7F6E API Key\u3002\u8BF7\u5148\u8FD0\u884C sharkcode \u5E76\u8F93\u5165 / \u914D\u7F6E Provider\u3002"));
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
- PURPLE2("\n\u{1F988} SharkCode") + GRAY(` | ${PROVIDERS[config2.providerName]?.label ?? config2.providerName} | ${config2.model}
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
- YELLOW(" \u26A0 \u5C1A\u672A\u914D\u7F6E API Key\u3002") + GRAY("\u8F93\u5165 / \u7136\u540E\u9009\u62E9\u300C\u5207\u6362 / \u914D\u7F6E Provider\u300D\n")
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(PURPLE2("\n\u25C6 "));
728
+ const raw = await readLineRaw(PURPLE3("\n\u25C6 "));
624
729
  if (raw === null) {
625
- console.log(GRAY("\nBye! \u{1F988}"));
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(GRAY("Bye! \u{1F988}"));
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(GRAY(" \u672A\u77E5\u547D\u4EE4\u3002\u8F93\u5165 / \u8C03\u51FA\u6307\u4EE4\u83DC\u5355\n"));
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(YELLOW(" \u26A0 \u8FD8\u672A\u586B\u5199 API Key\u3002\u8F93\u5165 / \u2192 \u5207\u6362 / \u914D\u7F6E Provider\n"));
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(RED(`
783
+ console.error(RED2(`
679
784
  \u274C ${String(err)}
680
785
  `));
681
786
  messages.pop();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sharkcode",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "Local First, open-source AI Coding Agent",
5
5
  "type": "module",
6
6
  "bin": {