wave-agent-sdk 0.12.1 → 0.12.2
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/builtin/skills/settings/SKILLS.md +13 -0
- package/dist/agent.d.ts +2 -2
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +3 -2
- package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
- package/dist/managers/backgroundTaskManager.js +9 -2
- package/dist/managers/cronManager.d.ts.map +1 -1
- package/dist/managers/cronManager.js +1 -0
- package/dist/managers/permissionManager.d.ts.map +1 -1
- package/dist/managers/permissionManager.js +9 -5
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +2 -0
- package/dist/services/fileWatcher.d.ts.map +1 -1
- package/dist/services/fileWatcher.js +12 -2
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +6 -1
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +2 -14
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +6 -16
- package/dist/tools/webFetchTool.d.ts.map +1 -1
- package/dist/tools/webFetchTool.js +1 -1
- package/dist/utils/bashParser.d.ts +4 -0
- package/dist/utils/bashParser.d.ts.map +1 -1
- package/dist/utils/bashParser.js +23 -0
- package/dist/utils/messageOperations.d.ts +10 -0
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +51 -0
- package/dist/utils/stringUtils.d.ts +4 -0
- package/dist/utils/stringUtils.d.ts.map +1 -1
- package/dist/utils/stringUtils.js +21 -0
- package/package.json +1 -1
- package/src/agent.ts +3 -2
- package/src/managers/backgroundTaskManager.ts +9 -2
- package/src/managers/cronManager.ts +1 -0
- package/src/managers/permissionManager.ts +9 -4
- package/src/managers/slashCommandManager.ts +2 -0
- package/src/services/fileWatcher.ts +13 -2
- package/src/services/hook.ts +4 -1
- package/src/services/session.ts +2 -21
- package/src/tools/bashTool.ts +8 -19
- package/src/tools/webFetchTool.ts +3 -2
- package/src/utils/bashParser.ts +24 -0
- package/src/utils/messageOperations.ts +57 -0
- package/src/utils/stringUtils.ts +20 -0
|
@@ -57,8 +57,21 @@ Project skills take precedence over user skills with the same name.
|
|
|
57
57
|
- **AI-Invoked**: The agent automatically discovers and uses skills based on their `description`.
|
|
58
58
|
- **User-Invoked**: Use slash commands in the CLI (e.g., `/my-skill`).
|
|
59
59
|
|
|
60
|
+
## Inline Bash Commands
|
|
61
|
+
|
|
62
|
+
You can embed bash commands in skill content using the `!`command`` syntax. The command will be executed and its output will be inserted inline.
|
|
63
|
+
|
|
64
|
+
```markdown
|
|
65
|
+
# Example Skill
|
|
66
|
+
|
|
67
|
+
Current git status: !`git status --short`
|
|
68
|
+
|
|
69
|
+
The above command will be replaced with the actual output when the skill is invoked.
|
|
70
|
+
```
|
|
71
|
+
|
|
60
72
|
## Best Practices
|
|
61
73
|
|
|
62
74
|
- **Clear Descriptions**: Write descriptions that help the AI understand exactly when the skill is relevant.
|
|
63
75
|
- **Modular Design**: Keep skills focused on a single task or capability.
|
|
64
76
|
- **Use `${WAVE_SKILL_DIR}`**: Use this placeholder to reference files within the skill directory.
|
|
77
|
+
- **Inline Bash Commands**: Use `!`command`` to execute bash commands and insert their output inline.
|
package/dist/agent.d.ts
CHANGED
|
@@ -150,8 +150,8 @@ export declare class Agent {
|
|
|
150
150
|
*/
|
|
151
151
|
restoreSession(sessionId: string): Promise<void>;
|
|
152
152
|
abortAIMessage(): void;
|
|
153
|
-
/** Execute bash command */
|
|
154
|
-
|
|
153
|
+
/** Execute bash command (bang command) */
|
|
154
|
+
bang(command: string): Promise<void>;
|
|
155
155
|
clearMessages(): Promise<void>;
|
|
156
156
|
/** Unified interrupt method, interrupts both AI messages and command execution */
|
|
157
157
|
abortMessage(): void;
|
package/dist/agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/agent.js
CHANGED
|
@@ -286,9 +286,10 @@ export class Agent {
|
|
|
286
286
|
abortAIMessage() {
|
|
287
287
|
this.aiManager.abortAIMessage();
|
|
288
288
|
}
|
|
289
|
-
/** Execute bash command */
|
|
290
|
-
async
|
|
289
|
+
/** Execute bash command (bang command) */
|
|
290
|
+
async bang(command) {
|
|
291
291
|
await this.bangManager?.executeCommand(command);
|
|
292
|
+
await this.messageManager.saveSession();
|
|
292
293
|
}
|
|
293
294
|
async clearMessages() {
|
|
294
295
|
await this.slashCommandManager.executeCommand("clear");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backgroundTaskManager.d.ts","sourceRoot":"","sources":["../../src/managers/backgroundTaskManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAIzD,OAAO,EAAE,cAAc,EAAmB,MAAM,uBAAuB,CAAC;AAGxE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,MAAM,WAAW,8BAA8B;IAC7C,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;CAC7D;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,CAAC,EAAE,8BAA8B,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAqB;IAO9B,OAAO,CAAC,SAAS;IANnB,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,OAAO,CAAS;gBAGd,SAAS,EAAE,SAAS,EAC5B,OAAO,EAAE,4BAA4B;IAMvC,OAAO,CAAC,iBAAiB;IAIlB,UAAU,IAAI,MAAM;IAIpB,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAKnC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI/C,WAAW,IAAI,cAAc,EAAE;IAI/B,UAAU,CACf,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAAE;
|
|
1
|
+
{"version":3,"file":"backgroundTaskManager.d.ts","sourceRoot":"","sources":["../../src/managers/backgroundTaskManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAIzD,OAAO,EAAE,cAAc,EAAmB,MAAM,uBAAuB,CAAC;AAGxE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,MAAM,WAAW,8BAA8B;IAC7C,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;CAC7D;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,CAAC,EAAE,8BAA8B,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAqB;IAO9B,OAAO,CAAC,SAAS;IANnB,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,OAAO,CAAS;gBAGd,SAAS,EAAE,SAAS,EAC5B,OAAO,EAAE,4BAA4B;IAMvC,OAAO,CAAC,iBAAiB;IAIlB,UAAU,IAAI,MAAM;IAIpB,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAKnC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI/C,WAAW,IAAI,cAAc,EAAE;IAI/B,UAAU,CACf,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAAE;IA2InD,YAAY,CACjB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,MAAM,EACf,aAAa,GAAE,MAAW,EAC1B,aAAa,GAAE,MAAW,GACzB,MAAM;IAmGF,SAAS,CACd,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,MAAM,GACd;QACD,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI;IAoCD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IA+B7B,OAAO,IAAI,IAAI;CAUvB"}
|
|
@@ -57,7 +57,7 @@ export class BackgroundTaskManager {
|
|
|
57
57
|
logStream.end();
|
|
58
58
|
if (child.pid) {
|
|
59
59
|
process.kill(-child.pid, "SIGTERM");
|
|
60
|
-
setTimeout(() => {
|
|
60
|
+
const forceKillTimer = setTimeout(() => {
|
|
61
61
|
if (child.pid && !child.killed) {
|
|
62
62
|
try {
|
|
63
63
|
process.kill(-child.pid, "SIGKILL");
|
|
@@ -67,6 +67,7 @@ export class BackgroundTaskManager {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
}, 1000);
|
|
70
|
+
forceKillTimer.unref();
|
|
70
71
|
}
|
|
71
72
|
else {
|
|
72
73
|
child.kill("SIGTERM");
|
|
@@ -84,6 +85,11 @@ export class BackgroundTaskManager {
|
|
|
84
85
|
if (timeout && timeout > 0) {
|
|
85
86
|
timeoutHandle = setTimeout(() => {
|
|
86
87
|
if (shell.status === "running") {
|
|
88
|
+
const timeoutMsg = "\n\nCommand timed out";
|
|
89
|
+
shell.stderr += timeoutMsg;
|
|
90
|
+
if (logStream.writable) {
|
|
91
|
+
logStream.write(timeoutMsg);
|
|
92
|
+
}
|
|
87
93
|
this.stopTask(id);
|
|
88
94
|
}
|
|
89
95
|
}, timeout);
|
|
@@ -179,7 +185,7 @@ export class BackgroundTaskManager {
|
|
|
179
185
|
logStream.end();
|
|
180
186
|
if (child.pid) {
|
|
181
187
|
process.kill(-child.pid, "SIGTERM");
|
|
182
|
-
setTimeout(() => {
|
|
188
|
+
const forceKillTimer = setTimeout(() => {
|
|
183
189
|
if (child.pid && !child.killed) {
|
|
184
190
|
try {
|
|
185
191
|
process.kill(-child.pid, "SIGKILL");
|
|
@@ -189,6 +195,7 @@ export class BackgroundTaskManager {
|
|
|
189
195
|
}
|
|
190
196
|
}
|
|
191
197
|
}, 1000);
|
|
198
|
+
forceKillTimer.unref();
|
|
192
199
|
}
|
|
193
200
|
else {
|
|
194
201
|
child.kill("SIGTERM");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cronManager.d.ts","sourceRoot":"","sources":["../../src/managers/cronManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAM3C,qBAAa,WAAW;IAIV,OAAO,CAAC,SAAS;IAH7B,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,QAAQ,CAA+B;gBAE3B,SAAS,EAAE,SAAS;IAExC,OAAO,KAAK,SAAS,GAEpB;IAED,OAAO,KAAK,cAAc,GAEzB;IAEM,KAAK,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"cronManager.d.ts","sourceRoot":"","sources":["../../src/managers/cronManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAM3C,qBAAa,WAAW;IAIV,OAAO,CAAC,SAAS;IAH7B,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,QAAQ,CAA+B;gBAE3B,SAAS,EAAE,SAAS;IAExC,OAAO,KAAK,SAAS,GAEpB;IAED,OAAO,KAAK,cAAc,GAEzB;IAEM,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI;IAOZ,SAAS,CACd,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC,GAC9D,OAAO;IAiCH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI9B,QAAQ,IAAI,OAAO,EAAE;IAI5B,OAAO,CAAC,WAAW;IAuBnB,OAAO,CAAC,sBAAsB;YAYhB,SAAS;CAuDxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissionManager.d.ts","sourceRoot":"","sources":["../../src/managers/permissionManager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EACV,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACf,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"permissionManager.d.ts","sourceRoot":"","sources":["../../src/managers/permissionManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import path from "node:path";
|
|
9
9
|
import { minimatch } from "minimatch";
|
|
10
10
|
import { RESTRICTED_TOOLS } from "../types/permissions.js";
|
|
11
|
-
import { splitBashCommand, stripEnvVars, stripRedirections, hasWriteRedirections, isBashHeredocWrite, getSmartPrefix, DANGEROUS_COMMANDS, } from "../utils/bashParser.js";
|
|
11
|
+
import { splitBashCommand, stripEnvVars, stripRedirections, hasWriteRedirections, isBashHeredocWrite, getSmartPrefix, isDangerousFind, DANGEROUS_COMMANDS, } from "../utils/bashParser.js";
|
|
12
12
|
import { isPathInside } from "../utils/pathSafety.js";
|
|
13
13
|
import { BASH_TOOL_NAME, EDIT_TOOL_NAME, WRITE_TOOL_NAME, READ_TOOL_NAME, } from "../constants/tools.js";
|
|
14
14
|
const SAFE_COMMANDS = [
|
|
@@ -24,6 +24,7 @@ const SAFE_COMMANDS = [
|
|
|
24
24
|
"tail",
|
|
25
25
|
"wc",
|
|
26
26
|
"sleep",
|
|
27
|
+
"find",
|
|
27
28
|
];
|
|
28
29
|
const DEFAULT_ALLOWED_RULES = [
|
|
29
30
|
"Bash(git status*)",
|
|
@@ -52,6 +53,7 @@ const DEFAULT_ALLOWED_RULES = [
|
|
|
52
53
|
"Bash(git count-objects*)",
|
|
53
54
|
"Bash(echo*)",
|
|
54
55
|
"Bash(ls*)",
|
|
56
|
+
"Bash(find*)",
|
|
55
57
|
"Bash(which*)",
|
|
56
58
|
"Bash(type*)",
|
|
57
59
|
"Bash(hostname*)",
|
|
@@ -658,7 +660,8 @@ export class PermissionManager {
|
|
|
658
660
|
cmd === "head" ||
|
|
659
661
|
cmd === "tail" ||
|
|
660
662
|
cmd === "wc" ||
|
|
661
|
-
cmd === "sleep"
|
|
663
|
+
cmd === "sleep" ||
|
|
664
|
+
(cmd === "find" && !isDangerousFind(part))) {
|
|
662
665
|
return true;
|
|
663
666
|
}
|
|
664
667
|
if (workdir) {
|
|
@@ -682,7 +685,7 @@ export class PermissionManager {
|
|
|
682
685
|
}
|
|
683
686
|
}
|
|
684
687
|
// Check if this specific part is allowed by any rule
|
|
685
|
-
if (
|
|
688
|
+
if (isDefaultRules && (hasWrite || isDangerousFind(part))) {
|
|
686
689
|
return false;
|
|
687
690
|
}
|
|
688
691
|
// We create a temporary context with just this part of the command
|
|
@@ -747,7 +750,8 @@ export class PermissionManager {
|
|
|
747
750
|
cmd === "head" ||
|
|
748
751
|
cmd === "tail" ||
|
|
749
752
|
cmd === "wc" ||
|
|
750
|
-
cmd === "sleep"
|
|
753
|
+
cmd === "sleep" ||
|
|
754
|
+
(cmd === "find" && !isDangerousFind(part))) {
|
|
751
755
|
isSafe = true;
|
|
752
756
|
}
|
|
753
757
|
else {
|
|
@@ -775,7 +779,7 @@ export class PermissionManager {
|
|
|
775
779
|
if (commandMatch) {
|
|
776
780
|
const cmd = commandMatch[1];
|
|
777
781
|
const args = commandMatch[2]?.trim() || "";
|
|
778
|
-
if (DANGEROUS_COMMANDS.includes(cmd)) {
|
|
782
|
+
if (DANGEROUS_COMMANDS.includes(cmd) || isDangerousFind(part)) {
|
|
779
783
|
continue;
|
|
780
784
|
}
|
|
781
785
|
if (cmd === "cd") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slashCommandManager.d.ts","sourceRoot":"","sources":["../../src/managers/slashCommandManager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAQ1E,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAWlD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAKxD,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,mBAAmB;IAQ5B,OAAO,CAAC,SAAS;IAPnB,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,cAAc,CAAyC;IAC/D,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,6BAA6B,CAAgC;gBAG3D,SAAS,EAAE,SAAS,EAC5B,OAAO,EAAE,0BAA0B;IAK9B,UAAU,IAAI,IAAI;IAazB,OAAO,KAAK,cAAc,GAEzB;IAED,OAAO,KAAK,SAAS,GAEpB;IAED,OAAO,KAAK,qBAAqB,GAEhC;IAED,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,eAAe,GAE1B;IAED,OAAO,CAAC,yBAAyB;IAcjC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA4C1B;;OAEG;IACI,qBAAqB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI;IA0K3D;;OAEG;IACI,sBAAsB,CAC3B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,kBAAkB,EAAE,GAC7B,IAAI;IA0CP;;OAEG;IACI,oBAAoB,IAAI,IAAI;IAWnC;;OAEG;IACI,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAInD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACI,WAAW,IAAI,YAAY,EAAE;IAIpC;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI9D;;OAEG;IACU,cAAc,CACzB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"slashCommandManager.d.ts","sourceRoot":"","sources":["../../src/managers/slashCommandManager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAQ1E,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAWlD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAKxD,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,mBAAmB;IAQ5B,OAAO,CAAC,SAAS;IAPnB,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,cAAc,CAAyC;IAC/D,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,6BAA6B,CAAgC;gBAG3D,SAAS,EAAE,SAAS,EAC5B,OAAO,EAAE,0BAA0B;IAK9B,UAAU,IAAI,IAAI;IAazB,OAAO,KAAK,cAAc,GAEzB;IAED,OAAO,KAAK,SAAS,GAEpB;IAED,OAAO,KAAK,qBAAqB,GAEhC;IAED,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,eAAe,GAE1B;IAED,OAAO,CAAC,yBAAyB;IAcjC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA4C1B;;OAEG;IACI,qBAAqB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI;IA0K3D;;OAEG;IACI,sBAAsB,CAC3B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,kBAAkB,EAAE,GAC7B,IAAI;IA0CP;;OAEG;IACI,oBAAoB,IAAI,IAAI;IAWnC;;OAEG;IACI,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAInD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACI,WAAW,IAAI,YAAY,EAAE;IAIpC;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI9D;;OAEG;IACU,cAAc,CACzB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC;IA2BnB;;;OAGG;IACI,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG;QAClD,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf;IAeD;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI7C;;OAEG;IACI,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI1E;;OAEG;IACI,iBAAiB,IAAI,kBAAkB,EAAE;IAIhD;;OAEG;YACW,+BAA+B;IAuD7C;;OAEG;IACI,mBAAmB,IAAI,IAAI;CAQnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileWatcher.d.ts","sourceRoot":"","sources":["../../src/services/fileWatcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B;AAaD,qBAAa,kBAAmB,SAAQ,YAAY;IAClD,OAAO,CAAC,QAAQ,CAA4C;IAC5D,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC;IAahE;;;OAGG;IACG,SAAS,CACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GACxC,OAAO,CAAC,IAAI,CAAC;IA+BhB;;;OAGG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB9C;;;OAGG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;IA0BxD;;;OAGG;IACH,qBAAqB,IAAI,iBAAiB,EAAE;IAM5C;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"fileWatcher.d.ts","sourceRoot":"","sources":["../../src/services/fileWatcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B;AAaD,qBAAa,kBAAmB,SAAQ,YAAY;IAClD,OAAO,CAAC,QAAQ,CAA4C;IAC5D,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC;IAahE;;;OAGG;IACG,SAAS,CACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GACxC,OAAO,CAAC,IAAI,CAAC;IA+BhB;;;OAGG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB9C;;;OAGG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;IA0BxD;;;OAGG;IACH,qBAAqB,IAAI,iBAAiB,EAAE;IAM5C;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAahB,iBAAiB;IAqD/B,OAAO,CAAC,wBAAwB;IAoChC,OAAO,CAAC,eAAe;CAoCxB"}
|
|
@@ -111,10 +111,13 @@ export class FileWatcherService extends EventEmitter {
|
|
|
111
111
|
*/
|
|
112
112
|
async cleanup() {
|
|
113
113
|
const paths = Array.from(this.watchers.keys());
|
|
114
|
-
|
|
114
|
+
for (const path of paths) {
|
|
115
|
+
await this.unwatchFile(path);
|
|
116
|
+
}
|
|
115
117
|
if (this.globalWatcher) {
|
|
116
|
-
|
|
118
|
+
const watcher = this.globalWatcher;
|
|
117
119
|
this.globalWatcher = null;
|
|
120
|
+
await watcher.close();
|
|
118
121
|
}
|
|
119
122
|
}
|
|
120
123
|
async initializeWatcher(entry) {
|
|
@@ -131,6 +134,13 @@ export class FileWatcherService extends EventEmitter {
|
|
|
131
134
|
usePolling: entry.config.fallbackPolling,
|
|
132
135
|
interval: entry.config.pollInterval,
|
|
133
136
|
});
|
|
137
|
+
// Unref the global watcher to allow natural exit if it's the only thing left
|
|
138
|
+
// (chokidar watchers keep the process alive by default)
|
|
139
|
+
// Note: some platforms might need additional handling
|
|
140
|
+
const watcher = this.globalWatcher;
|
|
141
|
+
if (watcher.unref) {
|
|
142
|
+
watcher.unref();
|
|
143
|
+
}
|
|
134
144
|
this.setupGlobalWatcherEvents();
|
|
135
145
|
}
|
|
136
146
|
// Add path to global watcher
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/services/hook.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EAElC,MAAM,mBAAmB,CAAC;AA0E3B;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,EAC5D,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/services/hook.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EAElC,MAAM,mBAAmB,CAAC;AA0E3B;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,EAC5D,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CA6I9B;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,EAC5D,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAchC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsBtD"}
|
package/dist/services/hook.js
CHANGED
|
@@ -119,11 +119,12 @@ export async function executeCommand(command, context, options) {
|
|
|
119
119
|
});
|
|
120
120
|
}
|
|
121
121
|
// Set up timeout
|
|
122
|
+
let forceKillTimeoutHandle;
|
|
122
123
|
const timeoutHandle = setTimeout(() => {
|
|
123
124
|
timedOut = true;
|
|
124
125
|
childProcess.kill("SIGTERM");
|
|
125
126
|
// Force kill after additional delay
|
|
126
|
-
setTimeout(() => {
|
|
127
|
+
forceKillTimeoutHandle = setTimeout(() => {
|
|
127
128
|
if (!childProcess.killed) {
|
|
128
129
|
childProcess.kill("SIGKILL");
|
|
129
130
|
}
|
|
@@ -163,6 +164,8 @@ export async function executeCommand(command, context, options) {
|
|
|
163
164
|
// Handle process completion
|
|
164
165
|
childProcess.on("close", (code) => {
|
|
165
166
|
clearTimeout(timeoutHandle);
|
|
167
|
+
if (forceKillTimeoutHandle)
|
|
168
|
+
clearTimeout(forceKillTimeoutHandle);
|
|
166
169
|
const duration = Date.now() - startTime;
|
|
167
170
|
resolve({
|
|
168
171
|
success: !timedOut && (code === 0 || code === null),
|
|
@@ -176,6 +179,8 @@ export async function executeCommand(command, context, options) {
|
|
|
176
179
|
// Handle process errors
|
|
177
180
|
childProcess.on("error", (error) => {
|
|
178
181
|
clearTimeout(timeoutHandle);
|
|
182
|
+
if (forceKillTimeoutHandle)
|
|
183
|
+
clearTimeout(forceKillTimeoutHandle);
|
|
179
184
|
const duration = Date.now() - startTime;
|
|
180
185
|
resolve({
|
|
181
186
|
success: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/services/session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/services/session.ts"],"names":[],"mappings":"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"}
|
package/dist/services/session.js
CHANGED
|
@@ -22,6 +22,7 @@ import { PathEncoder } from "../utils/pathEncoder.js";
|
|
|
22
22
|
import { JsonlHandler } from "../services/jsonlHandler.js";
|
|
23
23
|
import { extractLatestTotalTokens } from "../utils/tokenCalculation.js";
|
|
24
24
|
import { logger } from "../utils/globalLogger.js";
|
|
25
|
+
import { getMessageContent } from "../utils/messageOperations.js";
|
|
25
26
|
/**
|
|
26
27
|
* Generate a new session ID using Node.js native crypto.randomUUID()
|
|
27
28
|
* @returns UUID string for session identification
|
|
@@ -655,20 +656,7 @@ export async function getFirstMessageContent(sessionId, workdir) {
|
|
|
655
656
|
}
|
|
656
657
|
try {
|
|
657
658
|
const message = JSON.parse(firstLine);
|
|
658
|
-
|
|
659
|
-
const textBlock = message.blocks.find((block) => block.type === "text");
|
|
660
|
-
if (textBlock && "content" in textBlock) {
|
|
661
|
-
return textBlock.content;
|
|
662
|
-
}
|
|
663
|
-
const commandBlock = message.blocks.find((block) => block.type === "bang");
|
|
664
|
-
if (commandBlock && "command" in commandBlock) {
|
|
665
|
-
return commandBlock.command;
|
|
666
|
-
}
|
|
667
|
-
const compressBlock = message.blocks.find((block) => block.type === "compress");
|
|
668
|
-
if (compressBlock && "content" in compressBlock) {
|
|
669
|
-
return compressBlock.content;
|
|
670
|
-
}
|
|
671
|
-
return null;
|
|
659
|
+
return getMessageContent(message) || null;
|
|
672
660
|
}
|
|
673
661
|
catch (error) {
|
|
674
662
|
logger.warn(`Failed to parse first message in session ${sessionId}:`, error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAwCtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAmbtB,CAAC"}
|
package/dist/tools/bashTool.js
CHANGED
|
@@ -28,19 +28,6 @@ function processOutput(output) {
|
|
|
28
28
|
"\n\n... (output truncated, failed to persist full output)");
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
/**
|
|
32
|
-
* Simple throttle function to limit the frequency of updates.
|
|
33
|
-
*/
|
|
34
|
-
function throttle(func, limit) {
|
|
35
|
-
let inThrottle;
|
|
36
|
-
return function () {
|
|
37
|
-
if (!inThrottle) {
|
|
38
|
-
func();
|
|
39
|
-
inThrottle = true;
|
|
40
|
-
setTimeout(() => (inThrottle = false), limit);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
31
|
/**
|
|
45
32
|
* Bash command execution tool - supports both foreground and background execution
|
|
46
33
|
*/
|
|
@@ -229,7 +216,7 @@ Use the gh command via the Bash tool for GitHub-related tasks including working
|
|
|
229
216
|
let isAborted = false;
|
|
230
217
|
let isBackgrounded = false;
|
|
231
218
|
let isFinished = false;
|
|
232
|
-
const updateRealtimeResults =
|
|
219
|
+
const updateRealtimeResults = () => {
|
|
233
220
|
if (isAborted || isBackgrounded || isFinished)
|
|
234
221
|
return;
|
|
235
222
|
const combinedOutput = outputBuffer + (errorBuffer ? "\n" + errorBuffer : "");
|
|
@@ -250,7 +237,7 @@ Use the gh command via the Bash tool for GitHub-related tasks including working
|
|
|
250
237
|
"\n\n... (output truncated)";
|
|
251
238
|
context.onResultUpdate(content);
|
|
252
239
|
}
|
|
253
|
-
}
|
|
240
|
+
};
|
|
254
241
|
const foregroundTaskId = `bash_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
255
242
|
// Register as foreground task
|
|
256
243
|
if (context.foregroundTaskManager && command) {
|
|
@@ -327,9 +314,12 @@ Use the gh command via the Bash tool for GitHub-related tasks including working
|
|
|
327
314
|
}
|
|
328
315
|
}
|
|
329
316
|
}
|
|
317
|
+
const processedOutput = processOutput(outputBuffer + (errorBuffer ? "\n" + errorBuffer : ""));
|
|
330
318
|
resolve({
|
|
331
319
|
success: false,
|
|
332
|
-
content:
|
|
320
|
+
content: processedOutput
|
|
321
|
+
? `${processedOutput}\n\n${reason}`
|
|
322
|
+
: reason,
|
|
333
323
|
error: reason,
|
|
334
324
|
});
|
|
335
325
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webFetchTool.d.ts","sourceRoot":"","sources":["../../src/tools/webFetchTool.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AA+BtE,eAAO,MAAM,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"webFetchTool.d.ts","sourceRoot":"","sources":["../../src/tools/webFetchTool.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AA+BtE,eAAO,MAAM,YAAY,EAAE,UAiK1B,CAAC"}
|
|
@@ -42,6 +42,10 @@ export declare const TOOL_RULES: Record<string, ToolRule>;
|
|
|
42
42
|
* Registry of dangerous subcommands for specific tools.
|
|
43
43
|
*/
|
|
44
44
|
export declare const DANGEROUS_SUBCOMMANDS: Record<string, string[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Checks if a find command is dangerous (e.g., contains -exec, -delete, etc.).
|
|
47
|
+
*/
|
|
48
|
+
export declare function isDangerousFind(command: string): boolean;
|
|
45
49
|
/**
|
|
46
50
|
* Extracts a "smart prefix" from a bash command based on common developer tools.
|
|
47
51
|
* Returns null if the command is blacklisted or cannot be safely prefix-matched.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bashParser.d.ts","sourceRoot":"","sources":["../../src/utils/bashParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAoH1D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA2CpD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAuHzD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAkG7D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsCnD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,UAyB9B,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAoD/C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAQ1D,CAAC;AA2DF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2J7D"}
|
|
1
|
+
{"version":3,"file":"bashParser.d.ts","sourceRoot":"","sources":["../../src/utils/bashParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAoH1D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA2CpD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAuHzD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAkG7D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsCnD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,UAyB9B,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAoD/C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAQ1D,CAAC;AA2DF;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAmBxD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2J7D"}
|
package/dist/utils/bashParser.js
CHANGED
|
@@ -544,6 +544,29 @@ function shouldStopAtArg(arg) {
|
|
|
544
544
|
return true;
|
|
545
545
|
return false;
|
|
546
546
|
}
|
|
547
|
+
/**
|
|
548
|
+
* Checks if a find command is dangerous (e.g., contains -exec, -delete, etc.).
|
|
549
|
+
*/
|
|
550
|
+
export function isDangerousFind(command) {
|
|
551
|
+
const stripped = stripRedirections(stripEnvVars(command));
|
|
552
|
+
const tokens = stripped.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g) || [];
|
|
553
|
+
if (tokens.length === 0 || tokens[0] !== "find")
|
|
554
|
+
return false;
|
|
555
|
+
const dangerousFlags = [
|
|
556
|
+
"-exec",
|
|
557
|
+
"-execdir",
|
|
558
|
+
"-ok",
|
|
559
|
+
"-okdir",
|
|
560
|
+
"-delete",
|
|
561
|
+
"-fprint",
|
|
562
|
+
"-fprint0",
|
|
563
|
+
"-fprintf",
|
|
564
|
+
];
|
|
565
|
+
return tokens.some((token) => {
|
|
566
|
+
const unquoted = token.replace(/^(['"])(.*)\1$/, "$2");
|
|
567
|
+
return dangerousFlags.includes(unquoted);
|
|
568
|
+
});
|
|
569
|
+
}
|
|
547
570
|
/**
|
|
548
571
|
* Extracts a "smart prefix" from a bash command based on common developer tools.
|
|
549
572
|
* Returns null if the command is blacklisted or cannot be safely prefix-matched.
|
|
@@ -121,8 +121,18 @@ export declare function countToolBlocks(messages: Message[]): number;
|
|
|
121
121
|
* Used for hook error handling when the user prompt needs to be erased
|
|
122
122
|
*/
|
|
123
123
|
export declare const removeLastUserMessage: (messages: Message[]) => Message[];
|
|
124
|
+
/**
|
|
125
|
+
* Efficiently clone a message for UI freezing.
|
|
126
|
+
* Clones the message object and its blocks array, but reuses string references.
|
|
127
|
+
*/
|
|
128
|
+
export declare function cloneMessage(message: Message): Message;
|
|
124
129
|
/**
|
|
125
130
|
* Helper to format tool and token summary
|
|
126
131
|
*/
|
|
127
132
|
export declare function formatToolTokenSummary(toolCount: number, tokens: number): string;
|
|
133
|
+
/**
|
|
134
|
+
* Extracts displayable text from a Message object, handling various block types.
|
|
135
|
+
* Returns the first available content block.
|
|
136
|
+
*/
|
|
137
|
+
export declare function getMessageContent(message: Message): string;
|
|
128
138
|
//# sourceMappingURL=messageOperations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messageOperations.d.ts","sourceRoot":"","sources":["../../src/utils/messageOperations.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"messageOperations.d.ts","sourceRoot":"","sources":["../../src/utils/messageOperations.ts"],"names":[],"mappings":"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"}
|
|
@@ -435,6 +435,33 @@ export const removeLastUserMessage = (messages) => {
|
|
|
435
435
|
}
|
|
436
436
|
return newMessages;
|
|
437
437
|
};
|
|
438
|
+
/**
|
|
439
|
+
* Efficiently clone a message for UI freezing.
|
|
440
|
+
* Clones the message object and its blocks array, but reuses string references.
|
|
441
|
+
*/
|
|
442
|
+
export function cloneMessage(message) {
|
|
443
|
+
return {
|
|
444
|
+
...message,
|
|
445
|
+
blocks: message.blocks.map((block) => {
|
|
446
|
+
const clonedBlock = { ...block };
|
|
447
|
+
// Deep clone arrays/objects within blocks if they exist
|
|
448
|
+
if (clonedBlock.type === "tool" && clonedBlock.images) {
|
|
449
|
+
clonedBlock.images = clonedBlock.images.map((img) => ({ ...img }));
|
|
450
|
+
}
|
|
451
|
+
else if (clonedBlock.type === "image" && clonedBlock.imageUrls) {
|
|
452
|
+
clonedBlock.imageUrls = [...clonedBlock.imageUrls];
|
|
453
|
+
}
|
|
454
|
+
else if (clonedBlock.type === "file_history" && clonedBlock.snapshots) {
|
|
455
|
+
clonedBlock.snapshots = clonedBlock.snapshots.map((s) => ({ ...s }));
|
|
456
|
+
}
|
|
457
|
+
return clonedBlock;
|
|
458
|
+
}),
|
|
459
|
+
// Clone additionalFields if it exists
|
|
460
|
+
...(message.additionalFields
|
|
461
|
+
? { additionalFields: { ...message.additionalFields } }
|
|
462
|
+
: {}),
|
|
463
|
+
};
|
|
464
|
+
}
|
|
438
465
|
/**
|
|
439
466
|
* Helper to format tool and token summary
|
|
440
467
|
*/
|
|
@@ -449,3 +476,27 @@ export function formatToolTokenSummary(toolCount, tokens) {
|
|
|
449
476
|
summary += ")";
|
|
450
477
|
return summary;
|
|
451
478
|
}
|
|
479
|
+
/**
|
|
480
|
+
* Extracts displayable text from a Message object, handling various block types.
|
|
481
|
+
* Returns the first available content block.
|
|
482
|
+
*/
|
|
483
|
+
export function getMessageContent(message) {
|
|
484
|
+
// Find first available content block
|
|
485
|
+
const textBlock = message.blocks.find((block) => block.type === "text");
|
|
486
|
+
if (textBlock && "content" in textBlock) {
|
|
487
|
+
return textBlock.content;
|
|
488
|
+
}
|
|
489
|
+
const slashBlock = message.blocks.find((block) => block.type === "slash");
|
|
490
|
+
if (slashBlock && "command" in slashBlock) {
|
|
491
|
+
return `/${slashBlock.command}${slashBlock.args ? ` ${slashBlock.args}` : ""}`;
|
|
492
|
+
}
|
|
493
|
+
const bangBlock = message.blocks.find((block) => block.type === "bang");
|
|
494
|
+
if (bangBlock && "command" in bangBlock) {
|
|
495
|
+
return `!${bangBlock.command}`;
|
|
496
|
+
}
|
|
497
|
+
const compressBlock = message.blocks.find((block) => block.type === "compress");
|
|
498
|
+
if (compressBlock && "content" in compressBlock) {
|
|
499
|
+
return compressBlock.content;
|
|
500
|
+
}
|
|
501
|
+
return "";
|
|
502
|
+
}
|
|
@@ -23,4 +23,8 @@ export declare const stripAnsiColors: (text: string) => string;
|
|
|
23
23
|
* @returns Formatted line number prefix
|
|
24
24
|
*/
|
|
25
25
|
export declare function formatLineNumberPrefix(lineNumber: number): string;
|
|
26
|
+
/**
|
|
27
|
+
* Efficiently get the last N lines of a string without splitting the whole string.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getLastLines(text: string, count: number): string;
|
|
26
30
|
//# sourceMappingURL=stringUtils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stringUtils.d.ts","sourceRoot":"","sources":["../../src/utils/stringUtils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAgC/D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,GACpB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwBxB;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,MAK9C,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEjE"}
|
|
1
|
+
{"version":3,"file":"stringUtils.d.ts","sourceRoot":"","sources":["../../src/utils/stringUtils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAgC/D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,GACpB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwBxB;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,KAAG,MAK9C,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAehE"}
|
|
@@ -77,3 +77,24 @@ export const stripAnsiColors = (text) => {
|
|
|
77
77
|
export function formatLineNumberPrefix(lineNumber) {
|
|
78
78
|
return `${lineNumber.toString().padStart(6)}\t`;
|
|
79
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Efficiently get the last N lines of a string without splitting the whole string.
|
|
82
|
+
*/
|
|
83
|
+
export function getLastLines(text, count) {
|
|
84
|
+
if (!text || count <= 0)
|
|
85
|
+
return "";
|
|
86
|
+
let pos = text.length;
|
|
87
|
+
let found = 0;
|
|
88
|
+
while (pos > 0 && found < count) {
|
|
89
|
+
const nextNewline = text.lastIndexOf("\n", pos - 1);
|
|
90
|
+
if (nextNewline === -1) {
|
|
91
|
+
pos = 0;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
pos = nextNewline;
|
|
96
|
+
found++;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return text.substring(pos === 0 && found < count ? 0 : pos + 1);
|
|
100
|
+
}
|
package/package.json
CHANGED
package/src/agent.ts
CHANGED
|
@@ -425,9 +425,10 @@ export class Agent {
|
|
|
425
425
|
this.aiManager.abortAIMessage();
|
|
426
426
|
}
|
|
427
427
|
|
|
428
|
-
/** Execute bash command */
|
|
429
|
-
public async
|
|
428
|
+
/** Execute bash command (bang command) */
|
|
429
|
+
public async bang(command: string): Promise<void> {
|
|
430
430
|
await this.bangManager?.executeCommand(command);
|
|
431
|
+
await this.messageManager.saveSession();
|
|
431
432
|
}
|
|
432
433
|
|
|
433
434
|
public async clearMessages(): Promise<void> {
|
|
@@ -86,7 +86,7 @@ export class BackgroundTaskManager {
|
|
|
86
86
|
logStream.end();
|
|
87
87
|
if (child.pid) {
|
|
88
88
|
process.kill(-child.pid, "SIGTERM");
|
|
89
|
-
setTimeout(() => {
|
|
89
|
+
const forceKillTimer = setTimeout(() => {
|
|
90
90
|
if (child.pid && !child.killed) {
|
|
91
91
|
try {
|
|
92
92
|
process.kill(-child.pid, "SIGKILL");
|
|
@@ -95,6 +95,7 @@ export class BackgroundTaskManager {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
}, 1000);
|
|
98
|
+
forceKillTimer.unref();
|
|
98
99
|
} else {
|
|
99
100
|
child.kill("SIGTERM");
|
|
100
101
|
}
|
|
@@ -112,6 +113,11 @@ export class BackgroundTaskManager {
|
|
|
112
113
|
if (timeout && timeout > 0) {
|
|
113
114
|
timeoutHandle = setTimeout(() => {
|
|
114
115
|
if (shell.status === "running") {
|
|
116
|
+
const timeoutMsg = "\n\nCommand timed out";
|
|
117
|
+
shell.stderr += timeoutMsg;
|
|
118
|
+
if (logStream.writable) {
|
|
119
|
+
logStream.write(timeoutMsg);
|
|
120
|
+
}
|
|
115
121
|
this.stopTask(id);
|
|
116
122
|
}
|
|
117
123
|
}, timeout);
|
|
@@ -223,7 +229,7 @@ export class BackgroundTaskManager {
|
|
|
223
229
|
logStream.end();
|
|
224
230
|
if (child.pid) {
|
|
225
231
|
process.kill(-child.pid, "SIGTERM");
|
|
226
|
-
setTimeout(() => {
|
|
232
|
+
const forceKillTimer = setTimeout(() => {
|
|
227
233
|
if (child.pid && !child.killed) {
|
|
228
234
|
try {
|
|
229
235
|
process.kill(-child.pid, "SIGKILL");
|
|
@@ -232,6 +238,7 @@ export class BackgroundTaskManager {
|
|
|
232
238
|
}
|
|
233
239
|
}
|
|
234
240
|
}, 1000);
|
|
241
|
+
forceKillTimer.unref();
|
|
235
242
|
} else {
|
|
236
243
|
child.kill("SIGTERM");
|
|
237
244
|
}
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
hasWriteRedirections,
|
|
24
24
|
isBashHeredocWrite,
|
|
25
25
|
getSmartPrefix,
|
|
26
|
+
isDangerousFind,
|
|
26
27
|
DANGEROUS_COMMANDS,
|
|
27
28
|
} from "../utils/bashParser.js";
|
|
28
29
|
import { isPathInside } from "../utils/pathSafety.js";
|
|
@@ -48,6 +49,7 @@ const SAFE_COMMANDS = [
|
|
|
48
49
|
"tail",
|
|
49
50
|
"wc",
|
|
50
51
|
"sleep",
|
|
52
|
+
"find",
|
|
51
53
|
];
|
|
52
54
|
|
|
53
55
|
const DEFAULT_ALLOWED_RULES = [
|
|
@@ -77,6 +79,7 @@ const DEFAULT_ALLOWED_RULES = [
|
|
|
77
79
|
"Bash(git count-objects*)",
|
|
78
80
|
"Bash(echo*)",
|
|
79
81
|
"Bash(ls*)",
|
|
82
|
+
"Bash(find*)",
|
|
80
83
|
"Bash(which*)",
|
|
81
84
|
"Bash(type*)",
|
|
82
85
|
"Bash(hostname*)",
|
|
@@ -851,7 +854,8 @@ export class PermissionManager {
|
|
|
851
854
|
cmd === "head" ||
|
|
852
855
|
cmd === "tail" ||
|
|
853
856
|
cmd === "wc" ||
|
|
854
|
-
cmd === "sleep"
|
|
857
|
+
cmd === "sleep" ||
|
|
858
|
+
(cmd === "find" && !isDangerousFind(part))
|
|
855
859
|
) {
|
|
856
860
|
return true;
|
|
857
861
|
}
|
|
@@ -887,7 +891,7 @@ export class PermissionManager {
|
|
|
887
891
|
}
|
|
888
892
|
|
|
889
893
|
// Check if this specific part is allowed by any rule
|
|
890
|
-
if (
|
|
894
|
+
if (isDefaultRules && (hasWrite || isDangerousFind(part))) {
|
|
891
895
|
return false;
|
|
892
896
|
}
|
|
893
897
|
|
|
@@ -965,7 +969,8 @@ export class PermissionManager {
|
|
|
965
969
|
cmd === "head" ||
|
|
966
970
|
cmd === "tail" ||
|
|
967
971
|
cmd === "wc" ||
|
|
968
|
-
cmd === "sleep"
|
|
972
|
+
cmd === "sleep" ||
|
|
973
|
+
(cmd === "find" && !isDangerousFind(part))
|
|
969
974
|
) {
|
|
970
975
|
isSafe = true;
|
|
971
976
|
} else {
|
|
@@ -998,7 +1003,7 @@ export class PermissionManager {
|
|
|
998
1003
|
const cmd = commandMatch[1];
|
|
999
1004
|
const args = commandMatch[2]?.trim() || "";
|
|
1000
1005
|
|
|
1001
|
-
if (DANGEROUS_COMMANDS.includes(cmd)) {
|
|
1006
|
+
if (DANGEROUS_COMMANDS.includes(cmd) || isDangerousFind(part)) {
|
|
1002
1007
|
continue;
|
|
1003
1008
|
}
|
|
1004
1009
|
|
|
@@ -167,11 +167,14 @@ export class FileWatcherService extends EventEmitter {
|
|
|
167
167
|
*/
|
|
168
168
|
async cleanup(): Promise<void> {
|
|
169
169
|
const paths = Array.from(this.watchers.keys());
|
|
170
|
-
|
|
170
|
+
for (const path of paths) {
|
|
171
|
+
await this.unwatchFile(path);
|
|
172
|
+
}
|
|
171
173
|
|
|
172
174
|
if (this.globalWatcher) {
|
|
173
|
-
|
|
175
|
+
const watcher = this.globalWatcher;
|
|
174
176
|
this.globalWatcher = null;
|
|
177
|
+
await watcher.close();
|
|
175
178
|
}
|
|
176
179
|
}
|
|
177
180
|
|
|
@@ -190,6 +193,14 @@ export class FileWatcherService extends EventEmitter {
|
|
|
190
193
|
interval: entry.config.pollInterval,
|
|
191
194
|
});
|
|
192
195
|
|
|
196
|
+
// Unref the global watcher to allow natural exit if it's the only thing left
|
|
197
|
+
// (chokidar watchers keep the process alive by default)
|
|
198
|
+
// Note: some platforms might need additional handling
|
|
199
|
+
const watcher = this.globalWatcher as unknown as { unref?: () => void };
|
|
200
|
+
if (watcher.unref) {
|
|
201
|
+
watcher.unref();
|
|
202
|
+
}
|
|
203
|
+
|
|
193
204
|
this.setupGlobalWatcherEvents();
|
|
194
205
|
}
|
|
195
206
|
|
package/src/services/hook.ts
CHANGED
|
@@ -158,12 +158,13 @@ export async function executeCommand(
|
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
// Set up timeout
|
|
161
|
+
let forceKillTimeoutHandle: NodeJS.Timeout | undefined;
|
|
161
162
|
const timeoutHandle = setTimeout(() => {
|
|
162
163
|
timedOut = true;
|
|
163
164
|
childProcess.kill("SIGTERM");
|
|
164
165
|
|
|
165
166
|
// Force kill after additional delay
|
|
166
|
-
setTimeout(() => {
|
|
167
|
+
forceKillTimeoutHandle = setTimeout(() => {
|
|
167
168
|
if (!childProcess.killed) {
|
|
168
169
|
childProcess.kill("SIGKILL");
|
|
169
170
|
}
|
|
@@ -205,6 +206,7 @@ export async function executeCommand(
|
|
|
205
206
|
// Handle process completion
|
|
206
207
|
childProcess.on("close", (code: number | null) => {
|
|
207
208
|
clearTimeout(timeoutHandle);
|
|
209
|
+
if (forceKillTimeoutHandle) clearTimeout(forceKillTimeoutHandle);
|
|
208
210
|
const duration = Date.now() - startTime;
|
|
209
211
|
|
|
210
212
|
resolve({
|
|
@@ -220,6 +222,7 @@ export async function executeCommand(
|
|
|
220
222
|
// Handle process errors
|
|
221
223
|
childProcess.on("error", (error: Error) => {
|
|
222
224
|
clearTimeout(timeoutHandle);
|
|
225
|
+
if (forceKillTimeoutHandle) clearTimeout(forceKillTimeoutHandle);
|
|
223
226
|
const duration = Date.now() - startTime;
|
|
224
227
|
|
|
225
228
|
resolve({
|
package/src/services/session.ts
CHANGED
|
@@ -25,6 +25,7 @@ import { PathEncoder } from "../utils/pathEncoder.js";
|
|
|
25
25
|
import { JsonlHandler } from "../services/jsonlHandler.js";
|
|
26
26
|
import { extractLatestTotalTokens } from "../utils/tokenCalculation.js";
|
|
27
27
|
import { logger } from "../utils/globalLogger.js";
|
|
28
|
+
import { getMessageContent } from "../utils/messageOperations.js";
|
|
28
29
|
|
|
29
30
|
export interface SessionData {
|
|
30
31
|
id: string;
|
|
@@ -842,27 +843,7 @@ export async function getFirstMessageContent(
|
|
|
842
843
|
try {
|
|
843
844
|
const message = JSON.parse(firstLine) as Message;
|
|
844
845
|
|
|
845
|
-
|
|
846
|
-
const textBlock = message.blocks.find((block) => block.type === "text");
|
|
847
|
-
if (textBlock && "content" in textBlock) {
|
|
848
|
-
return textBlock.content;
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
const commandBlock = message.blocks.find(
|
|
852
|
-
(block) => block.type === "bang",
|
|
853
|
-
);
|
|
854
|
-
if (commandBlock && "command" in commandBlock) {
|
|
855
|
-
return commandBlock.command;
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
const compressBlock = message.blocks.find(
|
|
859
|
-
(block) => block.type === "compress",
|
|
860
|
-
);
|
|
861
|
-
if (compressBlock && "content" in compressBlock) {
|
|
862
|
-
return compressBlock.content;
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
return null;
|
|
846
|
+
return getMessageContent(message) || null;
|
|
866
847
|
} catch (error) {
|
|
867
848
|
logger.warn(
|
|
868
849
|
`Failed to parse first message in session ${sessionId}:`,
|
package/src/tools/bashTool.ts
CHANGED
|
@@ -44,20 +44,6 @@ function processOutput(output: string): string {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
/**
|
|
48
|
-
* Simple throttle function to limit the frequency of updates.
|
|
49
|
-
*/
|
|
50
|
-
function throttle(func: () => void, limit: number) {
|
|
51
|
-
let inThrottle: boolean;
|
|
52
|
-
return function () {
|
|
53
|
-
if (!inThrottle) {
|
|
54
|
-
func();
|
|
55
|
-
inThrottle = true;
|
|
56
|
-
setTimeout(() => (inThrottle = false), limit);
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
47
|
/**
|
|
62
48
|
* Bash command execution tool - supports both foreground and background execution
|
|
63
49
|
*/
|
|
@@ -268,7 +254,7 @@ Use the gh command via the Bash tool for GitHub-related tasks including working
|
|
|
268
254
|
let isBackgrounded = false;
|
|
269
255
|
let isFinished = false;
|
|
270
256
|
|
|
271
|
-
const updateRealtimeResults =
|
|
257
|
+
const updateRealtimeResults = () => {
|
|
272
258
|
if (isAborted || isBackgrounded || isFinished) return;
|
|
273
259
|
|
|
274
260
|
const combinedOutput =
|
|
@@ -294,7 +280,7 @@ Use the gh command via the Bash tool for GitHub-related tasks including working
|
|
|
294
280
|
"\n\n... (output truncated)";
|
|
295
281
|
context.onResultUpdate(content);
|
|
296
282
|
}
|
|
297
|
-
}
|
|
283
|
+
};
|
|
298
284
|
|
|
299
285
|
const foregroundTaskId = `bash_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
300
286
|
|
|
@@ -383,11 +369,14 @@ Use the gh command via the Bash tool for GitHub-related tasks including working
|
|
|
383
369
|
}
|
|
384
370
|
}
|
|
385
371
|
|
|
372
|
+
const processedOutput = processOutput(
|
|
373
|
+
outputBuffer + (errorBuffer ? "\n" + errorBuffer : ""),
|
|
374
|
+
);
|
|
386
375
|
resolve({
|
|
387
376
|
success: false,
|
|
388
|
-
content:
|
|
389
|
-
|
|
390
|
-
|
|
377
|
+
content: processedOutput
|
|
378
|
+
? `${processedOutput}\n\n${reason}`
|
|
379
|
+
: reason,
|
|
391
380
|
error: reason,
|
|
392
381
|
});
|
|
393
382
|
}
|
|
@@ -29,7 +29,7 @@ setInterval(() => {
|
|
|
29
29
|
cache.delete(url);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
}, CACHE_TTL);
|
|
32
|
+
}, CACHE_TTL).unref();
|
|
33
33
|
|
|
34
34
|
export const webFetchTool: ToolPlugin = {
|
|
35
35
|
name: WEB_FETCH_TOOL_NAME,
|
|
@@ -158,7 +158,8 @@ Usage notes:
|
|
|
158
158
|
return {
|
|
159
159
|
success: false,
|
|
160
160
|
content: markdown,
|
|
161
|
-
error:
|
|
161
|
+
error:
|
|
162
|
+
"AI Manager or AI Service not available for processing content",
|
|
162
163
|
};
|
|
163
164
|
}
|
|
164
165
|
|
package/src/utils/bashParser.ts
CHANGED
|
@@ -610,6 +610,30 @@ function shouldStopAtArg(arg: string): boolean {
|
|
|
610
610
|
return false;
|
|
611
611
|
}
|
|
612
612
|
|
|
613
|
+
/**
|
|
614
|
+
* Checks if a find command is dangerous (e.g., contains -exec, -delete, etc.).
|
|
615
|
+
*/
|
|
616
|
+
export function isDangerousFind(command: string): boolean {
|
|
617
|
+
const stripped = stripRedirections(stripEnvVars(command));
|
|
618
|
+
const tokens = stripped.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g) || [];
|
|
619
|
+
if (tokens.length === 0 || tokens[0] !== "find") return false;
|
|
620
|
+
|
|
621
|
+
const dangerousFlags = [
|
|
622
|
+
"-exec",
|
|
623
|
+
"-execdir",
|
|
624
|
+
"-ok",
|
|
625
|
+
"-okdir",
|
|
626
|
+
"-delete",
|
|
627
|
+
"-fprint",
|
|
628
|
+
"-fprint0",
|
|
629
|
+
"-fprintf",
|
|
630
|
+
];
|
|
631
|
+
return tokens.some((token) => {
|
|
632
|
+
const unquoted = token.replace(/^(['"])(.*)\1$/, "$2");
|
|
633
|
+
return dangerousFlags.includes(unquoted);
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
|
|
613
637
|
/**
|
|
614
638
|
* Extracts a "smart prefix" from a bash command based on common developer tools.
|
|
615
639
|
* Returns null if the command is blacklisted or cannot be safely prefix-matched.
|
|
@@ -614,6 +614,32 @@ export const removeLastUserMessage = (messages: Message[]): Message[] => {
|
|
|
614
614
|
return newMessages;
|
|
615
615
|
};
|
|
616
616
|
|
|
617
|
+
/**
|
|
618
|
+
* Efficiently clone a message for UI freezing.
|
|
619
|
+
* Clones the message object and its blocks array, but reuses string references.
|
|
620
|
+
*/
|
|
621
|
+
export function cloneMessage(message: Message): Message {
|
|
622
|
+
return {
|
|
623
|
+
...message,
|
|
624
|
+
blocks: message.blocks.map((block) => {
|
|
625
|
+
const clonedBlock = { ...block };
|
|
626
|
+
// Deep clone arrays/objects within blocks if they exist
|
|
627
|
+
if (clonedBlock.type === "tool" && clonedBlock.images) {
|
|
628
|
+
clonedBlock.images = clonedBlock.images.map((img) => ({ ...img }));
|
|
629
|
+
} else if (clonedBlock.type === "image" && clonedBlock.imageUrls) {
|
|
630
|
+
clonedBlock.imageUrls = [...clonedBlock.imageUrls];
|
|
631
|
+
} else if (clonedBlock.type === "file_history" && clonedBlock.snapshots) {
|
|
632
|
+
clonedBlock.snapshots = clonedBlock.snapshots.map((s) => ({ ...s }));
|
|
633
|
+
}
|
|
634
|
+
return clonedBlock;
|
|
635
|
+
}) as Message["blocks"],
|
|
636
|
+
// Clone additionalFields if it exists
|
|
637
|
+
...(message.additionalFields
|
|
638
|
+
? { additionalFields: { ...message.additionalFields } }
|
|
639
|
+
: {}),
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
|
|
617
643
|
/**
|
|
618
644
|
* Helper to format tool and token summary
|
|
619
645
|
*/
|
|
@@ -631,3 +657,34 @@ export function formatToolTokenSummary(
|
|
|
631
657
|
summary += ")";
|
|
632
658
|
return summary;
|
|
633
659
|
}
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* Extracts displayable text from a Message object, handling various block types.
|
|
663
|
+
* Returns the first available content block.
|
|
664
|
+
*/
|
|
665
|
+
export function getMessageContent(message: Message): string {
|
|
666
|
+
// Find first available content block
|
|
667
|
+
const textBlock = message.blocks.find((block) => block.type === "text");
|
|
668
|
+
if (textBlock && "content" in textBlock) {
|
|
669
|
+
return textBlock.content;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
const slashBlock = message.blocks.find((block) => block.type === "slash");
|
|
673
|
+
if (slashBlock && "command" in slashBlock) {
|
|
674
|
+
return `/${slashBlock.command}${slashBlock.args ? ` ${slashBlock.args}` : ""}`;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
const bangBlock = message.blocks.find((block) => block.type === "bang");
|
|
678
|
+
if (bangBlock && "command" in bangBlock) {
|
|
679
|
+
return `!${bangBlock.command}`;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
const compressBlock = message.blocks.find(
|
|
683
|
+
(block) => block.type === "compress",
|
|
684
|
+
);
|
|
685
|
+
if (compressBlock && "content" in compressBlock) {
|
|
686
|
+
return compressBlock.content;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
return "";
|
|
690
|
+
}
|
package/src/utils/stringUtils.ts
CHANGED
|
@@ -91,3 +91,23 @@ export const stripAnsiColors = (text: string): string => {
|
|
|
91
91
|
export function formatLineNumberPrefix(lineNumber: number): string {
|
|
92
92
|
return `${lineNumber.toString().padStart(6)}\t`;
|
|
93
93
|
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Efficiently get the last N lines of a string without splitting the whole string.
|
|
97
|
+
*/
|
|
98
|
+
export function getLastLines(text: string, count: number): string {
|
|
99
|
+
if (!text || count <= 0) return "";
|
|
100
|
+
let pos = text.length;
|
|
101
|
+
let found = 0;
|
|
102
|
+
while (pos > 0 && found < count) {
|
|
103
|
+
const nextNewline = text.lastIndexOf("\n", pos - 1);
|
|
104
|
+
if (nextNewline === -1) {
|
|
105
|
+
pos = 0;
|
|
106
|
+
break;
|
|
107
|
+
} else {
|
|
108
|
+
pos = nextNewline;
|
|
109
|
+
found++;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return text.substring(pos === 0 && found < count ? 0 : pos + 1);
|
|
113
|
+
}
|