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.
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/acp/agent.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,KAAK,KAAK,IAAI,QAAQ,EACtB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EAUzB,KAAK,qBAAqB,EAC1B,KAAK,6BAA6B,EAClC,KAAK,8BAA8B,EAEpC,MAAM,0BAA0B,CAAC;AAElC,qBAAa,YAAa,YAAW,QAAQ;IAC3C,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,UAAU,CAAsB;gBAE5B,UAAU,EAAE,mBAAmB;IAI3C,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,uBAAuB;YAkBjB,gBAAgB;IASxB,UAAU,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAoBzC,YAAY,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAI5C,WAAW;IA8CnB,UAAU,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA8BlE,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA4BrE,YAAY,CAChB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,oBAAoB,CAAC;IAmB1B,qBAAqB,CACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAc7B,SAAS,CACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAO7B,cAAc,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5D,sBAAsB,CAC1B,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,8BAA8B,CAAC;IAgBpC,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAiDtD,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;YASzC,uBAAuB;YAsGvB,mBAAmB;IA2EjC,OAAO,CAAC,cAAc;IA4BtB,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,WAAW;IAmBnB,OAAO,CAAC,eAAe;CAsIxB"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/acp/agent.ts"],"names":[],"mappings":"AAeA,OAAO,EACL,KAAK,KAAK,IAAI,QAAQ,EACtB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EAUzB,KAAK,qBAAqB,EAC1B,KAAK,6BAA6B,EAClC,KAAK,8BAA8B,EAEpC,MAAM,0BAA0B,CAAC;AAElC,qBAAa,YAAa,YAAW,QAAQ;IAC3C,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,UAAU,CAAsB;gBAE5B,UAAU,EAAE,mBAAmB;IAI3C,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,uBAAuB;YAkBjB,gBAAgB;IASxB,UAAU,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAoBzC,YAAY,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAI5C,WAAW;IAiEnB,UAAU,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAalE,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAWrE,YAAY,CAChB,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,oBAAoB,CAAC;IAuB1B,qBAAqB,CACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAc7B,SAAS,CACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAO7B,cAAc,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5D,sBAAsB,CAC1B,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,8BAA8B,CAAC;IAgBpC,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAiDtD,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;YASzC,uBAAuB;YAgHvB,mBAAmB;IA6EjC,OAAO,CAAC,cAAc;IAqCtB,OAAO,CAAC,gBAAgB;IAmCxB,OAAO,CAAC,WAAW;IAmBnB,OAAO,CAAC,eAAe;CAgMxB"}
package/dist/acp/agent.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Agent as WaveAgent, listSessions as listWaveSessions, deleteSession as deleteWaveSession, } from "wave-agent-sdk";
1
+ import { Agent as WaveAgent, listSessions as listWaveSessions, listAllSessions as listAllWaveSessions, deleteSession as deleteWaveSession, truncateContent, } from "wave-agent-sdk";
2
2
  import * as fs from "node:fs/promises";
3
3
  import * as path from "node:path";
4
4
  import { logger } from "../utils/logger.js";
