wave-code 0.10.0 → 0.10.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/dist/acp/agent.d.ts +15 -1
- package/dist/acp/agent.d.ts.map +1 -1
- package/dist/acp/agent.js +477 -40
- package/dist/components/ChatInterface.js +1 -1
- package/dist/components/DiffDisplay.d.ts.map +1 -1
- package/dist/components/DiffDisplay.js +23 -2
- package/dist/contexts/useChat.d.ts.map +1 -1
- package/dist/contexts/useChat.js +15 -4
- package/dist/utils/highlightUtils.d.ts.map +1 -1
- package/dist/utils/highlightUtils.js +8 -0
- package/dist/utils/toolParameterTransforms.d.ts +1 -5
- package/dist/utils/toolParameterTransforms.d.ts.map +1 -1
- package/dist/utils/toolParameterTransforms.js +0 -14
- package/dist/utils/worktree.js +2 -2
- package/package.json +3 -3
- package/src/acp/agent.ts +627 -68
- package/src/components/ChatInterface.tsx +1 -1
- package/src/components/DiffDisplay.tsx +27 -2
- package/src/contexts/useChat.tsx +20 -4
- package/src/utils/highlightUtils.ts +8 -0
- package/src/utils/toolParameterTransforms.ts +1 -23
- package/src/utils/worktree.ts +2 -2
|
@@ -72,7 +72,7 @@ export const ChatInterface: React.FC = () => {
|
|
|
72
72
|
|
|
73
73
|
const terminalHeight = stdout?.rows || 24;
|
|
74
74
|
const totalHeight = detailsHeight + selectorHeight + dynamicBlocksHeight;
|
|
75
|
-
if (totalHeight > terminalHeight) {
|
|
75
|
+
if (totalHeight > terminalHeight - 3) {
|
|
76
76
|
setIsConfirmationTooTall(true);
|
|
77
77
|
}
|
|
78
78
|
}, [
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import React, { useMemo } from "react";
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
WRITE_TOOL_NAME,
|
|
5
|
+
EDIT_TOOL_NAME,
|
|
6
|
+
type WriteToolParameters,
|
|
7
|
+
} from "wave-agent-sdk";
|
|
4
8
|
import { transformToolBlockToChanges } from "../utils/toolParameterTransforms.js";
|
|
5
9
|
import { diffLines, diffWords } from "diff";
|
|
10
|
+
import path from "path";
|
|
11
|
+
import { Markdown } from "./Markdown.js";
|
|
6
12
|
|
|
7
13
|
interface DiffDisplayProps {
|
|
8
14
|
toolName?: string;
|
|
@@ -97,6 +103,23 @@ export const DiffDisplay: React.FC<DiffDisplayProps> = ({
|
|
|
97
103
|
}
|
|
98
104
|
};
|
|
99
105
|
|
|
106
|
+
// Render highlighted code for Write tool
|
|
107
|
+
const renderWriteContent = () => {
|
|
108
|
+
if (!parameters) return null;
|
|
109
|
+
try {
|
|
110
|
+
const parsed = JSON.parse(parameters) as WriteToolParameters;
|
|
111
|
+
const content = parsed.content || "";
|
|
112
|
+
const filePath = parsed.file_path || "";
|
|
113
|
+
const ext = path.extname(filePath).slice(1);
|
|
114
|
+
|
|
115
|
+
const markdown = `\`\`\`${ext}\n${content}\n\`\`\``;
|
|
116
|
+
return <Markdown>{markdown}</Markdown>;
|
|
117
|
+
} catch (error) {
|
|
118
|
+
console.warn("Error rendering write content:", error);
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
100
123
|
// Render expanded diff display
|
|
101
124
|
const renderExpandedDiff = () => {
|
|
102
125
|
try {
|
|
@@ -352,7 +375,9 @@ export const DiffDisplay: React.FC<DiffDisplayProps> = ({
|
|
|
352
375
|
return (
|
|
353
376
|
<Box flexDirection="column">
|
|
354
377
|
<Box paddingLeft={2} borderLeft borderColor="cyan" flexDirection="column">
|
|
355
|
-
{
|
|
378
|
+
{toolName === WRITE_TOOL_NAME
|
|
379
|
+
? renderWriteContent()
|
|
380
|
+
: renderExpandedDiff()}
|
|
356
381
|
</Box>
|
|
357
382
|
</Box>
|
|
358
383
|
);
|
package/src/contexts/useChat.tsx
CHANGED
|
@@ -223,6 +223,20 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
223
223
|
const [wasLastDetailsTooTall, setWasLastDetailsTooTall] = useState(0);
|
|
224
224
|
|
|
225
225
|
const agentRef = useRef<Agent | null>(null);
|
|
226
|
+
const taskUpdateTimerRef = useRef<NodeJS.Timeout | null>(null);
|
|
227
|
+
|
|
228
|
+
const debouncedSetTasks = useCallback(
|
|
229
|
+
(newTasks: Task[]) => {
|
|
230
|
+
if (taskUpdateTimerRef.current) {
|
|
231
|
+
clearTimeout(taskUpdateTimerRef.current);
|
|
232
|
+
}
|
|
233
|
+
taskUpdateTimerRef.current = setTimeout(() => {
|
|
234
|
+
setTasks([...newTasks]);
|
|
235
|
+
taskUpdateTimerRef.current = null;
|
|
236
|
+
}, 100);
|
|
237
|
+
},
|
|
238
|
+
[setTasks],
|
|
239
|
+
);
|
|
226
240
|
|
|
227
241
|
// Permission confirmation methods with queue support
|
|
228
242
|
const showConfirmation = useCallback(
|
|
@@ -274,7 +288,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
274
288
|
setBackgroundTasks([...tasks]);
|
|
275
289
|
},
|
|
276
290
|
onTasksChange: (tasks) => {
|
|
277
|
-
|
|
291
|
+
debouncedSetTasks(tasks);
|
|
278
292
|
},
|
|
279
293
|
onSubagentMessagesChange: (subagentId: string, messages: Message[]) => {
|
|
280
294
|
logger.debug("onSubagentMessagesChange", subagentId, messages.length);
|
|
@@ -295,9 +309,6 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
295
309
|
onPermissionModeChange: (mode) => {
|
|
296
310
|
setPermissionModeState(mode);
|
|
297
311
|
},
|
|
298
|
-
onSlashCommandsChange: (commands) => {
|
|
299
|
-
setSlashCommands([...commands]);
|
|
300
|
-
},
|
|
301
312
|
};
|
|
302
313
|
|
|
303
314
|
try {
|
|
@@ -374,11 +385,16 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
374
385
|
workdir,
|
|
375
386
|
worktreeSession,
|
|
376
387
|
model,
|
|
388
|
+
debouncedSetTasks,
|
|
377
389
|
]);
|
|
378
390
|
|
|
379
391
|
// Cleanup on unmount
|
|
380
392
|
useEffect(() => {
|
|
381
393
|
return () => {
|
|
394
|
+
if (taskUpdateTimerRef.current) {
|
|
395
|
+
clearTimeout(taskUpdateTimerRef.current);
|
|
396
|
+
}
|
|
397
|
+
|
|
382
398
|
if (agentRef.current) {
|
|
383
399
|
try {
|
|
384
400
|
// Display usage summary before cleanup
|
|
@@ -49,6 +49,14 @@ function nodeToAnsi(node: Node): string {
|
|
|
49
49
|
|
|
50
50
|
for (const className of classes) {
|
|
51
51
|
if (theme[className]) {
|
|
52
|
+
// If content has newlines, split it and apply style to each line
|
|
53
|
+
// to ensure ANSI codes are correctly applied when splitting the final string by lines.
|
|
54
|
+
if (content.includes("\n")) {
|
|
55
|
+
return content
|
|
56
|
+
.split("\n")
|
|
57
|
+
.map((line) => theme[className](line))
|
|
58
|
+
.join("\n");
|
|
59
|
+
}
|
|
52
60
|
return theme[className](content);
|
|
53
61
|
}
|
|
54
62
|
}
|
|
@@ -3,11 +3,7 @@
|
|
|
3
3
|
* Forces type judgment based on tool name using type assertions
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
type Change,
|
|
8
|
-
type WriteToolParameters,
|
|
9
|
-
type EditToolParameters,
|
|
10
|
-
} from "wave-agent-sdk";
|
|
6
|
+
import { type Change, type EditToolParameters } from "wave-agent-sdk";
|
|
11
7
|
import { logger } from "./logger.js";
|
|
12
8
|
|
|
13
9
|
/**
|
|
@@ -26,20 +22,6 @@ function parseToolParameters(parameters: string): unknown {
|
|
|
26
22
|
}
|
|
27
23
|
}
|
|
28
24
|
|
|
29
|
-
/**
|
|
30
|
-
* Transform Write tool parameters to changes
|
|
31
|
-
*/
|
|
32
|
-
export function transformWriteParameters(
|
|
33
|
-
parameters: WriteToolParameters,
|
|
34
|
-
): Change[] {
|
|
35
|
-
return [
|
|
36
|
-
{
|
|
37
|
-
oldContent: "", // No previous content for write operations
|
|
38
|
-
newContent: parameters.content,
|
|
39
|
-
},
|
|
40
|
-
];
|
|
41
|
-
}
|
|
42
|
-
|
|
43
25
|
/**
|
|
44
26
|
* Transform Edit tool parameters to changes
|
|
45
27
|
*/
|
|
@@ -72,10 +54,6 @@ export function transformToolBlockToChanges(
|
|
|
72
54
|
|
|
73
55
|
let changes: Change[] = [];
|
|
74
56
|
switch (toolName) {
|
|
75
|
-
case "Write":
|
|
76
|
-
changes = transformWriteParameters(parsedParams as WriteToolParameters);
|
|
77
|
-
break;
|
|
78
|
-
|
|
79
57
|
case "Edit":
|
|
80
58
|
changes = transformEditParameters(parsedParams as EditToolParameters);
|
|
81
59
|
break;
|
package/src/utils/worktree.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
|
-
import {
|
|
4
|
+
import { getDefaultRemoteBranch, getGitMainRepoRoot } from "wave-agent-sdk";
|
|
5
5
|
|
|
6
6
|
export interface WorktreeSession {
|
|
7
7
|
name: string;
|
|
@@ -22,7 +22,7 @@ export const WORKTREE_DIR = ".wave/worktrees";
|
|
|
22
22
|
* @returns Worktree session details
|
|
23
23
|
*/
|
|
24
24
|
export function createWorktree(name: string, cwd: string): WorktreeSession {
|
|
25
|
-
const repoRoot =
|
|
25
|
+
const repoRoot = getGitMainRepoRoot(cwd);
|
|
26
26
|
const worktreePath = path.join(repoRoot, WORKTREE_DIR, name);
|
|
27
27
|
const branchName = `worktree-${name}`;
|
|
28
28
|
const baseBranch = getDefaultRemoteBranch(cwd);
|