wave-code 0.10.1 → 0.10.3

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.
@@ -125,6 +125,7 @@ export interface ChatProviderProps extends BaseAppProps {
125
125
  export const ChatProvider: React.FC<ChatProviderProps> = ({
126
126
  children,
127
127
  bypassPermissions,
128
+ permissionMode: initialPermissionMode,
128
129
  pluginDirs,
129
130
  tools,
130
131
  workdir,
@@ -180,8 +181,10 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
180
181
  >({});
181
182
 
182
183
  // Permission state
183
- const [permissionMode, setPermissionModeState] =
184
- useState<PermissionMode>("default");
184
+ const [permissionMode, setPermissionModeState] = useState<PermissionMode>(
185
+ initialPermissionMode ||
186
+ (bypassPermissions ? "bypassPermissions" : "default"),
187
+ );
185
188
 
186
189
  // Confirmation state with queue-based architecture
187
190
  const [isConfirmationVisible, setIsConfirmationVisible] = useState(false);
@@ -223,6 +226,20 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
223
226
  const [wasLastDetailsTooTall, setWasLastDetailsTooTall] = useState(0);
224
227
 
225
228
  const agentRef = useRef<Agent | null>(null);
229
+ const taskUpdateTimerRef = useRef<NodeJS.Timeout | null>(null);
230
+
231
+ const debouncedSetTasks = useCallback(
232
+ (newTasks: Task[]) => {
233
+ if (taskUpdateTimerRef.current) {
234
+ clearTimeout(taskUpdateTimerRef.current);
235
+ }
236
+ taskUpdateTimerRef.current = setTimeout(() => {
237
+ setTasks([...newTasks]);
238
+ taskUpdateTimerRef.current = null;
239
+ }, 100);
240
+ },
241
+ [setTasks],
242
+ );
226
243
 
227
244
  // Permission confirmation methods with queue support
228
245
  const showConfirmation = useCallback(
@@ -274,7 +291,7 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
274
291
  setBackgroundTasks([...tasks]);
275
292
  },
276
293
  onTasksChange: (tasks) => {
277
- setTasks([...tasks]);
294
+ debouncedSetTasks(tasks);
278
295
  },
279
296
  onSubagentMessagesChange: (subagentId: string, messages: Message[]) => {
280
297
  logger.debug("onSubagentMessagesChange", subagentId, messages.length);
@@ -325,7 +342,9 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
325
342
  restoreSessionId,
326
343
  continueLastSession,
327
344
  logger,
328
- permissionMode: bypassPermissions ? "bypassPermissions" : undefined,
345
+ permissionMode:
346
+ initialPermissionMode ||
347
+ (bypassPermissions ? "bypassPermissions" : undefined),
329
348
  canUseTool: permissionCallback,
330
349
  stream: false, // 关闭流式模式
331
350
  plugins: pluginDirs?.map((path) => ({ type: "local", path })),
@@ -371,11 +390,17 @@ export const ChatProvider: React.FC<ChatProviderProps> = ({
371
390
  workdir,
372
391
  worktreeSession,
373
392
  model,
393
+ debouncedSetTasks,
394
+ initialPermissionMode,
374
395
  ]);
375
396
 
376
397
  // Cleanup on unmount
377
398
  useEffect(() => {
378
399
  return () => {
400
+ if (taskUpdateTimerRef.current) {
401
+ clearTimeout(taskUpdateTimerRef.current);
402
+ }
403
+
379
404
  if (agentRef.current) {
380
405
  try {
381
406
  // Display usage summary before cleanup
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import yargs from "yargs";
2
2
  import { hideBin } from "yargs/helpers";
3
3
  import { startCli } from "./cli.js";
4
- import { Scope, generateRandomName } from "wave-agent-sdk";
4
+ import { Scope, generateRandomName, type PermissionMode } from "wave-agent-sdk";
5
5
  import { createWorktree, type WorktreeSession } from "./utils/worktree.js";
6
6
  import path from "path";
7
7
  import { readFileSync } from "fs";
@@ -53,6 +53,18 @@ export async function main() {
53
53
  default: false,
54
54
  global: false,
55
55
  })
56
+ .option("permission-mode", {
57
+ description: "Permission mode to use for the session",
58
+ choices: [
59
+ "acceptEdits",
60
+ "bypassPermissions",
61
+ "default",
62
+ "dontAsk",
63
+ "plan",
64
+ ],
65
+ type: "string",
66
+ global: false,
67
+ })
56
68
  .option("plugin-dir", {
57
69
  description: "Load a plugin from a specific directory",
58
70
  type: "array",
@@ -274,7 +286,8 @@ export async function main() {
274
286
  // Continue with the selected session
275
287
  return startCli({
276
288
  restoreSessionId: selectedSessionId,
277
- bypassPermissions: argv.dangerouslySkipPermissions,
289
+ bypassPermissions: argv.dangerouslySkipPermissions as boolean,
290
+ permissionMode: argv.permissionMode as PermissionMode | undefined,
278
291
  pluginDirs,
279
292
  tools,
280
293
  worktreeSession,
@@ -295,6 +308,7 @@ export async function main() {
295
308
  bypassPermissions: argv.dangerouslySkipPermissions as
296
309
  | boolean
297
310
  | undefined,
311
+ permissionMode: argv.permissionMode as PermissionMode | undefined,
298
312
  pluginDirs,
299
313
  tools,
300
314
  worktreeSession,
@@ -308,6 +322,7 @@ export async function main() {
308
322
  restoreSessionId: argv.restore as string | undefined,
309
323
  continueLastSession: argv.continue as boolean | undefined,
310
324
  bypassPermissions: argv.dangerouslySkipPermissions as boolean | undefined,
325
+ permissionMode: argv.permissionMode as PermissionMode | undefined,
311
326
  pluginDirs,
312
327
  tools,
313
328
  worktreeSession,
package/src/print-cli.ts CHANGED
@@ -38,6 +38,7 @@ export async function startPrintCli(options: PrintCliOptions): Promise<void> {
38
38
  message,
39
39
  showStats = false,
40
40
  bypassPermissions,
41
+ permissionMode,
41
42
  pluginDirs,
42
43
  tools,
43
44
  worktreeSession,
@@ -144,7 +145,8 @@ export async function startPrintCli(options: PrintCliOptions): Promise<void> {
144
145
  callbacks,
145
146
  restoreSessionId,
146
147
  continueLastSession,
147
- permissionMode: bypassPermissions ? "bypassPermissions" : undefined,
148
+ permissionMode:
149
+ permissionMode || (bypassPermissions ? "bypassPermissions" : undefined),
148
150
  plugins: pluginDirs?.map((path) => ({ type: "local", path })),
149
151
  tools,
150
152
  workdir,
package/src/types.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import { WorktreeSession } from "./utils/worktree.js";
2
+ import { PermissionMode } from "wave-agent-sdk";
2
3
 
3
4
  export interface BaseAppProps {
4
5
  bypassPermissions?: boolean;
6
+ permissionMode?: PermissionMode;
5
7
  pluginDirs?: string[];
6
8
  tools?: string[];
7
9
  worktreeSession?: WorktreeSession;
@@ -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;
@@ -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 { getGitRepoRoot, getDefaultRemoteBranch } from "wave-agent-sdk";
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 = getGitRepoRoot(cwd);
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);