@@ -86,6 +86,7 @@ export class WaveAcpAgent {
86
86
  const agent = await WaveAgent.create({
87
87
  workdir: cwd,
88
88
  restoreSessionId: sessionId,
89
+ stream: false,
89
90
  canUseTool: (context) => {
90
91
  if (!agentRef.instance) {
91
92
  throw new Error("Agent instance not yet initialized");
@@ -108,17 +109,11 @@ export class WaveAcpAgent {
108
109
  this.agents.set(actualSessionId, agent);
109
110
  // Update the callbacks object with the correct sessionId
110
111
  Object.assign(callbacks, this.createCallbacks(actualSessionId));
111
- return agent;
112
- }
113
- async newSession(params) {
114
- const { cwd } = params;
115
- logger.info(`Creating new session in ${cwd}`);
116
- const agent = await this.createAgent(undefined, cwd);
117
- logger.info(`New session created with ID: ${agent.sessionId}`);
118
112
  // Send initial available commands after agent creation
113
+ // Use setImmediate to ensure the client receives the session response before the update
119
114
  setImmediate(() => {
120
115
  this.connection.sessionUpdate({
121
- sessionId: agent.sessionId,
116
+ sessionId: actualSessionId,
122
117
  update: {
123
118
  sessionUpdate: "available_commands_update",
124
119
  availableCommands: agent.getSlashCommands().map((cmd) => ({
@@ -131,6 +126,13 @@ export class WaveAcpAgent {
131
126
  },
132
127
  });
133
128
  });
129
+ return agent;
130
+ }
131
+ async newSession(params) {
132
+ const { cwd } = params;
133
+ logger.info(`Creating new session in ${cwd}`);
134
+ const agent = await this.createAgent(undefined, cwd);
135
+ logger.info(`New session created with ID: ${agent.sessionId}`);
134
136
  return {
135
137
  sessionId: agent.sessionId,
136
138
  modes: this.getSessionModeState(agent),
@@ -141,22 +143,6 @@ export class WaveAcpAgent {
141
143
  const { sessionId, cwd } = params;
142
144
  logger.info(`Loading session: ${sessionId} in ${cwd}`);
143
145
  const agent = await this.createAgent(sessionId, cwd);
144
- // Send initial available commands after agent creation
145
- setImmediate(() => {
146
- this.connection.sessionUpdate({
147
- sessionId: agent.sessionId,
148
- update: {
149
- sessionUpdate: "available_commands_update",
150
- availableCommands: agent.getSlashCommands().map((cmd) => ({
151
- name: cmd.name,
152
- description: cmd.description,
153
- input: {
154
- hint: "Enter arguments...",
155
- },
156
- })),
157
- },
158
- });
159
- });
160
146
  return {
161
147
  modes: this.getSessionModeState(agent),
162
148
  configOptions: this.getSessionConfigOptions(agent),
@@ -165,16 +151,20 @@ export class WaveAcpAgent {
165
151
  async listSessions(params) {
166
152
  const { cwd } = params;
167
153
  logger.info(`listSessions called with params: ${JSON.stringify(params)}`);
154
+ let waveSessions;
168
155
  if (!cwd) {
169
- logger.warn("listSessions called without cwd, returning empty list");
170
- return { sessions: [] };
156
+ logger.info("listSessions called without cwd, listing all sessions");
157
+ waveSessions = await listAllWaveSessions();
158
+ }
159
+ else {
160
+ logger.info(`Listing sessions for ${cwd}`);
161
+ waveSessions = await listWaveSessions(cwd);
171
162
  }
172
- logger.info(`Listing sessions for ${cwd}`);
173
- const waveSessions = await listWaveSessions(cwd);
174
- logger.info(`Found ${waveSessions.length} sessions for ${cwd}`);
163
+ logger.info(`Found ${waveSessions.length} sessions`);
175
164
  const sessions = waveSessions.map((meta) => ({
176
165
  sessionId: meta.id,
177
166
  cwd: meta.workdir,
167
+ title: meta.firstMessage ? truncateContent(meta.firstMessage) : undefined,
178
168
  updatedAt: meta.lastActiveAt.toISOString(),
179
169
  }));
180
170
  return { sessions };
@@ -272,6 +262,21 @@ export class WaveAcpAgent {
272
262
  const workdir = agent?.workingDirectory || process.cwd();
273
263
  const toolCallId = context.toolCallId ||
274
264
  "perm-" + Math.random().toString(36).substring(2, 9);
265
+ let effectiveName = context.toolName;
266
+ let effectiveCompactParams = undefined;
267
+ if (agent?.messages && context.toolCallId) {
268
+ const toolBlock = agent.messages
269
+ .flatMap((m) => m.blocks)
270
+ .find((b) => b.type === "tool" && b.id === context.toolCallId);
271
+ if (toolBlock) {
272
+ effectiveName = toolBlock.name || effectiveName;
273
+ effectiveCompactParams =
274
+ toolBlock.compactParams || effectiveCompactParams;
275
+ }
276
+ }
277
+ const displayTitle = effectiveName && effectiveCompactParams
278
+ ? `${effectiveName}: ${effectiveCompactParams}`
279
+ : effectiveName || "Tool Call";
275
280
  const options = [
276
281
  {
277
282
  optionId: "allow_once",
@@ -288,11 +293,6 @@ export class WaveAcpAgent {
288
293
  name: "Reject Once",
289
294
  kind: "reject_once",
290
295
  },
291
- {
292
- optionId: "reject_always",
293
- name: "Reject Always",
294
- kind: "reject_always",
295
- },
296
296
  ];
297
297
  const content = context.toolName
298
298
  ? await this.getToolContentAsync(context.toolName, context.toolInput, workdir)
@@ -308,7 +308,7 @@ export class WaveAcpAgent {
308
308
  sessionId: sessionId,
309
309
  toolCall: {
310
310
  toolCallId,
311
- title: `Permission for ${context.toolName}`,
311
+ title: displayTitle,
312
312
  status: "pending",
313
313
  rawInput: context.toolInput,
314
314
  content,
@@ -323,21 +323,15 @@ export class WaveAcpAgent {
323
323
  const selectedOptionId = response.outcome.optionId;
324
324
  logger.info(`User selected permission option: ${selectedOptionId}`);
325
325
  switch (selectedOptionId) {
326
- case "allow_once":
327
- return { behavior: "allow" };
328
326
  case "allow_always":
329
327
  return {
330
328
  behavior: "allow",
331
329
  newPermissionRule: `${context.toolName}(*)`,
332
330
  };
331
+ case "allow_once":
332
+ return { behavior: "allow" };
333
333
  case "reject_once":
334
334
  return { behavior: "deny", message: "Rejected by user" };
335
- case "reject_always":
336
- return {
337
- behavior: "deny",
338
- message: "Rejected by user",
339
- newPermissionRule: `!${context.toolName}(*)`,
340
- };
341
335
  default:
342
336
  return { behavior: "deny", message: "Unknown option selected" };
343
337
  }
@@ -356,7 +350,8 @@ export class WaveAcpAgent {
356
350
  if (name === "Write") {
357
351
  let oldText = null;
358
352
  try {
359
- const filePath = parameters.file_path;
353
+ const filePath = (parameters.file_path ||
354
+ parameters.filePath);
360
355
  const fullPath = path.isAbsolute(filePath)
361
356
  ? filePath
362
357
  : path.join(workdir, filePath);
@@ -368,7 +363,7 @@ export class WaveAcpAgent {
368
363
  return [
369
364
  {
370
365
  type: "diff",
371
- path: parameters.file_path,
366
+ path: (parameters.file_path || parameters.filePath),
372
367
  oldText,
373
368
  newText: parameters.content,
374
369
  },
@@ -378,7 +373,8 @@ export class WaveAcpAgent {
378
373
  let oldText = null;
379
374
  let newText = null;
380
375
  try {
381
- const filePath = parameters.file_path;
376
+ const filePath = (parameters.file_path ||
377
+ parameters.filePath);
382
378
  const fullPath = path.isAbsolute(filePath)
383
379
  ? filePath
384
380
  : path.join(workdir, filePath);
@@ -401,7 +397,7 @@ export class WaveAcpAgent {
401
397
  return [
402
398
  {
403
399
  type: "diff",
404
- path: parameters.file_path,
400
+ path: (parameters.file_path || parameters.filePath),
405
401
  oldText,
406
402
  newText,
407
403
  },
@@ -411,49 +407,68 @@ export class WaveAcpAgent {
411
407
  return [
412
408
  {
413
409
  type: "diff",
414
- path: parameters.file_path,
410
+ path: (parameters.file_path || parameters.filePath),
415
411
  oldText: parameters.old_string,
416
412
  newText: parameters.new_string,
417
413
  },
418
414
  ];
419
415
  }
420
- return this.getToolContent(name, parameters);
416
+ return this.getToolContent(name, parameters, undefined);
421
417
  }
422
- getToolContent(name, parameters) {
423
- if (!parameters)
424
- return undefined;
425
- if (name === "Write") {
426
- return [
427
- {
418
+ getToolContent(name, parameters, shortResult) {
419
+ const contents = [];
420
+ if (parameters) {
421
+ if (name === "Write") {
422
+ contents.push({
428
423
  type: "diff",
429
- path: parameters.file_path,
424
+ path: (parameters.file_path || parameters.filePath),
430
425
  oldText: null,
431
426
  newText: parameters.content,
432
- },
433
- ];
434
- }
435
- if (name === "Edit") {
436
- return [
437
- {
427
+ });
428
+ }
429
+ else if (name === "Edit") {
430
+ contents.push({
438
431
  type: "diff",
439
- path: parameters.file_path,
432
+ path: (parameters.file_path || parameters.filePath),
440
433
  oldText: parameters.old_string,
441
434
  newText: parameters.new_string,
435
+ });
436
+ }
437
+ }
438
+ if (shortResult) {
439
+ contents.push({
440
+ type: "content",
441
+ content: {
442
+ type: "text",
443
+ text: shortResult,
442
444
  },
443
- ];
445
+ });
444
446
  }
445
- return undefined;
447
+ return contents.length > 0 ? contents : undefined;
446
448
  }
447
- getToolLocations(name, parameters) {
449
+ getToolLocations(name, parameters, extraStartLineNumber) {
448
450
  if (!parameters)
449
451
  return undefined;
450
- if (name === "Write" || name === "Edit" || name === "Read") {
451
- return [
452
- {
453
- path: parameters.file_path,
454
- line: parameters.offset,
455
- },
456
- ];
452
+ if (name === "Write" ||
453
+ name === "Edit" ||
454
+ name === "Read" ||
455
+ name === "LSP") {
456
+ const filePath = (parameters.file_path || parameters.filePath);
457
+ let line = extraStartLineNumber ??
458
+ parameters.startLineNumber ??
459
+ parameters.line ??
460
+ parameters.offset;
461
+ if (name === "Write" && line === undefined) {
462
+ line = 1;
463
+ }
464
+ if (filePath) {
465
+ return [
466
+ {
467
+ path: filePath,
468
+ line: line,
469
+ },
470
+ ];
471
+ }
457
472
  }
458
473
  return undefined;
459
474
  }
@@ -477,6 +492,7 @@ export class WaveAcpAgent {
477
492
  }
478
493
  createCallbacks(sessionId) {
479
494
  const getAgent = () => this.agents.get(sessionId);
495
+ const toolStates = new Map();
480
496
  return {
481
497
  onAssistantContentUpdated: (chunk) => {
482
498
  this.connection.sessionUpdate({
@@ -503,7 +519,29 @@ export class WaveAcpAgent {
503
519
  });
504
520
  },
505
521
  onToolBlockUpdated: (params) => {
506
- const { id, name, stage, success, error, result, parameters } = params;
522
+ const { id, name, stage, success, error, result, parameters, compactParams, shortResult, startLineNumber, } = params;
523
+ let state = toolStates.get(id);
524
+ if (!state) {
525
+ state = {};
526
+ toolStates.set(id, state);
527
+ }
528
+ if (name)
529
+ state.name = name;
530
+ if (compactParams)
531
+ state.compactParams = compactParams;
532
+ if (shortResult)
533
+ state.shortResult = shortResult;
534
+ if (startLineNumber !== undefined)
535
+ state.startLineNumber = startLineNumber;
536
+ const effectiveName = state.name || name;
537
+ const effectiveCompactParams = state.compactParams || compactParams;
538
+ const effectiveShortResult = state.shortResult || shortResult;
539
+ const effectiveStartLineNumber = state.startLineNumber !== undefined
540
+ ? state.startLineNumber
541
+ : startLineNumber;
542
+ const displayTitle = effectiveName && effectiveCompactParams
543
+ ? `${effectiveName}: ${effectiveCompactParams}`
544
+ : effectiveName || "Tool Call";
507
545
  let parsedParameters = undefined;
508
546
  if (parameters) {
509
547
  try {
@@ -513,20 +551,22 @@ export class WaveAcpAgent {
513
551
  // Ignore parse errors during streaming
514
552
  }
515
553
  }
516
- const content = name && parsedParameters
517
- ? this.getToolContent(name, parsedParameters)
554
+ const content = effectiveName && (parsedParameters || effectiveShortResult)
555
+ ? this.getToolContent(effectiveName, parsedParameters, effectiveShortResult)
518
556
  : undefined;
519
- const locations = name && parsedParameters
520
- ? this.getToolLocations(name, parsedParameters)
557
+ const locations = effectiveName && parsedParameters
558
+ ? this.getToolLocations(effectiveName, parsedParameters, effectiveStartLineNumber)
559
+ : undefined;
560
+ const kind = effectiveName
561
+ ? this.getToolKind(effectiveName)
521
562
  : undefined;
522
- const kind = name ? this.getToolKind(name) : undefined;
523
563
  if (stage === "start") {
524
564
  this.connection.sessionUpdate({
525
565
  sessionId: sessionId,
526
566
  update: {
527
567
  sessionUpdate: "tool_call",
528
568
  toolCallId: id,
529
- title: name || "Tool Call",
569
+ title: displayTitle,
530
570
  status: "pending",
531
571
  content,
532
572
  locations,
@@ -553,7 +593,7 @@ export class WaveAcpAgent {
553
593
  sessionUpdate: "tool_call_update",
554
594
  toolCallId: id,
555
595
  status,
556
- title: name || "Tool Call",
596
+ title: displayTitle,
557
597
  rawOutput: result || error,
558
598
  content,
559
599
  locations,
@@ -561,6 +601,9 @@ export class WaveAcpAgent {
561
601
  rawInput: parsedParameters,
562
602
  },
563
603
  });
604
+ if (stage === "end") {
605
+ toolStates.delete(id);
606
+ }
564
607
  },
565
608
  onTasksChange: (tasks) => {
566
609
  this.connection.sessionUpdate({
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA0DjE"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA4DjE"}
package/dist/cli.js CHANGED
@@ -4,7 +4,7 @@ import { App } from "./components/App.js";
4
4
  import { cleanupLogs } from "./utils/logger.js";
5
5
  import { removeWorktree } from "./utils/worktree.js";
6
6
  export async function startCli(options) {
7
- const { restoreSessionId, continueLastSession, bypassPermissions, pluginDirs, tools, worktreeSession, workdir, version, model, } = options;
7
+ const { restoreSessionId, continueLastSession, bypassPermissions, permissionMode, pluginDirs, tools, worktreeSession, workdir, version, model, } = options;
8
8
  // Continue with ink-based UI for normal mode
9
9
  let shouldRemoveWorktree = false;
10
10
  const handleExit = (shouldRemove) => {
@@ -12,7 +12,7 @@ export async function startCli(options) {
12
12
  unmount();
13
13
  };
14
14
  // Render the application
15
- const { unmount, waitUntilExit } = render(_jsx(App, { restoreSessionId: restoreSessionId, continueLastSession: continueLastSession, bypassPermissions: bypassPermissions, pluginDirs: pluginDirs, tools: tools, worktreeSession: worktreeSession, workdir: workdir, version: version, model: model, onExit: handleExit }), { exitOnCtrlC: false });
15
+ const { unmount, waitUntilExit } = render(_jsx(App, { restoreSessionId: restoreSessionId, continueLastSession: continueLastSession, bypassPermissions: bypassPermissions, permissionMode: permissionMode, pluginDirs: pluginDirs, tools: tools, worktreeSession: worktreeSession, workdir: workdir, version: version, model: model, onExit: handleExit }), { exitOnCtrlC: false });
16
16
  // Wait for the app to finish unmounting
17
17
  await waitUntilExit();
18
18
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAWxE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,UAAU,QAAS,SAAQ,YAAY;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,MAAM,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;CACzC;AA0ID,eAAO,MAAM,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CA6BlC,CAAC"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAWxE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,UAAU,QAAS,SAAQ,YAAY;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,MAAM,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;CACzC;AA4ID,eAAO,MAAM,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CA+BlC,CAAC"}
@@ -6,7 +6,7 @@ import { ChatProvider, useChat } from "../contexts/useChat.js";
6
6
  import { AppProvider } from "../contexts/useAppConfig.js";
7
7
  import { WorktreeExitPrompt } from "./WorktreeExitPrompt.js";
8
8
  import { hasUncommittedChanges, hasNewCommits, getDefaultRemoteBranch, } from "wave-agent-sdk";
9
- const AppWithProviders = ({ bypassPermissions, pluginDirs, tools, worktreeSession, workdir, version, model, onExit, }) => {
9
+ const AppWithProviders = ({ bypassPermissions, permissionMode, pluginDirs, tools, worktreeSession, workdir, version, model, onExit, }) => {
10
10
  const [isExiting, setIsExiting] = useState(false);
11
11
  const [worktreeStatus, setWorktreeStatus] = useState(null);
12
12
  const handleSignal = useCallback(async () => {
@@ -48,7 +48,7 @@ const AppWithProviders = ({ bypassPermissions, pluginDirs, tools, worktreeSessio
48
48
  if (isExiting && worktreeSession && worktreeStatus) {
49
49
  return (_jsx(WorktreeExitPrompt, { name: worktreeSession.name, path: worktreeSession.path, hasUncommittedChanges: worktreeStatus.hasUncommittedChanges, hasNewCommits: worktreeStatus.hasNewCommits, onKeep: () => onExit(false), onRemove: () => onExit(true), onCancel: () => setIsExiting(false) }));
50
50
  }
51
- return (_jsx(ChatProvider, { bypassPermissions: bypassPermissions, pluginDirs: pluginDirs, tools: tools, workdir: workdir, worktreeSession: worktreeSession, version: version, model: model, children: _jsx(ChatInterfaceWithRemount, {}) }));
51
+ return (_jsx(ChatProvider, { bypassPermissions: bypassPermissions, permissionMode: permissionMode, pluginDirs: pluginDirs, tools: tools, workdir: workdir, worktreeSession: worktreeSession, version: version, model: model, children: _jsx(ChatInterfaceWithRemount, {}) }));
52
52
  };
53
53
  const ChatInterfaceWithRemount = () => {
54
54
  const { stdout } = useStdout();
@@ -86,6 +86,6 @@ const ChatInterfaceWithRemount = () => {
86
86
  ]);
87
87
  return _jsx(ChatInterface, {}, remountKey);
88
88
  };
89
- export const App = ({ restoreSessionId, continueLastSession, bypassPermissions, pluginDirs, tools, worktreeSession, workdir, version, model, onExit, }) => {
90
- return (_jsx(AppProvider, { restoreSessionId: restoreSessionId, continueLastSession: continueLastSession, children: _jsx(AppWithProviders, { bypassPermissions: bypassPermissions, pluginDirs: pluginDirs, tools: tools, worktreeSession: worktreeSession, workdir: workdir, version: version, model: model, onExit: onExit }) }));
89
+ export const App = ({ restoreSessionId, continueLastSession, bypassPermissions, permissionMode, pluginDirs, tools, worktreeSession, workdir, version, model, onExit, }) => {
90
+ return (_jsx(AppProvider, { restoreSessionId: restoreSessionId, continueLastSession: continueLastSession, children: _jsx(AppWithProviders, { bypassPermissions: bypassPermissions, permissionMode: permissionMode, pluginDirs: pluginDirs, tools: tools, worktreeSession: worktreeSession, workdir: workdir, version: version, model: model, onExit: onExit }) }));
91
91
  };
@@ -1 +1 @@
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
+ {"version":3,"file":"DiffDisplay.d.ts","sourceRoot":"","sources":["../../src/components/DiffDisplay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAYvC,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,CA6WlD,CAAC"}
@@ -1,9 +1,11 @@
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 } from "wave-agent-sdk";
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";
7
9
  export const DiffDisplay = ({ toolName, parameters, startLineNumber, }) => {
8
10
  const showDiff = toolName && [WRITE_TOOL_NAME, EDIT_TOOL_NAME].includes(toolName);
9
11
  // Diff detection and transformation using typed parameters
@@ -53,6 +55,23 @@ export const DiffDisplay = ({ toolName, parameters, startLineNumber, }) => {
53
55
  };
54
56
  }
55
57
  };
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
+ };
56
75
  // Render expanded diff display
57
76
  const renderExpandedDiff = () => {
58
77
  try {
@@ -197,5 +216,7 @@ export const DiffDisplay = ({ toolName, parameters, startLineNumber, }) => {
197
216
  if (!showDiff) {
198
217
  return null;
199
218
  }
200
- return (_jsx(Box, { flexDirection: "column", children: _jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "cyan", flexDirection: "column", children: renderExpandedDiff() }) }));
219
+ return (_jsx(Box, { flexDirection: "column", children: _jsx(Box, { paddingLeft: 2, borderLeft: true, borderColor: "cyan", flexDirection: "column", children: toolName === WRITE_TOOL_NAME
220
+ ? renderWriteContent()
221
+ : renderExpandedDiff() }) }));
201
222
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useChat.d.ts","sourceRoot":"","sources":["../../src/contexts/useChat.tsx"],"names":[],"mappings":"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"}
@@ -13,7 +13,7 @@ export const useChat = () => {
13
13
  }
14
14
  return context;
15
15
  };
16
- export const ChatProvider = ({ children, bypassPermissions, pluginDirs, tools, workdir, worktreeSession, version, model, }) => {
16
+ export const ChatProvider = ({ children, bypassPermissions, permissionMode: initialPermissionMode, pluginDirs, tools, workdir, worktreeSession, version, model, }) => {
17
17
  const { restoreSessionId, continueLastSession } = useAppConfig();
18
18
  // Message Display State
19
19
  const [isExpanded, setIsExpanded] = useState(false);
@@ -42,7 +42,8 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, tools, w
42
42
  const [subagentMessages, setSubagentMessages] = useState({});
43
43
  const [subagentLatestTokens, setSubagentLatestTokens] = useState({});
44
44
  // Permission state
45
- const [permissionMode, setPermissionModeState] = useState("default");
45
+ const [permissionMode, setPermissionModeState] = useState(initialPermissionMode ||
46
+ (bypassPermissions ? "bypassPermissions" : "default"));
46
47
  // Confirmation state with queue-based architecture
47
48
  const [isConfirmationVisible, setIsConfirmationVisible] = useState(false);
48
49
  const [confirmingTool, setConfirmingTool] = useState();
@@ -55,6 +56,16 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, tools, w
55
56
  // Confirmation too tall state
56
57
  const [wasLastDetailsTooTall, setWasLastDetailsTooTall] = useState(0);
57
58
  const agentRef = useRef(null);
59
+ const taskUpdateTimerRef = useRef(null);
60
+ const debouncedSetTasks = useCallback((newTasks) => {
61
+ if (taskUpdateTimerRef.current) {
62
+ clearTimeout(taskUpdateTimerRef.current);
63
+ }
64
+ taskUpdateTimerRef.current = setTimeout(() => {
65
+ setTasks([...newTasks]);
66
+ taskUpdateTimerRef.current = null;
67
+ }, 100);
68
+ }, [setTasks]);
58
69
  // Permission confirmation methods with queue support
59
70
  const showConfirmation = useCallback(async (toolName, toolInput, suggestedPrefix, hidePersistentOption) => {
60
71
  return new Promise((resolve, reject) => {
@@ -95,7 +106,7 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, tools, w
95
106
  setBackgroundTasks([...tasks]);
96
107
  },
97
108
  onTasksChange: (tasks) => {
98
- setTasks([...tasks]);
109
+ debouncedSetTasks(tasks);
99
110
  },
100
111
  onSubagentMessagesChange: (subagentId, messages) => {
101
112
  logger.debug("onSubagentMessagesChange", subagentId, messages.length);
@@ -135,7 +146,8 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, tools, w
135
146
  restoreSessionId,
136
147
  continueLastSession,
137
148
  logger,
138
- permissionMode: bypassPermissions ? "bypassPermissions" : undefined,
149
+ permissionMode: initialPermissionMode ||
150
+ (bypassPermissions ? "bypassPermissions" : undefined),
139
151
  canUseTool: permissionCallback,
140
152
  stream: false, // 关闭流式模式
141
153
  plugins: pluginDirs?.map((path) => ({ type: "local", path })),
@@ -177,10 +189,15 @@ export const ChatProvider = ({ children, bypassPermissions, pluginDirs, tools, w
177
189
  workdir,
178
190
  worktreeSession,
179
191
  model,
192
+ debouncedSetTasks,
193
+ initialPermissionMode,
180
194
  ]);
181
195
  // Cleanup on unmount
182
196
  useEffect(() => {
183
197
  return () => {
198
+ if (taskUpdateTimerRef.current) {
199
+ clearTimeout(taskUpdateTimerRef.current);
200
+ }
184
201
  if (agentRef.current) {
185
202
  try {
186
203
  // Display usage summary before cleanup
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,wBAAsB,IAAI,kBAkTzB;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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,wBAAsB,IAAI,kBAiUzB;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
@@ -49,6 +49,18 @@ export async function main() {
49
49
  type: "boolean",
50
50
  default: false,
51
51
  global: false,
52
+ })
53
+ .option("permission-mode", {
54
+ description: "Permission mode to use for the session",
55
+ choices: [
56
+ "acceptEdits",
57
+ "bypassPermissions",
58
+ "default",
59
+ "dontAsk",
60
+ "plan",
61
+ ],
62
+ type: "string",
63
+ global: false,
52
64
  })
53
65
  .option("plugin-dir", {
54
66
  description: "Load a plugin from a specific directory",
@@ -194,6 +206,7 @@ export async function main() {
194
206
  return startCli({
195
207
  restoreSessionId: selectedSessionId,
196
208
  bypassPermissions: argv.dangerouslySkipPermissions,
209
+ permissionMode: argv.permissionMode,
197
210
  pluginDirs,
198
211
  tools,
199
212
  worktreeSession,
@@ -211,6 +224,7 @@ export async function main() {
211
224
  message: argv.print,
212
225
  showStats: argv.showStats,
213
226
  bypassPermissions: argv.dangerouslySkipPermissions,
227
+ permissionMode: argv.permissionMode,
214
228
  pluginDirs,
215
229
  tools,
216
230
  worktreeSession,
@@ -223,6 +237,7 @@ export async function main() {
223
237
  restoreSessionId: argv.restore,
224
238
  continueLastSession: argv.continue,
225
239
  bypassPermissions: argv.dangerouslySkipPermissions,
240
+ permissionMode: argv.permissionMode,
226
241
  pluginDirs,
227
242
  tools,
228
243
  worktreeSession,
@@ -1 +1 @@
1
- {"version":3,"file":"print-cli.d.ts","sourceRoot":"","sources":["../src/print-cli.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAgBD,wBAAsB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAsM3E"}
1
+ {"version":3,"file":"print-cli.d.ts","sourceRoot":"","sources":["../src/print-cli.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAgBD,wBAAsB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAwM3E"}