sharkbait 1.0.21 → 1.0.23

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.js +93 -65
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1378,16 +1378,20 @@ import { join as join3 } from "path";
1378
1378
  import { existsSync as existsSync3 } from "fs";
1379
1379
  import { execSync } from "child_process";
1380
1380
  function getBdPath() {
1381
- const paths = [
1382
- "bd",
1381
+ try {
1382
+ execSync("bd --version", { stdio: ["ignore", "ignore", "ignore"] });
1383
+ return "bd";
1384
+ } catch {}
1385
+ const fallbacks = [
1383
1386
  join3(homedir2(), "AppData", "Local", "beads", "bd.exe"),
1384
1387
  join3(homedir2(), ".local", "bin", "bd"),
1385
1388
  "/usr/local/bin/bd"
1386
1389
  ];
1387
- if (process.platform === "win32") {
1388
- return paths[1];
1390
+ for (const p of fallbacks) {
1391
+ if (existsSync3(p))
1392
+ return p;
1389
1393
  }
1390
- return paths[0];
1394
+ return "bd";
1391
1395
  }
1392
1396
  var BD_PATH = getBdPath();
1393
1397
  function isBeadsInitialized(cwd) {
@@ -6505,14 +6509,15 @@ Duration: ${(result.totalDurationMs / 1000).toFixed(1)}s`
6505
6509
  }
6506
6510
  }
6507
6511
  // src/agent/start-chat.ts
6508
- import React3 from "react";
6512
+ import React6 from "react";
6509
6513
  import { render } from "ink";
6510
6514
 
6511
6515
  // src/ui/app.tsx
6512
- import React2, { useState as useState2, useEffect as useEffect2, useCallback, useRef } from "react";
6516
+ import React5, { useState as useState2, useEffect as useEffect2, useCallback, useRef } from "react";
6513
6517
  import { Box as Box12, Text as Text12, useInput, useApp } from "ink";
6514
6518
 
6515
6519
  // src/ui/message.tsx
6520
+ import { memo } from "react";
6516
6521
  import { Box as Box2, Text as Text2 } from "ink";
6517
6522
 
6518
6523
  // src/ui/theme.ts
@@ -6700,7 +6705,7 @@ function HighlightedContent({ content }) {
6700
6705
 
6701
6706
  // src/ui/message.tsx
6702
6707
  import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
6703
- function MessageView({
6708
+ var MessageView = memo(function MessageView2({
6704
6709
  role,
6705
6710
  content,
6706
6711
  timestamp,
@@ -6769,7 +6774,7 @@ function MessageView({
6769
6774
  }, undefined, false, undefined, this)
6770
6775
  ]
6771
6776
  }, undefined, true, undefined, this);
6772
- }
6777
+ });
6773
6778
 
6774
6779
  // src/ui/spinner.tsx
6775
6780
  import { useState, useEffect } from "react";
@@ -6965,9 +6970,10 @@ function WelcomeScreen({ version, workingDir }) {
6965
6970
  }
6966
6971
 
6967
6972
  // src/ui/status-bar.tsx
6973
+ import { memo as memo2 } from "react";
6968
6974
  import { Box as Box6, Text as Text6 } from "ink";
6969
6975
  import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
6970
- function StatusBar({
6976
+ var StatusBar = memo2(function StatusBar2({
6971
6977
  model,
6972
6978
  tokens = 0,
6973
6979
  cost = 0,
@@ -7057,7 +7063,7 @@ function StatusBar({
7057
7063
  }, undefined, false, undefined, this)
7058
7064
  ]
7059
7065
  }, undefined, true, undefined, this);
7060
- }
7066
+ });
7061
7067
 
7062
7068
  // src/ui/input-prompt.tsx
7063
7069
  import { Box as Box7, Text as Text7 } from "ink";
@@ -7091,9 +7097,10 @@ function InputPrompt({
7091
7097
  }
7092
7098
 
7093
7099
  // src/ui/tool-call.tsx
7100
+ import { memo as memo3 } from "react";
7094
7101
  import { Box as Box8, Text as Text8 } from "ink";
7095
- import { jsxDEV as jsxDEV8, Fragment } from "react/jsx-dev-runtime";
7096
- function ToolCallView({
7102
+ import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
7103
+ var ToolCallView = memo3(function ToolCallView2({
7097
7104
  name,
7098
7105
  status,
7099
7106
  result,
@@ -7101,7 +7108,7 @@ function ToolCallView({
7101
7108
  duration
7102
7109
  }) {
7103
7110
  const statusConfig = {
7104
- running: { icon: icons.tool, color: colors.primary },
7111
+ running: { icon: "⟳", color: colors.primary },
7105
7112
  success: { icon: icons.success, color: colors.success },
7106
7113
  error: { icon: icons.error, color: colors.error }
7107
7114
  };
@@ -7116,34 +7123,33 @@ function ToolCallView({
7116
7123
  paddingX: 1,
7117
7124
  children: [
7118
7125
  /* @__PURE__ */ jsxDEV8(Box8, {
7119
- children: status === "running" ? /* @__PURE__ */ jsxDEV8(Spinner, {
7120
- text: name,
7121
- variant: "dots"
7122
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV8(Fragment, {
7123
- children: [
7124
- /* @__PURE__ */ jsxDEV8(Text8, {
7125
- color: config.color,
7126
- children: [
7127
- config.icon,
7128
- " "
7129
- ]
7130
- }, undefined, true, undefined, this),
7131
- /* @__PURE__ */ jsxDEV8(Text8, {
7132
- bold: true,
7133
- color: colors.text,
7134
- children: name
7135
- }, undefined, false, undefined, this),
7136
- durationText && /* @__PURE__ */ jsxDEV8(Text8, {
7137
- color: colors.textDim,
7138
- children: [
7139
- " (",
7140
- durationText,
7141
- ")"
7142
- ]
7143
- }, undefined, true, undefined, this)
7144
- ]
7145
- }, undefined, true, undefined, this)
7146
- }, undefined, false, undefined, this),
7126
+ children: [
7127
+ /* @__PURE__ */ jsxDEV8(Text8, {
7128
+ color: config.color,
7129
+ children: [
7130
+ config.icon,
7131
+ " "
7132
+ ]
7133
+ }, undefined, true, undefined, this),
7134
+ /* @__PURE__ */ jsxDEV8(Text8, {
7135
+ bold: true,
7136
+ color: colors.text,
7137
+ children: name
7138
+ }, undefined, false, undefined, this),
7139
+ status === "running" && /* @__PURE__ */ jsxDEV8(Text8, {
7140
+ color: colors.textDim,
7141
+ children: " ..."
7142
+ }, undefined, false, undefined, this),
7143
+ durationText && /* @__PURE__ */ jsxDEV8(Text8, {
7144
+ color: colors.textDim,
7145
+ children: [
7146
+ " (",
7147
+ durationText,
7148
+ ")"
7149
+ ]
7150
+ }, undefined, true, undefined, this)
7151
+ ]
7152
+ }, undefined, true, undefined, this),
7147
7153
  result && status === "success" && /* @__PURE__ */ jsxDEV8(Box8, {
7148
7154
  marginLeft: 2,
7149
7155
  marginTop: 0,
@@ -7171,7 +7177,7 @@ function ToolCallView({
7171
7177
  }, undefined, false, undefined, this)
7172
7178
  ]
7173
7179
  }, undefined, true, undefined, this);
7174
- }
7180
+ });
7175
7181
 
7176
7182
  // src/ui/parallel-progress.tsx
7177
7183
  import { Box as Box9, Text as Text9 } from "ink";
@@ -8304,7 +8310,7 @@ Type /help for available commands.`,
8304
8310
  }
8305
8311
  // src/ui/app.tsx
8306
8312
  import { basename as basename3 } from "path";
8307
- import { jsxDEV as jsxDEV12, Fragment as Fragment2 } from "react/jsx-dev-runtime";
8313
+ import { jsxDEV as jsxDEV12, Fragment } from "react/jsx-dev-runtime";
8308
8314
  function estimateTokens(text) {
8309
8315
  return Math.ceil(text.length / 4);
8310
8316
  }
@@ -8349,19 +8355,35 @@ function App({ contextFiles: initialContextFiles, enableBeads: initialBeadsEnabl
8349
8355
  });
8350
8356
  const abortControllerRef = useRef(null);
8351
8357
  const pendingOutputRef = useRef("");
8358
+ const pendingTokensRef = useRef(0);
8359
+ const pendingCostRef = useRef(0);
8352
8360
  const outputTimerRef = useRef(null);
8353
8361
  const { exit } = useApp();
8354
8362
  const workingDir = currentDir;
8355
8363
  const flushOutput = useCallback(() => {
8356
- if (pendingOutputRef.current) {
8357
- setCurrentOutput(pendingOutputRef.current);
8364
+ const output = pendingOutputRef.current;
8365
+ const tokens = pendingTokensRef.current;
8366
+ const cost = pendingCostRef.current;
8367
+ if (output)
8368
+ setCurrentOutput(output);
8369
+ if (tokens > 0) {
8370
+ setTokenCount((prev) => prev + tokens);
8371
+ pendingTokensRef.current = 0;
8372
+ }
8373
+ if (cost > 0) {
8374
+ setSessionCost((prev) => prev + cost);
8375
+ pendingCostRef.current = 0;
8358
8376
  }
8359
8377
  outputTimerRef.current = null;
8360
8378
  }, []);
8361
- const throttledSetOutput = useCallback((content) => {
8379
+ const throttledSetOutput = useCallback((content, chunkTokens) => {
8362
8380
  pendingOutputRef.current = content;
8381
+ if (chunkTokens && chunkTokens > 0) {
8382
+ pendingTokensRef.current += chunkTokens;
8383
+ pendingCostRef.current += chunkTokens * 0.00003;
8384
+ }
8363
8385
  if (!outputTimerRef.current) {
8364
- outputTimerRef.current = setTimeout(flushOutput, 50);
8386
+ outputTimerRef.current = setTimeout(flushOutput, 80);
8365
8387
  }
8366
8388
  }, [flushOutput]);
8367
8389
  useEffect2(() => {
@@ -8370,11 +8392,11 @@ function App({ contextFiles: initialContextFiles, enableBeads: initialBeadsEnabl
8370
8392
  clearTimeout(outputTimerRef.current);
8371
8393
  };
8372
8394
  }, []);
8373
- const agent = React2.useMemo(() => new Agent({
8395
+ const agent = React5.useMemo(() => new Agent({
8374
8396
  contextFiles,
8375
8397
  enableBeads: beadsEnabled
8376
8398
  }), [contextFiles, beadsEnabled]);
8377
- const commandContext = React2.useMemo(() => ({
8399
+ const commandContext = React5.useMemo(() => ({
8378
8400
  currentDir,
8379
8401
  setCurrentDir,
8380
8402
  addMessage: (role, content) => {
@@ -8533,10 +8555,8 @@ function App({ contextFiles: initialContextFiles, enableBeads: initialBeadsEnabl
8533
8555
  switch (event.type) {
8534
8556
  case "text":
8535
8557
  assistantContent += event.content;
8536
- throttledSetOutput(assistantContent);
8537
8558
  const chunkTokens = estimateTokens(event.content);
8538
- setTokenCount((prev) => prev + chunkTokens);
8539
- setSessionCost((prev) => prev + chunkTokens * 0.00003);
8559
+ throttledSetOutput(assistantContent, chunkTokens);
8540
8560
  break;
8541
8561
  case "agent_start":
8542
8562
  setCurrentAgent(event.agent);
@@ -8636,6 +8656,14 @@ ${event.consolidated}`,
8636
8656
  clearTimeout(outputTimerRef.current);
8637
8657
  outputTimerRef.current = null;
8638
8658
  }
8659
+ if (pendingTokensRef.current > 0) {
8660
+ setTokenCount((prev) => prev + pendingTokensRef.current);
8661
+ pendingTokensRef.current = 0;
8662
+ }
8663
+ if (pendingCostRef.current > 0) {
8664
+ setSessionCost((prev) => prev + pendingCostRef.current);
8665
+ pendingCostRef.current = 0;
8666
+ }
8639
8667
  pendingOutputRef.current = "";
8640
8668
  if (assistantContent.trim()) {
8641
8669
  setMessages((prev) => [...prev, {
@@ -8780,7 +8808,7 @@ ${event.consolidated}`,
8780
8808
  justifyContent: "center",
8781
8809
  children: /* @__PURE__ */ jsxDEV12(Text12, {
8782
8810
  color: colors.textDim,
8783
- children: isExecuting ? /* @__PURE__ */ jsxDEV12(Fragment2, {
8811
+ children: isExecuting ? /* @__PURE__ */ jsxDEV12(Fragment, {
8784
8812
  children: [
8785
8813
  "Press ",
8786
8814
  /* @__PURE__ */ jsxDEV12(Text12, {
@@ -8789,7 +8817,7 @@ ${event.consolidated}`,
8789
8817
  }, undefined, false, undefined, this),
8790
8818
  " to cancel"
8791
8819
  ]
8792
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV12(Fragment2, {
8820
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV12(Fragment, {
8793
8821
  children: [
8794
8822
  "Press ",
8795
8823
  /* @__PURE__ */ jsxDEV12(Text12, {
@@ -8811,7 +8839,7 @@ ${event.consolidated}`,
8811
8839
  }
8812
8840
 
8813
8841
  // src/version.ts
8814
- var VERSION = "1.0.21";
8842
+ var VERSION = "1.0.23";
8815
8843
 
8816
8844
  // src/agent/start-chat.ts
8817
8845
  async function startChat(options = {}) {
@@ -8821,7 +8849,7 @@ async function startChat(options = {}) {
8821
8849
  process.chdir(workingDir);
8822
8850
  }
8823
8851
  } catch {}
8824
- const { waitUntilExit } = render(React3.createElement(App, {
8852
+ const { waitUntilExit } = render(React6.createElement(App, {
8825
8853
  contextFiles: options.context,
8826
8854
  enableBeads: options.beads ?? true,
8827
8855
  version: VERSION,
@@ -8995,7 +9023,7 @@ Task completed.`);
8995
9023
  }
8996
9024
 
8997
9025
  // src/commands/setup.tsx
8998
- import React4, { useState as useState3, useEffect as useEffect3 } from "react";
9026
+ import React7, { useState as useState3, useEffect as useEffect3 } from "react";
8999
9027
  import { render as render2, Box as Box13, Text as Text13, useInput as useInput2, useApp as useApp2 } from "ink";
9000
9028
  import TextInput from "ink-text-input";
9001
9029
  import { writeFile as writeFile4, readFile as readFile3, mkdir as mkdir4, stat as stat3 } from "fs/promises";
@@ -9003,7 +9031,7 @@ import { join as join8, resolve as resolve4 } from "path";
9003
9031
  import { homedir as homedir4 } from "os";
9004
9032
  import { existsSync as existsSync6 } from "fs";
9005
9033
  import { execSync as execSync2 } from "child_process";
9006
- import { jsxDEV as jsxDEV13, Fragment as Fragment3 } from "react/jsx-dev-runtime";
9034
+ import { jsxDEV as jsxDEV13, Fragment as Fragment2 } from "react/jsx-dev-runtime";
9007
9035
  function SetupWizardWithCallback({ onComplete }) {
9008
9036
  const { exit } = useApp2();
9009
9037
  const [step, setStep] = useState3("welcome");
@@ -9858,7 +9886,7 @@ function SetupWizardWithCallback({ onComplete }) {
9858
9886
  beadsVersion ? ` — ${beadsVersion}` : ""
9859
9887
  ]
9860
9888
  }, undefined, true, undefined, this),
9861
- beadsInstallStatus === "failed" && /* @__PURE__ */ jsxDEV13(Fragment3, {
9889
+ beadsInstallStatus === "failed" && /* @__PURE__ */ jsxDEV13(Fragment2, {
9862
9890
  children: [
9863
9891
  /* @__PURE__ */ jsxDEV13(Text13, {
9864
9892
  color: colors.warning,
@@ -9890,7 +9918,7 @@ function SetupWizardWithCallback({ onComplete }) {
9890
9918
  /* @__PURE__ */ jsxDEV13(Box13, {
9891
9919
  marginTop: 1,
9892
9920
  flexDirection: "column",
9893
- children: state.authMethod === "azure-identity" ? /* @__PURE__ */ jsxDEV13(Fragment3, {
9921
+ children: state.authMethod === "azure-identity" ? /* @__PURE__ */ jsxDEV13(Fragment2, {
9894
9922
  children: [
9895
9923
  /* @__PURE__ */ jsxDEV13(Text13, {
9896
9924
  color: colors.textMuted,
@@ -9907,7 +9935,7 @@ function SetupWizardWithCallback({ onComplete }) {
9907
9935
  ]
9908
9936
  }, undefined, true, undefined, this)
9909
9937
  ]
9910
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV13(Fragment3, {
9938
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV13(Fragment2, {
9911
9939
  children: [
9912
9940
  /* @__PURE__ */ jsxDEV13(Text13, {
9913
9941
  color: colors.textMuted,
@@ -9958,13 +9986,13 @@ function SetupWizardWithCallback({ onComplete }) {
9958
9986
  async function runSetup() {
9959
9987
  let setupCompleted = false;
9960
9988
  function SetupWizardWrapper() {
9961
- return React4.createElement(SetupWizardWithCallback, {
9989
+ return React7.createElement(SetupWizardWithCallback, {
9962
9990
  onComplete: () => {
9963
9991
  setupCompleted = true;
9964
9992
  }
9965
9993
  });
9966
9994
  }
9967
- const { waitUntilExit } = render2(React4.createElement(SetupWizardWrapper));
9995
+ const { waitUntilExit } = render2(React7.createElement(SetupWizardWrapper));
9968
9996
  await waitUntilExit();
9969
9997
  return setupCompleted;
9970
9998
  }
@@ -10095,7 +10123,7 @@ ${"━".repeat(60)}`);
10095
10123
  }
10096
10124
 
10097
10125
  // src/version.ts
10098
- var VERSION2 = "1.0.21";
10126
+ var VERSION2 = "1.0.23";
10099
10127
 
10100
10128
  // src/ui/logo.tsx
10101
10129
  import { Box as Box14, Text as Text14 } from "ink";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sharkbait",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "description": "AI-powered coding assistant for the command line. Uses OpenAI Responses API (not Chat). Autonomous agents, parallel code reviews, 36 tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/cli.js",