feat: add Tauri desktop app support and terminal management

This commit is contained in:
Mohamed Boudra
2026-01-20 10:09:35 +07:00
parent 12f617dd10
commit d9c487dd54
125 changed files with 8906 additions and 1049 deletions
@@ -42,8 +42,9 @@ describe("parseToolCallDisplay", () => {
const input = { command: "pwd", description: "Print working directory" };
const result = { type: "command", command: "pwd", output: "/some/path" };
const display: ToolCallDisplay = parseToolCallDisplay(input, result);
const display: ToolCallDisplay = parseToolCallDisplay("Bash", input, result);
expect(display.type).toBe("shell");
expect(display.toolName).toBe("Shell");
if (display.type === "shell") {
expect(display.command).toBe("pwd");
expect(display.output).toBe("/some/path");
@@ -55,8 +56,9 @@ describe("parseToolCallDisplay", () => {
const input = { command: "pwd", description: "Print working directory" };
const result = undefined;
const display: ToolCallDisplay = parseToolCallDisplay(input, result);
const display: ToolCallDisplay = parseToolCallDisplay("Bash", input, result);
expect(display.type).toBe("shell");
expect(display.toolName).toBe("Shell");
if (display.type === "shell") {
expect(display.command).toBe("pwd");
expect(display.output).toBe("");
@@ -67,19 +69,44 @@ describe("parseToolCallDisplay", () => {
const input = { command: ["git", "status"] };
const result = { type: "command", output: "On branch main" };
const display: ToolCallDisplay = parseToolCallDisplay(input, result);
const display: ToolCallDisplay = parseToolCallDisplay("shell", input, result);
expect(display.type).toBe("shell");
expect(display.toolName).toBe("Shell");
if (display.type === "shell") {
expect(display.command).toBe("git status");
expect(display.output).toBe("On branch main");
}
});
test("normalizes tool names - shell to Shell", () => {
const input = { command: "pwd" };
const display = parseToolCallDisplay("shell", input, undefined);
expect(display.toolName).toBe("Shell");
});
test("normalizes tool names - Bash to Shell", () => {
const input = { command: "pwd" };
const display = parseToolCallDisplay("Bash", input, undefined);
expect(display.toolName).toBe("Shell");
});
test("normalizes tool names - read_file to Read", () => {
const input = { file_path: "/some/file.txt" };
const display = parseToolCallDisplay("read_file", input, undefined);
expect(display.toolName).toBe("Read");
});
test("preserves unknown tool names", () => {
const input = { some_arg: "value" };
const display = parseToolCallDisplay("MyCustomTool", input, undefined);
expect(display.toolName).toBe("MyCustomTool");
});
test("parses non-command tool call into generic type", () => {
const input = { file_path: "/some/file.txt" };
const result = { content: "file contents here", lineCount: 42 };
const display: ToolCallDisplay = parseToolCallDisplay(input, result);
const display: ToolCallDisplay = parseToolCallDisplay("SomeTool", input, result);
expect(display.type).toBe("generic");
if (display.type === "generic") {
expect(display.input).toContainEqual({ key: "file_path", value: "/some/file.txt" });
@@ -92,12 +119,12 @@ describe("parseToolCallDisplay", () => {
const input = { file_path: "/some/file.txt", content: "new content" };
const result = { type: "file_write", filePath: "/some/file.txt" };
const display: ToolCallDisplay = parseToolCallDisplay(input, result);
const display: ToolCallDisplay = parseToolCallDisplay("Write", input, result);
expect(display.type).toBe("generic");
});
test("handles undefined input and result gracefully", () => {
const display: ToolCallDisplay = parseToolCallDisplay(undefined, undefined);
const display: ToolCallDisplay = parseToolCallDisplay("unknown", undefined, undefined);
expect(display.type).toBe("generic");
if (display.type === "generic") {
expect(display.input).toEqual([]);
@@ -116,7 +143,7 @@ describe("parseToolCallDisplay", () => {
filePath: "/some/file.txt",
};
const display: ToolCallDisplay = parseToolCallDisplay(input, result);
const display: ToolCallDisplay = parseToolCallDisplay("Edit", input, result);
expect(display.type).toBe("edit");
if (display.type === "edit") {
expect(display.filePath).toBe("/some/file.txt");
@@ -133,7 +160,7 @@ describe("parseToolCallDisplay", () => {
};
const result = undefined;
const display: ToolCallDisplay = parseToolCallDisplay(input, result);
const display: ToolCallDisplay = parseToolCallDisplay("Edit", input, result);
expect(display.type).toBe("edit");
if (display.type === "edit") {
expect(display.filePath).toBe("/some/file.txt");
@@ -149,7 +176,7 @@ describe("parseToolCallDisplay", () => {
new_string: "new content",
};
const display: ToolCallDisplay = parseToolCallDisplay(input, undefined);
const display: ToolCallDisplay = parseToolCallDisplay("Edit", input, undefined);
expect(display.type).toBe("edit");
if (display.type === "edit") {
expect(display.filePath).toBe("/some/file.txt");
@@ -158,3 +185,111 @@ describe("parseToolCallDisplay", () => {
}
});
});
describe("parseToolCallDisplay - apply_patch (Codex)", () => {
test("parses apply_patch into edit type with unified diff", () => {
const input = {
files: [
{
path: "/Users/moboudra/dev/blankpage/editor/.tasks/578561c8.md",
kind: "update",
},
],
};
const result = {
files: [
{
path: "/Users/moboudra/dev/blankpage/editor/.tasks/578561c8.md",
patch: "@@ -15,3 +15,2 @@\n-This task defines the **design philosophy**\n+This task defines the **updated philosophy**",
kind: "update",
},
],
message: "Success. Updated the following files:\nM .tasks/578561c8.md",
success: true,
};
const display = parseToolCallDisplay("apply_patch", input, result);
expect(display.type).toBe("edit");
expect(display.toolName).toBe("Edit");
if (display.type === "edit") {
expect(display.filePath).toBe("/Users/moboudra/dev/blankpage/editor/.tasks/578561c8.md");
expect(display.unifiedDiff).toBe("@@ -15,3 +15,2 @@\n-This task defines the **design philosophy**\n+This task defines the **updated philosophy**");
expect(display.oldString).toBe("");
expect(display.newString).toBe("");
}
});
test("parses pending apply_patch (no result yet)", () => {
const input = {
files: [
{
path: "/some/file.txt",
kind: "create",
},
],
};
const display = parseToolCallDisplay("apply_patch", input, undefined);
expect(display.type).toBe("edit");
expect(display.toolName).toBe("Edit");
if (display.type === "edit") {
expect(display.filePath).toBe("/some/file.txt");
expect(display.unifiedDiff).toBeUndefined();
}
});
test("handles apply_patch with multiple files (uses first file)", () => {
const input = {
files: [
{ path: "/first/file.txt", kind: "update" },
{ path: "/second/file.txt", kind: "create" },
],
};
const result = {
files: [
{ path: "/first/file.txt", patch: "@@ -1 +1 @@\n-old\n+new", kind: "update" },
{ path: "/second/file.txt", patch: "@@ -0,0 +1 @@\n+content", kind: "create" },
],
success: true,
};
const display = parseToolCallDisplay("apply_patch", input, result);
expect(display.type).toBe("edit");
if (display.type === "edit") {
expect(display.filePath).toBe("/first/file.txt");
expect(display.unifiedDiff).toBe("@@ -1 +1 @@\n-old\n+new");
}
});
});
describe("parseToolCallDisplay - read_file (Codex)", () => {
test("parses Codex read_file into read type", () => {
const input = {
path: "/Users/moboudra/dev/blankpage/editor/.tasks/578561c8.md",
};
const result = {
type: "read_file",
path: "/Users/moboudra/dev/blankpage/editor/.tasks/578561c8.md",
content: "260 - Source: `**bold**|`\n261 - Action: `Shift+ArrowLeft`",
};
const display = parseToolCallDisplay("read_file", input, result);
expect(display.type).toBe("read");
expect(display.toolName).toBe("Read");
if (display.type === "read") {
expect(display.filePath).toBe("/Users/moboudra/dev/blankpage/editor/.tasks/578561c8.md");
expect(display.content).toBe("260 - Source: `**bold**|`\n261 - Action: `Shift+ArrowLeft`");
}
});
test("Codex read_file falls through to generic when result is missing", () => {
const input = {
path: "/some/file.txt",
};
const display = parseToolCallDisplay("read_file", input, undefined);
// Without result, it can't match the schema so falls through to generic
expect(display.type).toBe("generic");
expect(display.toolName).toBe("Read");
});
});