Skip to content

Commit 10ac0d5

Browse files
committed
Merge branch 'main' into local-pty
2 parents 6c48b73 + dea7368 commit 10ac0d5

File tree

9 files changed

+30
-28
lines changed

9 files changed

+30
-28
lines changed

.github/actions/setup-mux/action.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ runs:
1414
run: echo "version=$(bun --version)" >> $GITHUB_OUTPUT
1515

1616
- name: Cache node_modules
17+
id: cache-node-modules
1718
uses: actions/cache@v4
1819
with:
1920
path: node_modules
@@ -22,6 +23,7 @@ runs:
2223
${{ runner.os }}-${{ runner.arch }}-bun-${{ steps.bun-version.outputs.version }}-node-modules-
2324
2425
- name: Cache bun install cache
26+
id: cache-bun-install
2527
uses: actions/cache@v4
2628
with:
2729
path: ~/.bun/install/cache
@@ -30,6 +32,7 @@ runs:
3032
${{ runner.os }}-bun-cache-
3133
3234
- name: Install dependencies
35+
if: steps.cache-node-modules.outputs.cache-hit != 'true'
3336
shell: bash
3437
run: bun install --frozen-lockfile
3538

src/components/WorkspaceListItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ const WorkspaceListItemInner: React.FC<WorkspaceListItemProps> = ({
164164
title="Double-click to rename"
165165
>
166166
{canInterrupt ? (
167-
<Shimmer className="h-4 w-full truncate" colorClass="var(--color-foreground)">
167+
<Shimmer className="w-full truncate" colorClass="var(--color-foreground)">
168168
{displayName}
169169
</Shimmer>
170170
) : (

src/components/ai-elements/shimmer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const ShimmerComponent = ({
2929
<MotionComponent
3030
animate={{ backgroundPosition: "0% center" }}
3131
className={cn(
32-
"relative inline-block bg-[length:250%_100%,auto] bg-clip-text text-transparent",
32+
"relative bg-[length:250%_100%,auto] bg-clip-text text-transparent",
3333
"[--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--color-background),#0000_calc(50%+var(--spread)))] [background-repeat:no-repeat,padding-box]",
3434
className
3535
)}

src/services/tools/file_edit_insert.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,12 @@ describe("file_edit_insert tool", () => {
9696
}
9797
});
9898

99-
it("creates new file when create flag is provided", async () => {
99+
it("creates a new file without requiring create flag or guards", async () => {
100100
const newFile = path.join(testDir, "new.txt");
101101
const tool = createTestTool(testDir);
102102
const args: FileEditInsertToolArgs = {
103103
file_path: path.relative(testDir, newFile),
104104
content: "Hello world!\n",
105-
create: true,
106105
};
107106

108107
const result = (await tool.execute!(args, mockToolCallOptions)) as FileEditInsertToolResult;

src/services/tools/file_edit_insert.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export const createFileEditInsertTool: ToolFactory = (config: ToolConfiguration)
4848
description: TOOL_DEFINITIONS.file_edit_insert.description,
4949
inputSchema: TOOL_DEFINITIONS.file_edit_insert.schema,
5050
execute: async (
51-
{ file_path, content, before, after, create }: FileEditInsertToolArgs,
51+
{ file_path, content, before, after }: FileEditInsertToolArgs,
5252
{ abortSignal }
5353
): Promise<FileEditInsertToolResult> => {
5454
try {
@@ -71,14 +71,6 @@ export const createFileEditInsertTool: ToolFactory = (config: ToolConfiguration)
7171
const exists = await fileExists(config.runtime, resolvedPath, abortSignal);
7272

7373
if (!exists) {
74-
if (!create) {
75-
return {
76-
success: false,
77-
error: `File not found: ${file_path}. Set create: true to create it.`,
78-
note: `${EDIT_FAILED_NOTE_PREFIX} File does not exist. Set create: true to create it, or check the file path.`,
79-
};
80-
}
81-
8274
try {
8375
await writeFileString(config.runtime, resolvedPath, content, abortSignal);
8476
} catch (err) {
@@ -139,7 +131,7 @@ function insertContent(
139131
}
140132

141133
if (before === undefined && after === undefined) {
142-
return guardFailure("Provide either a before or after guard to anchor the insertion point.");
134+
return guardFailure("Provide either a before or after guard when editing existing files.");
143135
}
144136

145137
return insertWithGuards(originalContent, contentToInsert, { before, after });

src/telemetry/utils.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@ import { VERSION } from "../version";
99
* Get base telemetry properties included with all events
1010
*/
1111
export function getBaseTelemetryProperties(): BaseTelemetryProperties {
12+
const gitDescribe =
13+
typeof VERSION === "object" &&
14+
VERSION !== null &&
15+
typeof (VERSION as Record<string, unknown>).git_describe === "string"
16+
? (VERSION as { git_describe: string }).git_describe
17+
: "unknown";
18+
1219
return {
13-
version: String(VERSION.git_describe),
20+
version: gitDescribe,
1421
platform: window.api?.platform || "unknown",
1522
electronVersion: window.api?.versions?.electron || "unknown",
1623
};

src/types/tools.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ export interface FileEditErrorResult {
7474
export interface FileEditInsertToolArgs {
7575
file_path: string;
7676
content: string;
77-
/** When true, create the file if it doesn't exist */
78-
create?: boolean;
7977
/** Optional substring that must appear immediately before the insertion point */
8078
before?: string;
8179
/** Optional substring that must appear immediately after the insertion point */

src/utils/tools/toolDefinitions.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,12 @@ export const TOOL_DEFINITIONS = {
116116
description:
117117
"Insert content into a file using substring guards. " +
118118
"Provide exactly one of before or after to anchor the operation when editing an existing file. " +
119-
"Set create: true to write a brand new file without guards. " +
119+
"When the file does not exist, it is created automatically without guards. " +
120120
`Optional before/after substrings must uniquely match surrounding content. ${TOOL_EDIT_WARNING}`,
121121
schema: z
122122
.object({
123123
file_path: FILE_EDIT_FILE_PATH,
124124
content: z.string().describe("The content to insert"),
125-
create: z.boolean().optional().describe("If true, create the file if it does not exist"),
126125
before: z
127126
.string()
128127
.min(1)
@@ -134,14 +133,6 @@ export const TOOL_DEFINITIONS = {
134133
.optional()
135134
.describe("Optional substring that must appear immediately after the insertion point"),
136135
})
137-
.refine(
138-
(data) => data.create === true || data.before !== undefined || data.after !== undefined,
139-
{
140-
message:
141-
"Provide before or after when editing existing files, or set create: true to write a new file.",
142-
path: ["before"],
143-
}
144-
)
145136
.refine((data) => !(data.before !== undefined && data.after !== undefined), {
146137
message: "Provide only one of before or after (not both).",
147138
path: ["before"],

tests/ipcMain/runtimeExecuteBash.test.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
type SSHServerConfig,
3434
} from "../runtime/ssh-fixture";
3535
import type { RuntimeConfig } from "../../src/types/runtime";
36+
import type { WorkspaceChatMessage } from "../../src/types/ipc";
3637
import type { ToolPolicy } from "../../src/utils/tools/toolPolicy";
3738

3839
// Tool policy: Only allow bash tool
@@ -41,6 +42,16 @@ const BASH_ONLY: ToolPolicy = [
4142
{ regex_match: "file_.*", action: "disable" },
4243
];
4344

45+
function collectToolOutputs(events: WorkspaceChatMessage[], toolName: string): string {
46+
return events
47+
.filter((event: any) => event.type === "tool-call-end" && event.toolName === toolName)
48+
.map((event: any) => {
49+
const output = event.result?.output;
50+
return typeof output === "string" ? output : "";
51+
})
52+
.join("\n");
53+
}
54+
4455
// Skip all tests if TEST_INTEGRATION is not set
4556
const describeIntegration = shouldRunIntegrationTests() ? describe : describe.skip;
4657

@@ -264,7 +275,8 @@ describeIntegration("Runtime Bash Execution", () => {
264275

265276
// Verify command completed successfully (not timeout)
266277
expect(responseText).toContain("test");
267-
expect(responseText).toContain("data");
278+
const bashOutput = collectToolOutputs(events, "bash");
279+
expect(bashOutput).toContain('"test": "data"');
268280

269281
// Verify command completed quickly (not hanging until timeout)
270282
// With tokenizer preloading, both local and SSH complete in ~8s total

0 commit comments

Comments
 (0)