sharkcode 0.3.5 → 0.3.7

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 +77 -30
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -204,6 +204,23 @@ import { exec } from "child_process";
204
204
 
205
205
  // src/permission.ts
206
206
  import chalk from "chalk";
207
+
208
+ // src/spinnerState.ts
209
+ var _stop = null;
210
+ function registerToolSpinner(stop) {
211
+ _stop = stop;
212
+ }
213
+ function unregisterToolSpinner() {
214
+ _stop = null;
215
+ }
216
+ function stopToolSpinner() {
217
+ if (_stop) {
218
+ _stop();
219
+ _stop = null;
220
+ }
221
+ }
222
+
223
+ // src/permission.ts
207
224
  var PURPLE = chalk.hex("#a855f7");
208
225
  var GRAY = chalk.gray;
209
226
  var GREEN = chalk.green;
@@ -224,6 +241,7 @@ async function askPermission(command) {
224
241
  );
225
242
  return true;
226
243
  }
244
+ stopToolSpinner();
227
245
  const width = Math.min(72, process.stdout.columns ?? 80);
228
246
  const innerWidth = width - 4;
229
247
  const line = (s) => ` ${s}
@@ -315,28 +333,45 @@ function createProvider(config) {
315
333
 
316
334
  // src/agent.ts
317
335
  var PURPLE2 = chalk2.hex("#a855f7");
336
+ var PURPLE_DIM = chalk2.hex("#7c3aed");
318
337
  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" }
338
+ read_file: { icon: "\u{1F4D6}", verb: "reading" },
339
+ write_file: { icon: "\u270D\uFE0F ", verb: "writing" },
340
+ edit_file: { icon: "\u270F\uFE0F ", verb: "editing" },
341
+ bash: { icon: "\u2699\uFE0F ", verb: "running" }
323
342
  };
343
+ function playScanLine() {
344
+ return new Promise((resolve4) => {
345
+ const cols = Math.min(process.stdout.columns ?? 80, 72);
346
+ const steps = 12;
347
+ const chars = "\u258F\u258E\u258D\u258C\u258B\u258A\u2589\u2588\u2589\u258A\u258B\u258C\u258D\u258E\u258F";
348
+ let frame = 0;
349
+ const t = setInterval(() => {
350
+ const pos = Math.floor(frame / steps * cols);
351
+ const bar = PURPLE_DIM("\u2500".repeat(pos)) + PURPLE2(chars[frame % chars.length]) + chalk2.dim("\u2500".repeat(Math.max(0, cols - pos - 1)));
352
+ process.stdout.write(`\r${bar}`);
353
+ frame++;
354
+ if (frame >= steps) {
355
+ clearInterval(t);
356
+ process.stdout.write(`\r${PURPLE2("\u2500".repeat(cols))}
357
+ `);
358
+ resolve4();
359
+ }
360
+ }, 30);
361
+ });
362
+ }
324
363
  function createSpinner(label) {
325
364
  const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
326
365
  let i = 0;
327
366
  let timer = null;
328
367
  return {
329
368
  start() {
330
- process.stdout.write("\n");
331
369
  timer = setInterval(() => {
332
370
  process.stdout.write(
333
- `\r${PURPLE2(frames[i++ % frames.length])} ${chalk2.gray(label)}`
371
+ `\r ${PURPLE2(frames[i++ % frames.length])} ${chalk2.gray(label)}`
334
372
  );
335
373
  }, 80);
336
374
  },
337
- update(newLabel) {
338
- label = newLabel;
339
- },
340
375
  stop() {
341
376
  if (timer) {
342
377
  clearInterval(timer);
@@ -378,9 +413,9 @@ async function runAgent(messages, config) {
378
413
  let currentStep = 0;
379
414
  const thinkingSpinner = createSpinner("thinking...");
380
415
  let thinkingDone = false;
416
+ let lastWasNewline = true;
381
417
  let toolSpinner = null;
382
418
  let currentToolName = "";
383
- let currentToolArgs = null;
384
419
  thinkingSpinner.start();
385
420
  for await (const event of result.fullStream) {
386
421
  if (!thinkingDone && (event.type === "text-delta" || event.type === "tool-call" || event.type === "error")) {
@@ -390,42 +425,49 @@ async function runAgent(messages, config) {
390
425
  switch (event.type) {
391
426
  case "text-delta":
392
427
  process.stdout.write(event.text);
428
+ lastWasNewline = event.text.endsWith("\n");
393
429
  break;
394
430
  case "tool-call": {
395
431
  const meta = TOOL_LABELS[event.toolName] ?? { icon: "\u{1F527}", verb: "running" };
396
432
  currentToolName = event.toolName;
397
- currentToolArgs = event.input;
398
433
  const argHint = getArgHint(event.toolName, event.input);
399
- const spinLabel = `${meta.verb}${argHint ? ` \u203A ${argHint}` : ""}`;
434
+ if (!lastWasNewline) process.stdout.write("\n");
435
+ await playScanLine();
400
436
  process.stdout.write(
401
- "\n" + chalk2.cyan(`${meta.icon} ${event.toolName}`) + chalk2.gray(argHint ? ` ${argHint}` : "") + "\n"
437
+ ` ${meta.icon} ${PURPLE2(meta.verb)}${argHint ? chalk2.dim(" \u203A ") + chalk2.white(argHint) : ""}
438
+ `
402
439
  );
403
- toolSpinner = createSpinner(spinLabel);
440
+ toolSpinner = createSpinner(`${meta.verb}...`);
441
+ registerToolSpinner(() => toolSpinner?.stop());
404
442
  toolSpinner.start();
443
+ lastWasNewline = false;
405
444
  break;
406
445
  }
407
446
  case "tool-result": {
408
447
  if (toolSpinner) {
409
448
  toolSpinner.stop();
410
449
  toolSpinner = null;
450
+ unregisterToolSpinner();
411
451
  }
412
- const meta = TOOL_LABELS[currentToolName] ?? { icon: "\u{1F527}", verb: "done" };
413
- const summary = truncate(String(event.output), 100);
452
+ const summary = truncate(String(event.output), 80);
414
453
  process.stdout.write(
415
- chalk2.green(` \u2713 done`) + chalk2.gray(` ${summary}`) + "\n\n"
454
+ ` ${chalk2.green("\u2713")} ${chalk2.dim(summary)}
455
+ `
416
456
  );
457
+ lastWasNewline = true;
417
458
  break;
418
459
  }
419
460
  case "tool-error":
420
461
  if (toolSpinner) {
421
462
  toolSpinner.stop();
422
463
  toolSpinner = null;
464
+ unregisterToolSpinner();
423
465
  }
424
466
  process.stderr.write(
425
- chalk2.red(`
426
- \u2717 Tool error [${event.toolName}]: ${String(event.error)}
467
+ chalk2.red(` \u2717 [${event.toolName}] ${String(event.error)}
427
468
  `)
