sharkbait 1.0.12 → 1.0.14
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.js +63 -32
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -746,14 +746,6 @@ var REQUIRES_CONFIRMATION = [
|
|
|
746
746
|
undoHint: "chown with original owner"
|
|
747
747
|
}
|
|
748
748
|
];
|
|
749
|
-
var SHELL_CHAINING_PATTERNS = [
|
|
750
|
-
/;/,
|
|
751
|
-
/\|\|/,
|
|
752
|
-
/&&/,
|
|
753
|
-
/\$\(/,
|
|
754
|
-
/`[^`]+`/,
|
|
755
|
-
/\|\s*\w/
|
|
756
|
-
];
|
|
757
749
|
var DANGEROUS_PREFIXES = ["sudo", "doas", "pkexec", "exec"];
|
|
758
750
|
function classifyCommand(command) {
|
|
759
751
|
const trimmed = command.trim();
|
|
@@ -780,17 +772,30 @@ function classifyCommand(command) {
|
|
|
780
772
|
reversibility: "effort"
|
|
781
773
|
};
|
|
782
774
|
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
775
|
+
if (/\$\(/.test(trimmed) || /`[^`]+`/.test(trimmed)) {
|
|
776
|
+
return {
|
|
777
|
+
status: "requires_confirmation",
|
|
778
|
+
reason: "Command contains command substitution ($() or backticks)",
|
|
779
|
+
reversibility: "effort"
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
const hasChaining = /;|&&|\|\||(\|\s*\w)/.test(trimmed);
|
|
783
|
+
if (hasChaining) {
|
|
784
|
+
const subCommands = trimmed.split(/\s*(?:;|&&|\|\|)\s*/).flatMap((segment) => segment.split(/\s*\|\s*/)).map((s) => s.trim()).filter(Boolean);
|
|
785
|
+
for (const sub of subCommands) {
|
|
786
|
+
const subSafety = classifySimpleCommand(sub);
|
|
787
|
+
if (subSafety.status === "blocked")
|
|
788
|
+
return subSafety;
|
|
789
|
+
if (subSafety.status === "requires_confirmation")
|
|
790
|
+
return subSafety;
|
|
790
791
|
}
|
|
792
|
+
return { status: "allowed" };
|
|
791
793
|
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
+
return classifySimpleCommand(trimmed);
|
|
795
|
+
}
|
|
796
|
+
function classifySimpleCommand(command) {
|
|
797
|
+
const baseCommand = extractBaseCommand(command);
|
|
798
|
+
if (isOnAllowlist(baseCommand, command)) {
|
|
794
799
|
return { status: "allowed" };
|
|
795
800
|
}
|
|
796
801
|
return {
|
|
@@ -6423,7 +6428,7 @@ import React3 from "react";
|
|
|
6423
6428
|
import { render } from "ink";
|
|
6424
6429
|
|
|
6425
6430
|
// src/ui/app.tsx
|
|
6426
|
-
import React2, { useState as useState2, useRef } from "react";
|
|
6431
|
+
import React2, { useState as useState2, useEffect as useEffect2, useCallback, useRef } from "react";
|
|
6427
6432
|
import { Box as Box12, Text as Text12, useInput, useApp } from "ink";
|
|
6428
6433
|
|
|
6429
6434
|
// src/ui/message.tsx
|
|
@@ -6700,7 +6705,7 @@ function Spinner({
|
|
|
6700
6705
|
useEffect(() => {
|
|
6701
6706
|
const timer = setInterval(() => {
|
|
6702
6707
|
setFrameIndex((prev) => (prev + 1) % frames.length);
|
|
6703
|
-
},
|
|
6708
|
+
}, 200);
|
|
6704
6709
|
return () => clearInterval(timer);
|
|
6705
6710
|
}, [frames.length]);
|
|
6706
6711
|
return /* @__PURE__ */ jsxDEV3(Box3, {
|
|
@@ -8262,8 +8267,28 @@ function App({ contextFiles: initialContextFiles, enableBeads: initialBeadsEnabl
|
|
|
8262
8267
|
return config.azure.deployment;
|
|
8263
8268
|
});
|
|
8264
8269
|
const abortControllerRef = useRef(null);
|
|
8270
|
+
const pendingOutputRef = useRef("");
|
|
8271
|
+
const outputTimerRef = useRef(null);
|
|
8265
8272
|
const { exit } = useApp();
|
|
8266
8273
|
const workingDir = currentDir;
|
|
8274
|
+
const flushOutput = useCallback(() => {
|
|
8275
|
+
if (pendingOutputRef.current) {
|
|
8276
|
+
setCurrentOutput(pendingOutputRef.current);
|
|
8277
|
+
}
|
|
8278
|
+
outputTimerRef.current = null;
|
|
8279
|
+
}, []);
|
|
8280
|
+
const throttledSetOutput = useCallback((content) => {
|
|
8281
|
+
pendingOutputRef.current = content;
|
|
8282
|
+
if (!outputTimerRef.current) {
|
|
8283
|
+
outputTimerRef.current = setTimeout(flushOutput, 50);
|
|
8284
|
+
}
|
|
8285
|
+
}, [flushOutput]);
|
|
8286
|
+
useEffect2(() => {
|
|
8287
|
+
return () => {
|
|
8288
|
+
if (outputTimerRef.current)
|
|
8289
|
+
clearTimeout(outputTimerRef.current);
|
|
8290
|
+
};
|
|
8291
|
+
}, []);
|
|
8267
8292
|
const agent = React2.useMemo(() => new Agent({
|
|
8268
8293
|
contextFiles,
|
|
8269
8294
|
enableBeads: beadsEnabled
|
|
@@ -8427,7 +8452,7 @@ function App({ contextFiles: initialContextFiles, enableBeads: initialBeadsEnabl
|
|
|
8427
8452
|
switch (event.type) {
|
|
8428
8453
|
case "text":
|
|
8429
8454
|
assistantContent += event.content;
|
|
8430
|
-
|
|
8455
|
+
throttledSetOutput(assistantContent);
|
|
8431
8456
|
const chunkTokens = estimateTokens(event.content);
|
|
8432
8457
|
setTokenCount((prev) => prev + chunkTokens);
|
|
8433
8458
|
setSessionCost((prev) => prev + chunkTokens * 0.00003);
|
|
@@ -8497,18 +8522,18 @@ ${event.consolidated}`,
|
|
|
8497
8522
|
}
|
|
8498
8523
|
case "tool_result": {
|
|
8499
8524
|
const duration = event.duration;
|
|
8500
|
-
setActiveToolCalls((prev) => prev.map((tc) => tc.name === event.name && tc.status === "running" ? {
|
|
8501
|
-
...tc,
|
|
8502
|
-
status: "success",
|
|
8503
|
-
duration,
|
|
8504
|
-
result: typeof event.result === "string" ? event.result.slice(0, 100) : JSON.stringify(event.result).slice(0, 100)
|
|
8505
|
-
} : tc));
|
|
8506
8525
|
setActiveToolCalls((prev) => {
|
|
8507
|
-
const
|
|
8526
|
+
const updated = prev.map((tc) => tc.name === event.name && tc.status === "running" ? {
|
|
8527
|
+
...tc,
|
|
8528
|
+
status: "success",
|
|
8529
|
+
duration,
|
|
8530
|
+
result: typeof event.result === "string" ? event.result.slice(0, 100) : JSON.stringify(event.result).slice(0, 100)
|
|
8531
|
+
} : tc);
|
|
8532
|
+
const completed = updated.find((tc) => tc.name === event.name && tc.status === "success");
|
|
8508
8533
|
if (completed) {
|
|
8509
8534
|
completedToolCalls.push(completed);
|
|
8510
8535
|
}
|
|
8511
|
-
return
|
|
8536
|
+
return updated.filter((tc) => !(tc.name === event.name && tc.status === "success"));
|
|
8512
8537
|
});
|
|
8513
8538
|
break;
|
|
8514
8539
|
}
|
|
@@ -8526,6 +8551,11 @@ ${event.consolidated}`,
|
|
|
8526
8551
|
setTokenCount(event.totalTokens);
|
|
8527
8552
|
break;
|
|
8528
8553
|
case "done":
|
|
8554
|
+
if (outputTimerRef.current) {
|
|
8555
|
+
clearTimeout(outputTimerRef.current);
|
|
8556
|
+
outputTimerRef.current = null;
|
|
8557
|
+
}
|
|
8558
|
+
pendingOutputRef.current = "";
|
|
8529
8559
|
if (assistantContent.trim()) {
|
|
8530
8560
|
setMessages((prev) => [...prev, {
|
|
8531
8561
|
role: "assistant",
|
|
@@ -8636,7 +8666,8 @@ ${event.consolidated}`,
|
|
|
8636
8666
|
}, undefined, false, undefined, this),
|
|
8637
8667
|
currentOutput && /* @__PURE__ */ jsxDEV12(MessageView, {
|
|
8638
8668
|
role: "assistant",
|
|
8639
|
-
content: currentOutput
|
|
8669
|
+
content: currentOutput,
|
|
8670
|
+
enableHighlighting: false
|
|
8640
8671
|
}, undefined, false, undefined, this)
|
|
8641
8672
|
]
|
|
8642
8673
|
}, undefined, true, undefined, this),
|
|
@@ -8699,7 +8730,7 @@ ${event.consolidated}`,
|
|
|
8699
8730
|
}
|
|
8700
8731
|
|
|
8701
8732
|
// src/version.ts
|
|
8702
|
-
var VERSION = "1.0.
|
|
8733
|
+
var VERSION = "1.0.14";
|
|
8703
8734
|
|
|
8704
8735
|
// src/agent/start-chat.ts
|
|
8705
8736
|
async function startChat(options = {}) {
|
|
@@ -8714,7 +8745,7 @@ async function startChat(options = {}) {
|
|
|
8714
8745
|
enableBeads: options.beads ?? true,
|
|
8715
8746
|
version: VERSION,
|
|
8716
8747
|
workingDir
|
|
8717
|
-
}));
|
|
8748
|
+
}), { patchConsole: true });
|
|
8718
8749
|
await waitUntilExit();
|
|
8719
8750
|
}
|
|
8720
8751
|
// src/commands/init.ts
|
|
@@ -9876,7 +9907,7 @@ ${"━".repeat(60)}`);
|
|
|
9876
9907
|
}
|
|
9877
9908
|
|
|
9878
9909
|
// src/version.ts
|
|
9879
|
-
var VERSION2 = "1.0.
|
|
9910
|
+
var VERSION2 = "1.0.14";
|
|
9880
9911
|
|
|
9881
9912
|
// src/ui/logo.tsx
|
|
9882
9913
|
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.
|
|
3
|
+
"version": "1.0.14",
|
|
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",
|