wave-code 0.12.0 → 0.12.1
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/README.md +9 -51
- package/dist/acp/agent.js +1 -1
- package/dist/components/DiffDisplay.d.ts.map +1 -1
- package/dist/components/DiffDisplay.js +2 -23
- package/dist/components/MessageList.d.ts.map +1 -1
- package/dist/components/MessageList.js +8 -3
- package/dist/components/StatusCommand.d.ts.map +1 -1
- package/dist/components/StatusCommand.js +1 -1
- package/dist/components/ToolDisplay.js +1 -1
- package/dist/contexts/useChat.d.ts +0 -2
- package/dist/contexts/useChat.d.ts.map +1 -1
- package/dist/contexts/useChat.js +1 -33
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/utils/highlightUtils.d.ts.map +1 -1
- package/dist/utils/highlightUtils.js +0 -8
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +10 -5
- package/dist/utils/toolParameterTransforms.d.ts +5 -1
- package/dist/utils/toolParameterTransforms.d.ts.map +1 -1
- package/dist/utils/toolParameterTransforms.js +14 -0
- package/dist/utils/worktree.d.ts +0 -1
- package/dist/utils/worktree.d.ts.map +1 -1
- package/dist/utils/worktree.js +2 -2
- package/package.json +3 -3
- package/src/acp/agent.ts +1 -1
- package/src/components/DiffDisplay.tsx +2 -27
- package/src/components/MessageList.tsx +14 -4
- package/src/components/StatusCommand.tsx +7 -0
- package/src/components/ToolDisplay.tsx +1 -1
- package/src/contexts/useChat.tsx +1 -49
- package/src/index.ts +13 -0
- package/src/utils/highlightUtils.ts +0 -8
- package/src/utils/logger.ts +9 -7
- package/src/utils/toolParameterTransforms.ts +23 -1
- package/src/utils/worktree.ts +7 -3
package/README.md
CHANGED
|
@@ -31,38 +31,26 @@ export WAVE_API_KEY="your_token_here"
|
|
|
31
31
|
|
|
32
32
|
# AI Gateway API URL (required)
|
|
33
33
|
export WAVE_BASE_URL="https://your-api-gateway-url.com"
|
|
34
|
+
|
|
35
|
+
# AI model (required)
|
|
36
|
+
export WAVE_MODEL="MiniMax-M2.7"
|
|
37
|
+
|
|
38
|
+
# Fast AI model (required)
|
|
39
|
+
export WAVE_FAST_MODEL="MiniMax-M2.7-highspeed"
|
|
34
40
|
```
|
|
35
41
|
|
|
36
42
|
### Optional Environment Variables
|
|
37
43
|
|
|
38
44
|
```bash
|
|
39
|
-
# Specify AI model (optional, defaults to gemini-3-flash)
|
|
40
|
-
export WAVE_MODEL="gemini-3-flash"
|
|
41
|
-
|
|
42
|
-
# Specify fast AI model (optional, defaults to gemini-2.5-flash)
|
|
43
|
-
export WAVE_FAST_MODEL="gemini-2.5-flash"
|
|
44
|
-
|
|
45
45
|
# Token limit (optional, defaults to 96000)
|
|
46
46
|
export WAVE_MAX_INPUT_TOKENS="96000"
|
|
47
|
-
|
|
48
47
|
```
|
|
49
48
|
|
|
50
49
|
## Usage
|
|
51
50
|
|
|
52
|
-
### Full Command
|
|
53
|
-
|
|
54
51
|
```bash
|
|
55
52
|
# Start the CLI
|
|
56
|
-
wave-code
|
|
57
|
-
|
|
58
|
-
# Continue from last session
|
|
59
|
-
wave-code --continue
|
|
60
|
-
|
|
61
|
-
# Restore specific session
|
|
62
|
-
wave-code --restore session_id
|
|
63
|
-
|
|
64
|
-
# List available sessions
|
|
65
|
-
wave-code --list-sessions
|
|
53
|
+
wave-code -h
|
|
66
54
|
```
|
|
67
55
|
|
|
68
56
|
### Short Command (wave)
|
|
@@ -70,42 +58,12 @@ wave-code --list-sessions
|
|
|
70
58
|
For convenience, you can also use the shorter `wave` command:
|
|
71
59
|
|
|
72
60
|
```bash
|
|
73
|
-
# Start the CLI
|
|
74
|
-
wave
|
|
75
|
-
|
|
76
|
-
# Continue from last session
|
|
77
|
-
wave --continue
|
|
78
|
-
|
|
79
|
-
# Restore specific session
|
|
80
|
-
wave --restore session_id
|
|
81
|
-
|
|
82
|
-
# List available sessions
|
|
83
|
-
wave --list-sessions
|
|
84
|
-
|
|
85
|
-
# Show help
|
|
86
|
-
wave --help
|
|
61
|
+
# Start the CLI
|
|
62
|
+
wave -h
|
|
87
63
|
```
|
|
88
64
|
|
|
89
65
|
The `wave` command is an alias for `wave-code` and supports all the same options and functionality.
|
|
90
66
|
|
|
91
|
-
## Development
|
|
92
|
-
|
|
93
|
-
This package depends on `wave-agent-sdk` for core functionality including AI services, tools, and utilities.
|
|
94
|
-
|
|
95
|
-
```bash
|
|
96
|
-
# Install dependencies
|
|
97
|
-
pnpm install
|
|
98
|
-
|
|
99
|
-
# Start development
|
|
100
|
-
pnpm dev
|
|
101
|
-
|
|
102
|
-
# Build
|
|
103
|
-
pnpm build
|
|
104
|
-
|
|
105
|
-
# Test
|
|
106
|
-
pnpm test
|
|
107
|
-
```
|
|
108
|
-
|
|
109
67
|
## License
|
|
110
68
|
|
|
111
69
|
MIT
|
package/dist/acp/agent.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DiffDisplay.d.ts","sourceRoot":"","sources":["../../src/components/DiffDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"DiffDisplay.d.ts","sourceRoot":"","sources":["../../src/components/DiffDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAMvC,UAAU,gBAAgB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA0VlD,CAAC"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo } from "react";
|
|
3
3
|
import { Box, Text } from "ink";
|
|
4
|
-
import { WRITE_TOOL_NAME, EDIT_TOOL_NAME
|
|
4
|
+
import { WRITE_TOOL_NAME, EDIT_TOOL_NAME } from "wave-agent-sdk";
|
|
5
5
|
import { transformToolBlockToChanges } from "../utils/toolParameterTransforms.js";
|
|
6
6
|
import { diffLines, diffWords } from "diff";
|
|
7
|
-
import path from "path";
|
|
8
|
-
import { Markdown } from "./Markdown.js";
|
|
9
7
|
export const DiffDisplay = ({ toolName, parameters, startLineNumber, }) => {
|
|
10
8
|
const showDiff = toolName && [WRITE_TOOL_NAME, EDIT_TOOL_NAME].includes(toolName);
|
|
11
9
|
// Diff detection and transformation using typed parameters
|
|
@@ -55,23 +53,6 @@ export const DiffDisplay = ({ toolName, parameters, startLineNumber, }) => {
|
|
|
55
53
|
};
|
|
56
54
|
}
|
|
57
55
|
};
|
|
58
|
-
// Render highlighted code for Write tool
|
|
59
|
-
const renderWriteContent = () => {
|
|
60
|
-
if (!parameters)
|
|
61
|
-
return null;
|
|
62
|
-
try {
|
|
63
|
-
const parsed = JSON.parse(parameters);
|
|
64
|
-
const content = parsed.content || "";
|
|
65
|
-
const filePath = parsed.file_path || "";
|
|
66
|
-
const ext = path.extname(filePath).slice(1);
|
|
67
|
-
const markdown = `\`\`\`${ext}\n${content}\n\`\`\``;
|
|
68
|
-
return _jsx(Markdown, { children: markdown });
|
|
69
|
-
}
|
|
70
|
-
catch (error) {
|
|
71
|
-
console.warn("Error rendering write content:", error);
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
56
|
// Render expanded diff display
|
|
76
57
|
const renderExpandedDiff = () => {
|
|
77
58
|
try {
|
|
@@ -216,7 +197,5 @@ export const DiffDisplay = ({ toolName, parameters, startLineNumber, }) => {
|
|
|
216
197
|
if (!showDiff) {
|
|
217
198
|
return null;
|
|
218
199
|
}
|
|
219
|
-
return (_jsx(Box, { flexDirection: "column", children: _jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "cyan", flexDirection: "column", children:
|
|
220
|
-
? renderWriteContent()
|
|
221
|
-
: renderExpandedDiff() }) }));
|
|
200
|
+
return (_jsx(Box, { flexDirection: "column", children: _jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "cyan", flexDirection: "column", children: renderExpandedDiff() }) }));
|
|
222
201
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAGvD,OAAO,KAAK,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAGvD,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,gBAAgB,CAAC;AAG5D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6BAA6B,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AAED,eAAO,MAAM,WAAW,sHAQnB,gBAAgB,6CA4HpB,CAAC"}
|
|
@@ -9,6 +9,13 @@ export const MessageList = React.memo(({ messages, isExpanded = false, forceStat
|
|
|
9
9
|
const maxMessages = 10;
|
|
10
10
|
// Filter out meta messages
|
|
11
11
|
const visibleMessages = messages.filter((m) => !m.isMeta);
|
|
12
|
+
const isRunning = (b) => (b.type === "tool" && b.stage === "running") ||
|
|
13
|
+
(b.type === "bang" && b.isRunning) ||
|
|
14
|
+
(b.type === "slash" && b.stage === "running");
|
|
15
|
+
const messagesWithRunningBlocks = new Set(visibleMessages
|
|
16
|
+
.map((m, i) => ({ m, i }))
|
|
17
|
+
.filter(({ m }) => m.blocks.some(isRunning))
|
|
18
|
+
.map(({ i }) => i));
|
|
12
19
|
// Flatten messages into blocks with metadata
|
|
13
20
|
const allBlocks = visibleMessages.flatMap((message, messageIndex) => {
|
|
14
21
|
return message.blocks.map((block, blockIndex) => ({
|
|
@@ -23,9 +30,7 @@ export const MessageList = React.memo(({ messages, isExpanded = false, forceStat
|
|
|
23
30
|
const blocksWithStatus = allBlocks.map((item) => {
|
|
24
31
|
const { block } = item;
|
|
25
32
|
const isDynamic = !forceStatic &&
|
|
26
|
-
((
|
|
27
|
-
(block.type === "bang" && block.isRunning) ||
|
|
28
|
-
(block.type === "slash" && block.stage === "running"));
|
|
33
|
+
(messagesWithRunningBlocks.has(item.messageIndex) || isRunning(block));
|
|
29
34
|
return { ...item, isDynamic };
|
|
30
35
|
});
|
|
31
36
|
const staticBlocks = blocksWithStatus.filter((b) => !b.isDynamic);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatusCommand.d.ts","sourceRoot":"","sources":["../../src/components/StatusCommand.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"StatusCommand.d.ts","sourceRoot":"","sources":["../../src/components/StatusCommand.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAsFtD,CAAC"}
|
|
@@ -24,5 +24,5 @@ export const StatusCommand = ({ onCancel }) => {
|
|
|
24
24
|
catch {
|
|
25
25
|
// Fallback if package.json cannot be read
|
|
26
26
|
}
|
|
27
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", borderLeft: false, borderRight: false, paddingX: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "cyan", bold: true, underline: true, children: "Agent Status" }) }), _jsxs(Box, { children: [_jsx(Box, { width: 20, children: _jsx(Text, { color: "yellow", children: "Version:" }) }), _jsx(Text, { color: "white", children: version })] }), _jsxs(Box, { children: [_jsx(Box, { width: 20, children: _jsx(Text, { color: "yellow", children: "Session ID:" }) }), _jsx(Text, { color: "white", children: sessionId })] }), _jsxs(Box, { children: [_jsx(Box, { width: 20, children: _jsx(Text, { color: "yellow", children: "cwd:" }) }), _jsx(Text, { color: "white", wrap: "wrap", children: workingDirectory })] }), _jsxs(Box, { children: [_jsx(Box, { width: 20, children: _jsx(Text, { color: "yellow", children: "Wave base URL:" }) }), _jsx(Text, { color: "white", children: gatewayConfig.baseURL })] }), _jsxs(Box, { children: [_jsx(Box, { width: 20, children: _jsx(Text, { color: "yellow", children: "Model:" }) }), _jsx(Text, { color: "white", children: modelConfig.model })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Esc to cancel" }) })] }));
|
|
27
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", borderLeft: false, borderRight: false, paddingX: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "cyan", bold: true, underline: true, children: "Agent Status" }) }), _jsxs(Box, { children: [_jsx(Box, { width: 20, children: _jsx(Text, { color: "yellow", children: "Version:" }) }), _jsx(Text, { color: "white", children: version })] }), _jsxs(Box, { children: [_jsx(Box, { width: 20, children: _jsx(Text, { color: "yellow", children: "Session ID:" }) }), _jsx(Text, { color: "white", children: sessionId })] }), _jsxs(Box, { children: [_jsx(Box, { width: 20, children: _jsx(Text, { color: "yellow", children: "cwd:" }) }), _jsx(Text, { color: "white", wrap: "wrap", children: workingDirectory })] }), _jsxs(Box, { children: [_jsx(Box, { width: 20, children: _jsx(Text, { color: "yellow", children: "Wave base URL:" }) }), _jsx(Text, { color: "white", children: gatewayConfig.baseURL })] }), _jsxs(Box, { children: [_jsx(Box, { width: 20, children: _jsx(Text, { color: "yellow", children: "Model:" }) }), _jsx(Text, { color: "white", children: modelConfig.model })] }), _jsxs(Box, { children: [_jsx(Box, { width: 20, children: _jsx(Text, { color: "yellow", children: "Fast model:" }) }), _jsx(Text, { color: "white", children: modelConfig.fastModel })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Esc to cancel" }) })] }));
|
|
28
28
|
};
|
|
@@ -40,5 +40,5 @@ export const ToolDisplay = ({ block, isExpanded = false, }) => {
|
|
|
40
40
|
return null;
|
|
41
41
|
};
|
|
42
42
|
const shortResult = getShortResult();
|
|
43
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsxs(Box, { flexShrink: 0, children: [_jsx(Text, { color: getStatusColor(), children: "\u25CF " }), _jsx(Text, { color: "white", children: toolName })] }), !isExpanded && compactParams && (_jsxs(Text, { color: "gray", children: [" ", compactParams] })), hasImages() && _jsxs(Text, { color: "blue", children: [" ", getImageIndicator()] })] }), !isExpanded && shortResult && !error && (_jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: shortResult.split("\n").map((line, index) => (_jsx(Text, { color: "gray", children: line }, index))) })), isExpanded && parameters && (_jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Parameters:" }), _jsx(Text, { color: "gray", children: parameters })] })), isExpanded && result && (_jsx(Box, { flexDirection: "column", children: _jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "green", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Result:" }), _jsx(Text, { color: "white", children: result })] }) })), error && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", typeof error === "string" ? error : String(error)] }) })), !isExpanded && stage === "end" && success && (_jsx(DiffDisplay, { toolName: name, parameters: parameters, startLineNumber: block.startLineNumber }))] }));
|
|
43
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsxs(Box, { flexShrink: 0, children: [_jsx(Text, { color: getStatusColor(), children: "\u25CF " }), _jsx(Text, { color: "white", children: toolName })] }), !isExpanded && compactParams && (_jsxs(Text, { color: "gray", children: [" ", compactParams] })), hasImages() && _jsxs(Text, { color: "blue", children: [" ", getImageIndicator()] })] }), !isExpanded && shortResult && !error && (_jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: shortResult.split("\n").map((line, index) => (_jsx(Text, { color: "gray", wrap: "truncate-end", children: line }, index))) })), isExpanded && parameters && (_jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "gray", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Parameters:" }), _jsx(Text, { color: "gray", children: parameters })] })), isExpanded && result && (_jsx(Box, { flexDirection: "column", children: _jsxs(Box, { paddingLeft: 2, borderLeft: true, borderColor: "green", flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "Result:" }), _jsx(Text, { color: "white", children: result })] }) })), error && (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["Error: ", typeof error === "string" ? error : String(error)] }) })), !isExpanded && stage === "end" && success && (_jsx(DiffDisplay, { toolName: name, parameters: parameters, startLineNumber: block.startLineNumber }))] }));
|
|
44
44
|
};
|
|
@@ -43,8 +43,6 @@ export interface ChatContextType {
|
|
|
43
43
|
stopBackgroundTask: (taskId: string) => boolean;
|
|
44
44
|
slashCommands: SlashCommand[];
|
|
45
45
|
hasSlashCommand: (commandId: string) => boolean;
|
|
46
|
-
subagentMessages: Record<string, Message[]>;
|
|
47
|
-
subagentLatestTokens: Record<string, number>;
|
|
48
46
|
permissionMode: PermissionMode;
|
|
49
47
|
setPermissionMode: (mode: PermissionMode) => void;
|
|
50
48
|
allowBypassInCycle: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EACV,OAAO,EACP,eAAe,EACf,cAAc,EACd,IAAI,EACJ,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACf,MAAM,gBAAgB,CAAC;AAWxB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IAEvB,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,oBAAoB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,cAAc,EAAE,KAAK,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACnD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACtC,CAAC,CAAC;IAEH,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,CACX,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,EAClD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACjC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAE1B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,mBAAmB,EAAE,MAAM,MAAM,EAAE,CAAC;IACpC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,mBAAmB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9D,eAAe,EAAE,cAAc,EAAE,CAAC;IAElC,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,uBAAuB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK;QAC3C,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,IAAI,CAAC;IACT,kBAAkB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAEhD,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAEhD,
|
|
1
|
+
{"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"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"}
|
package/dist/contexts/useChat.js
CHANGED
|
@@ -41,9 +41,6 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
|
|
|
41
41
|
const [tasks, setTasks] = useState([]);
|
|
42
42
|
// Command state
|
|
43
43
|
const [slashCommands, setSlashCommands] = useState([]);
|
|
44
|
-
// Subagent messages state
|
|
45
|
-
const [subagentMessages, setSubagentMessages] = useState({});
|
|
46
|
-
const [subagentLatestTokens, setSubagentLatestTokens] = useState({});
|
|
47
44
|
// Permission state
|
|
48
45
|
const [permissionMode, setPermissionModeState] = useState(initialPermissionMode ||
|
|
49
46
|
(bypassPermissions ? "bypassPermissions" : "default"));
|
|
@@ -75,16 +72,6 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
|
|
|
75
72
|
const [wasLastDetailsTooTall, setWasLastDetailsTooTall] = useState(0);
|
|
76
73
|
const allowBypassInCycle = !!bypassPermissions || initialPermissionMode === "bypassPermissions";
|
|
77
74
|
const agentRef = useRef(null);
|
|
78
|
-
const taskUpdateTimerRef = useRef(null);
|
|
79
|
-
const debouncedSetTasks = useCallback((newTasks) => {
|
|
80
|
-
if (taskUpdateTimerRef.current) {
|
|
81
|
-
clearTimeout(taskUpdateTimerRef.current);
|
|
82
|
-
}
|
|
83
|
-
taskUpdateTimerRef.current = setTimeout(() => {
|
|
84
|
-
setTasks([...newTasks]);
|
|
85
|
-
taskUpdateTimerRef.current = null;
|
|
86
|
-
}, 100);
|
|
87
|
-
}, [setTasks]);
|
|
88
75
|
// Permission confirmation methods with queue support
|
|
89
76
|
const showConfirmation = useCallback(async (toolName, toolInput, suggestedPrefix, hidePersistentOption, planContent) => {
|
|
90
77
|
return new Promise((resolve, reject) => {
|
|
@@ -126,20 +113,7 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
|
|
|
126
113
|
setBackgroundTasks([...tasks]);
|
|
127
114
|
},
|
|
128
115
|
onTasksChange: (tasks) => {
|
|
129
|
-
|
|
130
|
-
},
|
|
131
|
-
onSubagentMessagesChange: (subagentId, messages) => {
|
|
132
|
-
logger.debug("onSubagentMessagesChange", subagentId, messages.length);
|
|
133
|
-
setSubagentMessages((prev) => ({
|
|
134
|
-
...prev,
|
|
135
|
-
[subagentId]: [...messages],
|
|
136
|
-
}));
|
|
137
|
-
},
|
|
138
|
-
onSubagentLatestTotalTokensChange: (subagentId, tokens) => {
|
|
139
|
-
setSubagentLatestTokens((prev) => ({
|
|
140
|
-
...prev,
|
|
141
|
-
[subagentId]: tokens,
|
|
142
|
-
}));
|
|
116
|
+
setTasks([...tasks]);
|
|
143
117
|
},
|
|
144
118
|
onPermissionModeChange: (mode) => {
|
|
145
119
|
setPermissionModeState(mode);
|
|
@@ -221,15 +195,11 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
|
|
|
221
195
|
workdir,
|
|
222
196
|
worktreeSession,
|
|
223
197
|
model,
|
|
224
|
-
debouncedSetTasks,
|
|
225
198
|
initialPermissionMode,
|
|
226
199
|
]);
|
|
227
200
|
// Cleanup on unmount
|
|
228
201
|
useEffect(() => {
|
|
229
202
|
return () => {
|
|
230
|
-
if (taskUpdateTimerRef.current) {
|
|
231
|
-
clearTimeout(taskUpdateTimerRef.current);
|
|
232
|
-
}
|
|
233
203
|
if (agentRef.current) {
|
|
234
204
|
try {
|
|
235
205
|
// Display usage summary before cleanup
|
|
@@ -499,8 +469,6 @@ export const ChatProvider = ({ children, bypassPermissions, permissionMode: init
|
|
|
499
469
|
stopBackgroundTask,
|
|
500
470
|
slashCommands,
|
|
501
471
|
hasSlashCommand,
|
|
502
|
-
subagentMessages,
|
|
503
|
-
subagentLatestTokens,
|
|
504
472
|
permissionMode,
|
|
505
473
|
setPermissionMode,
|
|
506
474
|
allowBypassInCycle,
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgBA,wBAAsB,IAAI,kBAgYzB;AAGD,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import yargs from "yargs";
|
|
2
2
|
import { hideBin } from "yargs/helpers";
|
|
3
3
|
import { startCli } from "./cli.js";
|
|
4
|
+
import { logger } from "./utils/logger.js";
|
|
4
5
|
import { generateRandomName } from "wave-agent-sdk";
|
|
5
6
|
import { createWorktree } from "./utils/worktree.js";
|
|
6
7
|
import path from "path";
|
|
@@ -12,6 +13,15 @@ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
|
12
13
|
const version = packageJson.version;
|
|
13
14
|
// Export main function for external use
|
|
14
15
|
export async function main() {
|
|
16
|
+
// Start memory monitoring in debug mode
|
|
17
|
+
if (process.env.LOG_LEVEL === "DEBUG") {
|
|
18
|
+
setInterval(() => {
|
|
19
|
+
const usage = process.memoryUsage();
|
|
20
|
+
logger.debug(`[Memory] RSS: ${Math.round(usage.rss / 1024 / 1024)}MB, ` +
|
|
21
|
+
`Heap: ${Math.round(usage.heapUsed / 1024 / 1024)}/${Math.round(usage.heapTotal / 1024 / 1024)}MB, ` +
|
|
22
|
+
`External: ${Math.round(usage.external / 1024 / 1024)}MB`);
|
|
23
|
+
}, 10000).unref();
|
|
24
|
+
}
|
|
15
25
|
try {
|
|
16
26
|
const originalCwd = process.cwd();
|
|
17
27
|
const argv = await yargs(hideBin(process.argv))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"highlightUtils.d.ts","sourceRoot":"","sources":["../../src/utils/highlightUtils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"highlightUtils.d.ts","sourceRoot":"","sources":["../../src/utils/highlightUtils.ts"],"names":[],"mappings":"AA6DA,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAsCvE"}
|
|
@@ -45,14 +45,6 @@ function nodeToAnsi(node) {
|
|
|
45
45
|
const classes = node.getAttribute("class")?.split(/\s+/) || [];
|
|
46
46
|
for (const className of classes) {
|
|
47
47
|
if (theme[className]) {
|
|
48
|
-
// If content has newlines, split it and apply style to each line
|
|
49
|
-
// to ensure ANSI codes are correctly applied when splitting the final string by lines.
|
|
50
|
-
if (content.includes("\n")) {
|
|
51
|
-
return content
|
|
52
|
-
.split("\n")
|
|
53
|
-
.map((line) => theme[className](line))
|
|
54
|
-
.join("\n");
|
|
55
|
-
}
|
|
56
48
|
return theme[className](content);
|
|
57
49
|
}
|
|
58
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH;;GAEG;AACH,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAsBD;;GAEG;AACH,UAAU,SAAS;IACjB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;CAC7B;
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH;;GAEG;AACH,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAsBD;;GAEG;AACH,UAAU,SAAS;IACjB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;CAC7B;AAiID;;GAEG;AACH,eAAO,MAAM,MAAM;IACjB;;OAEG;qBACc,OAAO,EAAE,KAAG,IAAI;IAIjC;;OAEG;oBACa,OAAO,EAAE,KAAG,IAAI;IAIhC;;OAEG;oBACa,OAAO,EAAE,KAAG,IAAI;IAIhC;;OAEG;qBACc,OAAO,EAAE,KAAG,IAAI;CAGlC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,QAAO,SAE/B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,QAAO,MAE7B,CAAC;AAEF;;GAEG;AACH,UAAU,gBAAgB;IACxB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;CACnB;AAqDD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GACtB,eAAe,OAAO,CAAC,gBAAgB,CAAC,KACvC,OAAO,CAAC,IAAI,CAiBd,CAAC"}
|
package/dist/utils/logger.js
CHANGED
|
@@ -106,20 +106,25 @@ const formatArg = (arg) => {
|
|
|
106
106
|
return "null";
|
|
107
107
|
if (arg === undefined)
|
|
108
108
|
return "undefined";
|
|
109
|
+
let result;
|
|
109
110
|
if (arg instanceof Error) {
|
|
110
111
|
// Special handling for Error objects, display stack or message
|
|
111
|
-
|
|
112
|
+
result = arg.stack || arg.message || String(arg);
|
|
112
113
|
}
|
|
113
|
-
if (typeof arg === "object") {
|
|
114
|
+
else if (typeof arg === "object") {
|
|
114
115
|
try {
|
|
115
|
-
|
|
116
|
+
result = JSON.stringify(arg);
|
|
116
117
|
}
|
|
117
118
|
catch {
|
|
118
119
|
// If JSON.stringify fails, fallback to String()
|
|
119
|
-
|
|
120
|
+
result = String(arg);
|
|
120
121
|
}
|
|
121
122
|
}
|
|
122
|
-
|
|
123
|
+
else {
|
|
124
|
+
result = String(arg);
|
|
125
|
+
}
|
|
126
|
+
// Ensure no newlines in the result to keep log entries single-line
|
|
127
|
+
return result.replace(/[\n\r]+/g, " ");
|
|
123
128
|
};
|
|
124
129
|
/**
|
|
125
130
|
* Generic log output function
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
* Tool parameter transformation utilities for UI rendering
|
|
3
3
|
* Forces type judgment based on tool name using type assertions
|
|
4
4
|
*/
|
|
5
|
-
import { type Change, type EditToolParameters } from "wave-agent-sdk";
|
|
5
|
+
import { type Change, type WriteToolParameters, type EditToolParameters } from "wave-agent-sdk";
|
|
6
|
+
/**
|
|
7
|
+
* Transform Write tool parameters to changes
|
|
8
|
+
*/
|
|
9
|
+
export declare function transformWriteParameters(parameters: WriteToolParameters): Change[];
|
|
6
10
|
/**
|
|
7
11
|
* Transform Edit tool parameters to changes
|
|
8
12
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolParameterTransforms.d.ts","sourceRoot":"","sources":["../../src/utils/toolParameterTransforms.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"toolParameterTransforms.d.ts","sourceRoot":"","sources":["../../src/utils/toolParameterTransforms.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,KAAK,MAAM,EACX,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAC;AAmBxB;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,mBAAmB,GAC9B,MAAM,EAAE,CAOV;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,kBAAkB,GAC7B,MAAM,EAAE,CAOV;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,MAAM,GACvB,MAAM,EAAE,CA8BV"}
|
|
@@ -18,6 +18,17 @@ function parseToolParameters(parameters) {
|
|
|
18
18
|
return {};
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Transform Write tool parameters to changes
|
|
23
|
+
*/
|
|
24
|
+
export function transformWriteParameters(parameters) {
|
|
25
|
+
return [
|
|
26
|
+
{
|
|
27
|
+
oldContent: "", // No previous content for write operations
|
|
28
|
+
newContent: parameters.content,
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
}
|
|
21
32
|
/**
|
|
22
33
|
* Transform Edit tool parameters to changes
|
|
23
34
|
*/
|
|
@@ -41,6 +52,9 @@ export function transformToolBlockToChanges(toolName, parameters, startLineNumbe
|
|
|
41
52
|
const parsedParams = parseToolParameters(parameters);
|
|
42
53
|
let changes = [];
|
|
43
54
|
switch (toolName) {
|
|
55
|
+
case "Write":
|
|
56
|
+
changes = transformWriteParameters(parsedParams);
|
|
57
|
+
break;
|
|
44
58
|
case "Edit":
|
|
45
59
|
changes = transformEditParameters(parsedParams);
|
|
46
60
|
break;
|
package/dist/utils/worktree.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/utils/worktree.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED
|
|
1
|
+
{"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/utils/worktree.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,eAAe,CA+EzE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CA6D7D"}
|
package/dist/utils/worktree.js
CHANGED
|
@@ -2,7 +2,6 @@ import { execSync } from "node:child_process";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import { getDefaultRemoteBranch, getGitMainRepoRoot } from "wave-agent-sdk";
|
|
5
|
-
export const WORKTREE_DIR = ".wave/worktrees";
|
|
6
5
|
/**
|
|
7
6
|
* Create a new git worktree
|
|
8
7
|
* @param name Worktree name
|
|
@@ -11,7 +10,8 @@ export const WORKTREE_DIR = ".wave/worktrees";
|
|
|
11
10
|
*/
|
|
12
11
|
export function createWorktree(name, cwd) {
|
|
13
12
|
const repoRoot = getGitMainRepoRoot(cwd);
|
|
14
|
-
const
|
|
13
|
+
const projectName = path.basename(repoRoot);
|
|
14
|
+
const worktreePath = path.join(repoRoot, "..", `${projectName}.worktrees`, name);
|
|
15
15
|
const branchName = `worktree-${name}`;
|
|
16
16
|
const baseBranch = getDefaultRemoteBranch(cwd);
|
|
17
17
|
// Ensure parent directory exists
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wave-code",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "CLI-based code assistant powered by AI, built with React and Ink",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"semver": "^7.7.4",
|
|
43
43
|
"yargs": "^17.7.2",
|
|
44
44
|
"zod": "^3.23.8",
|
|
45
|
-
"wave-agent-sdk": "0.12.
|
|
45
|
+
"wave-agent-sdk": "0.12.1"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/react": "^19.1.8",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
},
|
|
66
66
|
"license": "MIT",
|
|
67
67
|
"scripts": {
|
|
68
|
-
"wave": "tsx --tsconfig tsconfig.dev.json src/index.ts",
|
|
68
|
+
"wave": "NODE_OPTIONS='--heapsnapshot-near-heap-limit=1' tsx --tsconfig tsconfig.dev.json src/index.ts",
|
|
69
69
|
"build": "rimraf dist && tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
|
|
70
70
|
"type-check": "tsc --noEmit --incremental",
|
|
71
71
|
"watch": "tsc -p tsconfig.build.json --watch & tsc-alias -p tsconfig.build.json --watch",
|
package/src/acp/agent.ts
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
import React, { useMemo } from "react";
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
|
-
import {
|
|
4
|
-
WRITE_TOOL_NAME,
|
|
5
|
-
EDIT_TOOL_NAME,
|
|
6
|
-
type WriteToolParameters,
|
|
7
|
-
} from "wave-agent-sdk";
|
|
3
|
+
import { WRITE_TOOL_NAME, EDIT_TOOL_NAME } from "wave-agent-sdk";
|
|
8
4
|
import { transformToolBlockToChanges } from "../utils/toolParameterTransforms.js";
|
|
9
5
|
import { diffLines, diffWords } from "diff";
|
|
10
|
-
import path from "path";
|
|
11
|
-
import { Markdown } from "./Markdown.js";
|
|
12
6
|
|
|
13
7
|
interface DiffDisplayProps {
|
|
14
8
|
toolName?: string;
|
|
@@ -103,23 +97,6 @@ export const DiffDisplay: React.FC<DiffDisplayProps> = ({
|
|
|
103
97
|
}
|
|
104
98
|
};
|
|
105
99
|
|
|
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
|
-
|
|
123
100
|
// Render expanded diff display
|
|
124
101
|
const renderExpandedDiff = () => {
|
|
125
102
|
try {
|
|
@@ -375,9 +352,7 @@ export const DiffDisplay: React.FC<DiffDisplayProps> = ({
|
|
|
375
352
|
return (
|
|
376
353
|
<Box flexDirection="column">
|
|
377
354
|
<Box paddingLeft={2} borderLeft borderColor="cyan" flexDirection="column">
|
|
378
|
-
{
|
|
379
|
-
? renderWriteContent()
|
|
380
|
-
: renderExpandedDiff()}
|
|
355
|
+
{renderExpandedDiff()}
|
|
381
356
|
</Box>
|
|
382
357
|
</Box>
|
|
383
358
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useLayoutEffect, useRef } from "react";
|
|
2
2
|
import os from "os";
|
|
3
3
|
import { Box, Text, Static, measureElement } from "ink";
|
|
4
|
-
import type { Message } from "wave-agent-sdk";
|
|
4
|
+
import type { Message, MessageBlock } from "wave-agent-sdk";
|
|
5
5
|
import { MessageBlockItem } from "./MessageBlockItem.js";
|
|
6
6
|
|
|
7
7
|
export interface MessageListProps {
|
|
@@ -39,6 +39,18 @@ export const MessageList = React.memo(
|
|
|
39
39
|
// Filter out meta messages
|
|
40
40
|
const visibleMessages = messages.filter((m) => !m.isMeta);
|
|
41
41
|
|
|
42
|
+
const isRunning = (b: MessageBlock) =>
|
|
43
|
+
(b.type === "tool" && b.stage === "running") ||
|
|
44
|
+
(b.type === "bang" && b.isRunning) ||
|
|
45
|
+
(b.type === "slash" && b.stage === "running");
|
|
46
|
+
|
|
47
|
+
const messagesWithRunningBlocks = new Set(
|
|
48
|
+
visibleMessages
|
|
49
|
+
.map((m, i) => ({ m, i }))
|
|
50
|
+
.filter(({ m }) => m.blocks.some(isRunning))
|
|
51
|
+
.map(({ i }) => i),
|
|
52
|
+
);
|
|
53
|
+
|
|
42
54
|
// Flatten messages into blocks with metadata
|
|
43
55
|
const allBlocks = visibleMessages.flatMap((message, messageIndex) => {
|
|
44
56
|
return message.blocks.map((block, blockIndex) => ({
|
|
@@ -55,9 +67,7 @@ export const MessageList = React.memo(
|
|
|
55
67
|
const { block } = item;
|
|
56
68
|
const isDynamic =
|
|
57
69
|
!forceStatic &&
|
|
58
|
-
((
|
|
59
|
-
(block.type === "bang" && block.isRunning) ||
|
|
60
|
-
(block.type === "slash" && block.stage === "running"));
|
|
70
|
+
(messagesWithRunningBlocks.has(item.messageIndex) || isRunning(block));
|
|
61
71
|
return { ...item, isDynamic };
|
|
62
72
|
});
|
|
63
73
|
|
|
@@ -86,6 +86,13 @@ export const StatusCommand: React.FC<StatusCommandProps> = ({ onCancel }) => {
|
|
|
86
86
|
<Text color="white">{modelConfig.model}</Text>
|
|
87
87
|
</Box>
|
|
88
88
|
|
|
89
|
+
<Box>
|
|
90
|
+
<Box width={20}>
|
|
91
|
+
<Text color="yellow">Fast model:</Text>
|
|
92
|
+
</Box>
|
|
93
|
+
<Text color="white">{modelConfig.fastModel}</Text>
|
|
94
|
+
</Box>
|
|
95
|
+
|
|
89
96
|
<Box marginTop={1}>
|
|
90
97
|
<Text dimColor>Esc to cancel</Text>
|
|
91
98
|
</Box>
|
package/src/contexts/useChat.tsx
CHANGED
|
@@ -77,9 +77,6 @@ export interface ChatContextType {
|
|
|
77
77
|
// Slash Command functionality
|
|
78
78
|
slashCommands: SlashCommand[];
|
|
79
79
|
hasSlashCommand: (commandId: string) => boolean;
|
|
80
|
-
// Subagent messages
|
|
81
|
-
subagentMessages: Record<string, Message[]>;
|
|
82
|
-
subagentLatestTokens: Record<string, number>;
|
|
83
80
|
// Permission functionality
|
|
84
81
|
permissionMode: PermissionMode;
|
|
85
82
|
setPermissionMode: (mode: PermissionMode) => void;
|
|
@@ -195,14 +192,6 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
195
192
|
// Command state
|
|
196
193
|
const [slashCommands, setSlashCommands] = useState<SlashCommand[]>([]);
|
|
197
194
|
|
|
198
|
-
// Subagent messages state
|
|
199
|
-
const [subagentMessages, setSubagentMessages] = useState<
|
|
200
|
-
Record<string, Message[]>
|
|
201
|
-
>({});
|
|
202
|
-
const [subagentLatestTokens, setSubagentLatestTokens] = useState<
|
|
203
|
-
Record<string, number>
|
|
204
|
-
>({});
|
|
205
|
-
|
|
206
195
|
// Permission state
|
|
207
196
|
const [permissionMode, setPermissionModeState] = useState<PermissionMode>(
|
|
208
197
|
initialPermissionMode ||
|
|
@@ -276,20 +265,6 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
276
265
|
!!bypassPermissions || initialPermissionMode === "bypassPermissions";
|
|
277
266
|
|
|
278
267
|
const agentRef = useRef<Agent | null>(null);
|
|
279
|
-
const taskUpdateTimerRef = useRef<NodeJS.Timeout | null>(null);
|
|
280
|
-
|
|
281
|
-
const debouncedSetTasks = useCallback(
|
|
282
|
-
(newTasks: Task[]) => {
|
|
283
|
-
if (taskUpdateTimerRef.current) {
|
|
284
|
-
clearTimeout(taskUpdateTimerRef.current);
|
|
285
|
-
}
|
|
286
|
-
taskUpdateTimerRef.current = setTimeout(() => {
|
|
287
|
-
setTasks([...newTasks]);
|
|
288
|
-
taskUpdateTimerRef.current = null;
|
|
289
|
-
}, 100);
|
|
290
|
-
},
|
|
291
|
-
[setTasks],
|
|
292
|
-
);
|
|
293
268
|
|
|
294
269
|
// Permission confirmation methods with queue support
|
|
295
270
|
const showConfirmation = useCallback(
|
|
@@ -343,23 +318,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
343
318
|
setBackgroundTasks([...tasks]);
|
|
344
319
|
},
|
|
345
320
|
onTasksChange: (tasks) => {
|
|
346
|
-
|
|
347
|
-
},
|
|
348
|
-
onSubagentMessagesChange: (subagentId: string, messages: Message[]) => {
|
|
349
|
-
logger.debug("onSubagentMessagesChange", subagentId, messages.length);
|
|
350
|
-
setSubagentMessages((prev) => ({
|
|
351
|
-
...prev,
|
|
352
|
-
[subagentId]: [...messages],
|
|
353
|
-
}));
|
|
354
|
-
},
|
|
355
|
-
onSubagentLatestTotalTokensChange: (
|
|
356
|
-
subagentId: string,
|
|
357
|
-
tokens: number,
|
|
358
|
-
) => {
|
|
359
|
-
setSubagentLatestTokens((prev) => ({
|
|
360
|
-
...prev,
|
|
361
|
-
[subagentId]: tokens,
|
|
362
|
-
}));
|
|
321
|
+
setTasks([...tasks]);
|
|
363
322
|
},
|
|
364
323
|
onPermissionModeChange: (mode) => {
|
|
365
324
|
setPermissionModeState(mode);
|
|
@@ -455,17 +414,12 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
455
414
|
workdir,
|
|
456
415
|
worktreeSession,
|
|
457
416
|
model,
|
|
458
|
-
debouncedSetTasks,
|
|
459
417
|
initialPermissionMode,
|
|
460
418
|
]);
|
|
461
419
|
|
|
462
420
|
// Cleanup on unmount
|
|
463
421
|
useEffect(() => {
|
|
464
422
|
return () => {
|
|
465
|
-
if (taskUpdateTimerRef.current) {
|
|
466
|
-
clearTimeout(taskUpdateTimerRef.current);
|
|
467
|
-
}
|
|
468
|
-
|
|
469
423
|
if (agentRef.current) {
|
|
470
424
|
try {
|
|
471
425
|
// Display usage summary before cleanup
|
|
@@ -772,8 +726,6 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
|
|
|
772
726
|
stopBackgroundTask,
|
|
773
727
|
slashCommands,
|
|
774
728
|
hasSlashCommand,
|
|
775
|
-
subagentMessages,
|
|
776
|
-
subagentLatestTokens,
|
|
777
729
|
permissionMode,
|
|
778
730
|
setPermissionMode,
|
|
779
731
|
allowBypassInCycle,
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import yargs from "yargs";
|
|
2
2
|
import { hideBin } from "yargs/helpers";
|
|
3
3
|
import { startCli } from "./cli.js";
|
|
4
|
+
import { logger } from "./utils/logger.js";
|
|
4
5
|
import { Scope, generateRandomName, type PermissionMode } from "wave-agent-sdk";
|
|
5
6
|
import { createWorktree, type WorktreeSession } from "./utils/worktree.js";
|
|
6
7
|
import path from "path";
|
|
@@ -14,6 +15,18 @@ const version = packageJson.version;
|
|
|
14
15
|
|
|
15
16
|
// Export main function for external use
|
|
16
17
|
export async function main() {
|
|
18
|
+
// Start memory monitoring in debug mode
|
|
19
|
+
if (process.env.LOG_LEVEL === "DEBUG") {
|
|
20
|
+
setInterval(() => {
|
|
21
|
+
const usage = process.memoryUsage();
|
|
22
|
+
logger.debug(
|
|
23
|
+
`[Memory] RSS: ${Math.round(usage.rss / 1024 / 1024)}MB, ` +
|
|
24
|
+
`Heap: ${Math.round(usage.heapUsed / 1024 / 1024)}/${Math.round(usage.heapTotal / 1024 / 1024)}MB, ` +
|
|
25
|
+
`External: ${Math.round(usage.external / 1024 / 1024)}MB`,
|
|
26
|
+
);
|
|
27
|
+
}, 10000).unref();
|
|
28
|
+
}
|
|
29
|
+
|
|
17
30
|
try {
|
|
18
31
|
const originalCwd = process.cwd();
|
|
19
32
|
const argv = await yargs(hideBin(process.argv))
|
|
@@ -49,14 +49,6 @@ 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
|
-
}
|
|
60
52
|
return theme[className](content);
|
|
61
53
|
}
|
|
62
54
|
}
|
package/src/utils/logger.ts
CHANGED
|
@@ -124,21 +124,23 @@ const formatArg = (arg: unknown): string => {
|
|
|
124
124
|
if (arg === null) return "null";
|
|
125
125
|
if (arg === undefined) return "undefined";
|
|
126
126
|
|
|
127
|
+
let result: string;
|
|
127
128
|
if (arg instanceof Error) {
|
|
128
129
|
// Special handling for Error objects, display stack or message
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (typeof arg === "object") {
|
|
130
|
+
result = arg.stack || arg.message || String(arg);
|
|
131
|
+
} else if (typeof arg === "object") {
|
|
133
132
|
try {
|
|
134
|
-
|
|
133
|
+
result = JSON.stringify(arg);
|
|
135
134
|
} catch {
|
|
136
135
|
// If JSON.stringify fails, fallback to String()
|
|
137
|
-
|
|
136
|
+
result = String(arg);
|
|
138
137
|
}
|
|
138
|
+
} else {
|
|
139
|
+
result = String(arg);
|
|
139
140
|
}
|
|
140
141
|
|
|
141
|
-
|
|
142
|
+
// Ensure no newlines in the result to keep log entries single-line
|
|
143
|
+
return result.replace(/[\n\r]+/g, " ");
|
|
142
144
|
};
|
|
143
145
|
|
|
144
146
|
/**
|
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
* Forces type judgment based on tool name using type assertions
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
type Change,
|
|
8
|
+
type WriteToolParameters,
|
|
9
|
+
type EditToolParameters,
|
|
10
|
+
} from "wave-agent-sdk";
|
|
7
11
|
import { logger } from "./logger.js";
|
|
8
12
|
|
|
9
13
|
/**
|
|
@@ -22,6 +26,20 @@ function parseToolParameters(parameters: string): unknown {
|
|
|
22
26
|
}
|
|
23
27
|
}
|
|
24
28
|
|
|
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
|
+
|
|
25
43
|
/**
|
|
26
44
|
* Transform Edit tool parameters to changes
|
|
27
45
|
*/
|
|
@@ -54,6 +72,10 @@ export function transformToolBlockToChanges(
|
|
|
54
72
|
|
|
55
73
|
let changes: Change[] = [];
|
|
56
74
|
switch (toolName) {
|
|
75
|
+
case "Write":
|
|
76
|
+
changes = transformWriteParameters(parsedParams as WriteToolParameters);
|
|
77
|
+
break;
|
|
78
|
+
|
|
57
79
|
case "Edit":
|
|
58
80
|
changes = transformEditParameters(parsedParams as EditToolParameters);
|
|
59
81
|
break;
|
package/src/utils/worktree.ts
CHANGED
|
@@ -13,8 +13,6 @@ export interface WorktreeSession {
|
|
|
13
13
|
isNew: boolean;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export const WORKTREE_DIR = ".wave/worktrees";
|
|
17
|
-
|
|
18
16
|
/**
|
|
19
17
|
* Create a new git worktree
|
|
20
18
|
* @param name Worktree name
|
|
@@ -23,7 +21,13 @@ export const WORKTREE_DIR = ".wave/worktrees";
|
|
|
23
21
|
*/
|
|
24
22
|
export function createWorktree(name: string, cwd: string): WorktreeSession {
|
|
25
23
|
const repoRoot = getGitMainRepoRoot(cwd);
|
|
26
|
-
const
|
|
24
|
+
const projectName = path.basename(repoRoot);
|
|
25
|
+
const worktreePath = path.join(
|
|
26
|
+
repoRoot,
|
|
27
|
+
"..",
|
|
28
|
+
`${projectName}.worktrees`,
|
|
29
|
+
name,
|
|
30
|
+
);
|
|
27
31
|
const branchName = `worktree-${name}`;
|
|
28
32
|
const baseBranch = getDefaultRemoteBranch(cwd);
|
|
29
33
|
|