428
469
  );
470
+ lastWasNewline = true;
429
471
  break;
430
472
  case "finish-step":
431
473
  currentStep++;
@@ -434,24 +476,27 @@ async function runAgent(messages, config) {
434
476
  if (toolSpinner) {
435
477
  toolSpinner.stop();
436
478
  toolSpinner = null;
479
+ unregisterToolSpinner();
437
480
  }
438
481
  thinkingSpinner.stop();
439
482
  process.stderr.write(chalk2.red(`
440
- \u274C Error: ${String(event.error)}
483
+ \u274C ${String(event.error)}
441
484
  `));
485
+ lastWasNewline = true;
442
486
  break;
443
487
  }
444
488
  }
445
489
  thinkingSpinner.stop();
446
- if (toolSpinner) toolSpinner.stop();
447
- process.stdout.write("\n");
490
+ if (toolSpinner) {
491
+ toolSpinner.stop();
492
+ unregisterToolSpinner();
493
+ }
494
+ if (!lastWasNewline) process.stdout.write("\n");
448
495
  const usage = await result.totalUsage;
449
496
  if (usage) {
450
497
  process.stderr.write(
451
- chalk2.gray(
452
- `\u{1F4CA} ${usage.inputTokens} in / ${usage.outputTokens} out | steps: ${currentStep}
453
- `
454
- )
498
+ chalk2.dim(` \u{1F4CA} ${usage.inputTokens}\u2191 ${usage.outputTokens}\u2193 steps:${currentStep}
499
+ `)
455
500
  );
456
501
  }
457
502
  try {
@@ -502,17 +547,19 @@ var GLYPHS = {
502
547
  };
503
548
  function renderWord(word, padLeft = 2) {
504
549
  const letters = word.toUpperCase().split("").map((c) => GLYPHS[c]);
550
+ const ON = chalk3.bgHex("#a855f7")(" ");
551
+ const OFF = " ";
505
552
  const rows = [];
506
553
  for (let row = 0; row < 5; row++) {
507
554
  let line = " ".repeat(padLeft);
508
555
  for (let i = 0; i < letters.length; i++) {
509
556
  const letter = letters[i];
510
557
  for (let col = 0; col < letter[row].length; col++) {
511
- line += letter[row][col] ? "\u2588\u2588" : " ";
558
+ line += letter[row][col] ? ON : OFF;
512
559
  }
513
- if (i < letters.length - 1) line += " ";
560
+ if (i < letters.length - 1) line += OFF;
514
561
  }
515
- rows.push(PURPLE3(line));
562
+ rows.push(line);
516
563
  }
517
564
  return rows;
518
565
  }
@@ -691,7 +738,7 @@ async function main() {
691
738
  return;
692
739
  }
693
740
  if (args[0] === "--version" || args[0] === "-v") {
694
- console.log("sharkcode v0.3.5");
741
+ console.log("sharkcode v0.3.6");
695
742
  return;
696
743
  }
697
744
  if (args.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sharkcode",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
4
4
  "description": "Local First, open-source AI Coding Agent",
5
5
  "type": "module",
6
6
  "bin": {