wave-agent-sdk 0.12.10 → 0.13.0

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.
Files changed (59) hide show
  1. package/dist/constants/tools.d.ts +1 -0
  2. package/dist/constants/tools.d.ts.map +1 -1
  3. package/dist/constants/tools.js +1 -0
  4. package/dist/managers/aiManager.d.ts.map +1 -1
  5. package/dist/managers/aiManager.js +5 -3
  6. package/dist/managers/mcpManager.d.ts +9 -0
  7. package/dist/managers/mcpManager.d.ts.map +1 -1
  8. package/dist/managers/mcpManager.js +46 -1
  9. package/dist/managers/messageManager.d.ts +10 -0
  10. package/dist/managers/messageManager.d.ts.map +1 -1
  11. package/dist/managers/messageManager.js +39 -0
  12. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  13. package/dist/managers/slashCommandManager.js +15 -9
  14. package/dist/managers/subagentManager.d.ts.map +1 -1
  15. package/dist/managers/subagentManager.js +4 -2
  16. package/dist/managers/toolManager.d.ts.map +1 -1
  17. package/dist/managers/toolManager.js +9 -1
  18. package/dist/services/MarketplaceService.d.ts +6 -1
  19. package/dist/services/MarketplaceService.d.ts.map +1 -1
  20. package/dist/services/MarketplaceService.js +34 -1
  21. package/dist/services/configurationService.d.ts +1 -5
  22. package/dist/services/configurationService.d.ts.map +1 -1
  23. package/dist/services/configurationService.js +21 -21
  24. package/dist/services/initializationService.d.ts.map +1 -1
  25. package/dist/services/initializationService.js +1 -1
  26. package/dist/services/interactionService.d.ts.map +1 -1
  27. package/dist/services/interactionService.js +2 -2
  28. package/dist/tools/enterPlanMode.d.ts +6 -0
  29. package/dist/tools/enterPlanMode.d.ts.map +1 -0
  30. package/dist/tools/enterPlanMode.js +87 -0
  31. package/dist/types/messaging.d.ts +4 -1
  32. package/dist/types/messaging.d.ts.map +1 -1
  33. package/dist/types/permissions.d.ts +1 -1
  34. package/dist/types/permissions.d.ts.map +1 -1
  35. package/dist/types/permissions.js +2 -1
  36. package/dist/utils/containerSetup.js +2 -4
  37. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  38. package/dist/utils/convertMessagesForAPI.js +2 -1
  39. package/dist/utils/messageOperations.d.ts +2 -1
  40. package/dist/utils/messageOperations.d.ts.map +1 -1
  41. package/dist/utils/messageOperations.js +14 -6
  42. package/package.json +1 -1
  43. package/src/constants/tools.ts +1 -0
  44. package/src/managers/aiManager.ts +12 -3
  45. package/src/managers/mcpManager.ts +56 -1
  46. package/src/managers/messageManager.ts +43 -0
  47. package/src/managers/slashCommandManager.ts +17 -10
  48. package/src/managers/subagentManager.ts +4 -2
  49. package/src/managers/toolManager.ts +13 -1
  50. package/src/services/MarketplaceService.ts +33 -1
  51. package/src/services/configurationService.ts +21 -22
  52. package/src/services/initializationService.ts +3 -1
  53. package/src/services/interactionService.ts +3 -2
  54. package/src/tools/enterPlanMode.ts +107 -0
  55. package/src/types/messaging.ts +4 -1
  56. package/src/types/permissions.ts +2 -0
  57. package/src/utils/containerSetup.ts +4 -4
  58. package/src/utils/convertMessagesForAPI.ts +2 -1
  59. package/src/utils/messageOperations.ts +15 -5
@@ -7,6 +7,7 @@
7
7
  import { readFileSync, existsSync, promises as fs } from "fs";
8
8
  import * as path from "path";
9
9
  import { isValidHookEvent } from "../types/hooks.js";
10
+ import { logger } from "../utils/globalLogger.js";
10
11
  import { getAllConfigPaths, getExistingConfigPaths, getUserConfigPaths, getProjectConfigPaths, } from "../utils/configPaths.js";
11
12
  import { isValidEnvironmentVars, } from "../types/environment.js";
12
13
  import { ConfigurationError, CONFIG_ERRORS, } from "../types/index.js";
@@ -21,8 +22,8 @@ import { parseCustomHeaders } from "../utils/stringUtils.js";
21
22
  export class ConfigurationService {
22
23
  constructor() {
23
24
  this.currentConfiguration = null;
24
- this.env = {};
25
25
  this.options = {};
26
+ this._configuredEnvKeys = new Set();
26
27
  }
27
28
  /**
28
29
  * Set agent options for configuration resolution
@@ -273,13 +274,13 @@ export class ConfigurationService {
273
274
  * This replaces direct process.env modification
274
275
  */
275
276
  setEnvironmentVars(env) {
276
- this.env = { ...env };
277
- }
278
- /**
279
- * Get current environment variables
280
- */
281
- getEnvironmentVars() {
282
- return { ...this.env };
277
+ for (const [key, value] of Object.entries(env)) {
278
+ if (process.env[key] !== undefined && !this._configuredEnvKeys.has(key)) {
279
+ logger.warn(`Overriding environment variable: ${key}`);
280
+ }
281
+ process.env[key] = value;
282
+ this._configuredEnvKeys.add(key);
283
+ }
283
284
  }
284
285
  // =============================================================================
285
286
  // Configuration Resolution Methods (merged from configResolver.ts)
@@ -306,7 +307,7 @@ export class ConfigurationService {
306
307
  resolvedApiKey = this.options.apiKey;
307
308
  }
308
309
  else {
309
- resolvedApiKey = this.env.WAVE_API_KEY;
310
+ resolvedApiKey = process.env.WAVE_API_KEY;
310
311
  }
311
312
  // Resolve base URL: override > options > env (settings.json) > process.env
312
313
  // Note: Explicitly provided empty strings should be treated as invalid, not fall back to env
@@ -318,7 +319,7 @@ export class ConfigurationService {
318
319
  resolvedBaseURL = this.options.baseURL;
319
320
  }
320
321
  else {
321
- resolvedBaseURL = this.env.WAVE_BASE_URL || "";
322
+ resolvedBaseURL = process.env.WAVE_BASE_URL || "";
322
323
  }
323
324
  // Fallback to process.env if still not resolved (for dynamic updates in tests)
324
325
  if (resolvedApiKey === undefined) {
@@ -331,14 +332,14 @@ export class ConfigurationService {
331
332
  throw new ConfigurationError(CONFIG_ERRORS.MISSING_BASE_URL, "baseURL", {
332
333
  constructor: baseURL,
333
334
  environment: process.env.WAVE_BASE_URL,
334
- settings: this.env.WAVE_BASE_URL,
335
+ settings: process.env.WAVE_BASE_URL,
335
336
  });
336
337
  }
337
338
  if (resolvedBaseURL.trim() === "") {
338
339
  throw new ConfigurationError(CONFIG_ERRORS.EMPTY_BASE_URL, "baseURL", resolvedBaseURL);
339
340
  }
340
341
  // Resolve custom headers from environment: env (settings.json) > process.env
341
- const envCustomHeaders = this.env.WAVE_CUSTOM_HEADERS || process.env.WAVE_CUSTOM_HEADERS || "";
342
+ const envCustomHeaders = process.env.WAVE_CUSTOM_HEADERS || process.env.WAVE_CUSTOM_HEADERS || "";
342
343
  const parsedEnvHeaders = parseCustomHeaders(envCustomHeaders);
343
344
  // Merge headers: env headers < options < override
344
345
  const resolvedHeaders = {
@@ -367,26 +368,24 @@ export class ConfigurationService {
367
368
  // Resolve agent model: override > options > env (settings.json) > process.env
368
369
  const resolvedAgentModel = model ||
369
370
  this.options.model ||
370
- this.env.WAVE_MODEL ||
371
+ process.env.WAVE_MODEL ||
371
372
  process.env.WAVE_MODEL;
372
373
  // Resolve fast model: override > options > env (settings.json) > process.env
373
374
  const resolvedFastModel = fastModel ||
374
375
  this.options.fastModel ||
375
- this.env.WAVE_FAST_MODEL ||
376
+ process.env.WAVE_FAST_MODEL ||
376
377
  process.env.WAVE_FAST_MODEL;
377
378
  // Validate required fields
378
379
  if (!resolvedAgentModel) {
379
380
  throw new ConfigurationError(CONFIG_ERRORS.MISSING_MODEL, "model", {
380
381
  constructor: model,
381
382
  environment: process.env.WAVE_MODEL,
382
- settings: this.env.WAVE_MODEL,
383
383
  });
384
384
  }
385
385
  if (!resolvedFastModel) {
386
386
  throw new ConfigurationError(CONFIG_ERRORS.MISSING_FAST_MODEL, "fastModel", {
387
387
  constructor: fastModel,
388
388
  environment: process.env.WAVE_FAST_MODEL,
389
- settings: this.env.WAVE_FAST_MODEL,
390
389
  });
391
390
  }
392
391
  // Resolve max output tokens
@@ -423,7 +422,7 @@ export class ConfigurationService {
423
422
  return this.options.maxInputTokens;
424
423
  }
425
424
  // Try env (settings.json) first, then process.env
426
- const envMaxInputTokens = this.env.WAVE_MAX_INPUT_TOKENS || process.env.WAVE_MAX_INPUT_TOKENS;
425
+ const envMaxInputTokens = process.env.WAVE_MAX_INPUT_TOKENS || process.env.WAVE_MAX_INPUT_TOKENS;
427
426
  if (envMaxInputTokens) {
428
427
  const parsed = parseInt(envMaxInputTokens, 10);
429
428
  if (!isNaN(parsed)) {
@@ -465,7 +464,8 @@ export class ConfigurationService {
465
464
  return this.currentConfiguration.autoMemoryEnabled;
466
465
  }
467
466
  // 2. WAVE_DISABLE_AUTO_MEMORY environment variable
468
- const disableAutoMemory = this.env.WAVE_DISABLE_AUTO_MEMORY || process.env.WAVE_DISABLE_AUTO_MEMORY;
467
+ const disableAutoMemory = process.env.WAVE_DISABLE_AUTO_MEMORY ||
468
+ process.env.WAVE_DISABLE_AUTO_MEMORY;
469
469
  if (disableAutoMemory === "1" || disableAutoMemory === "true") {
470
470
  return false;
471
471
  }
@@ -483,7 +483,7 @@ export class ConfigurationService {
483
483
  return this.currentConfiguration.autoMemoryFrequency;
484
484
  }
485
485
  // 2. WAVE_AUTO_MEMORY_FREQUENCY environment variable
486
- const envFrequency = this.env.WAVE_AUTO_MEMORY_FREQUENCY ||
486
+ const envFrequency = process.env.WAVE_AUTO_MEMORY_FREQUENCY ||
487
487
  process.env.WAVE_AUTO_MEMORY_FREQUENCY;
488
488
  if (envFrequency) {
489
489
  const parsed = parseInt(envFrequency, 10);
@@ -510,7 +510,7 @@ export class ConfigurationService {
510
510
  return this.options.maxTokens;
511
511
  }
512
512
  // Try env (settings.json) first, then process.env
513
- const envMaxOutputTokens = this.env.WAVE_MAX_OUTPUT_TOKENS || process.env.WAVE_MAX_OUTPUT_TOKENS;
513
+ const envMaxOutputTokens = process.env.WAVE_MAX_OUTPUT_TOKENS || process.env.WAVE_MAX_OUTPUT_TOKENS;
514
514
  if (envMaxOutputTokens) {
515
515
  const parsed = parseInt(envMaxOutputTokens, 10);
516
516
  if (!isNaN(parsed) && parsed > 0) {
@@ -532,7 +532,7 @@ export class ConfigurationService {
532
532
  getConfiguredModels() {
533
533
  const models = new Set();
534
534
  // Add current model from options or environment
535
- const currentModel = this.options.model || this.env.WAVE_MODEL || process.env.WAVE_MODEL;
535
+ const currentModel = this.options.model || process.env.WAVE_MODEL || process.env.WAVE_MODEL;
536
536
  if (currentModel) {
537
537
  models.add(currentModel);
538
538
  }
@@ -1 +1 @@
1
- {"version":3,"file":"initializationService.d.ts","sourceRoot":"","sources":["../../src/services/initializationService.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,OAAO,EACP,MAAM,EACN,YAAY,EACZ,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpD,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,WAAW,CAAC;IACxB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,WAAW,EAAE,WAAW,CAAC;IACzB,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,WAAW,EAAE,WAAW,CAAC;IACzB,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,wBAAwB,EAAE,MAAM,IAAI,CAAC;CACtC;AAED,qBAAa,qBAAqB;WACZ,UAAU,CAC5B,OAAO,EAAE,qBAAqB,EAC9B,OAAO,CAAC,EAAE;QACR,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;KACtB,GACA,OAAO,CAAC,IAAI,CAAC;CAuRjB"}
1
+ {"version":3,"file":"initializationService.d.ts","sourceRoot":"","sources":["../../src/services/initializationService.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,OAAO,EACP,MAAM,EACN,YAAY,EACZ,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpD,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,WAAW,CAAC;IACxB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,WAAW,EAAE,WAAW,CAAC;IACzB,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,WAAW,EAAE,WAAW,CAAC;IACzB,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,wBAAwB,EAAE,MAAM,IAAI,CAAC;CACtC;AAED,qBAAa,qBAAqB;WACZ,UAAU,CAC5B,OAAO,EAAE,qBAAqB,EAC9B,OAAO,CAAC,EAAE;QACR,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;KACtB,GACA,OAAO,CAAC,IAAI,CAAC;CAyRjB"}
@@ -87,7 +87,7 @@ export class InitializationService {
87
87
  transcriptPath: messageManager.getTranscriptPath(),
88
88
  cwd: workdir,
89
89
  worktreeName: agentOptions.worktreeName,
90
- env: configurationService.getEnvironmentVars(),
90
+ env: Object.fromEntries(Object.entries(process.env).filter((e) => e[1] !== undefined)),
91
91
  });
92
92
  // Process hook results
93
93
  hookManager.processHookResults("WorktreeCreate", hookResults, messageManager);
@@ -1 +1 @@
1
- {"version":3,"file":"interactionService.d.ts","sourceRoot":"","sources":["../../src/services/interactionService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,cAAc,CAAC;IAC/B,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,eAAe,CAAC;IACjC,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,YAAY,CAAC;IACtB,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED,qBAAa,kBAAkB;WACT,WAAW,CAC7B,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,GACjD,OAAO,CAAC,IAAI,CAAC;WAyFI,cAAc,CAChC,OAAO,EAAE,kBAAkB,EAC3B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;CAiDjB"}
1
+ {"version":3,"file":"interactionService.d.ts","sourceRoot":"","sources":["../../src/services/interactionService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,cAAc,CAAC;IAC/B,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,SAAS,CAAC;IACrB,eAAe,EAAE,eAAe,CAAC;IACjC,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,YAAY,CAAC;IACtB,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED,qBAAa,kBAAkB;WACT,WAAW,CAC7B,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,GACjD,OAAO,CAAC,IAAI,CAAC;WA0FI,cAAc,CAChC,OAAO,EAAE,kBAAkB,EAC3B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;CAiDjB"}
@@ -1,7 +1,7 @@
1
1
  import { loadSessionFromJsonl } from "./session.js";
2
2
  export class InteractionService {
3
3
  static async sendMessage(context, content, images) {
4
- const { messageManager, slashCommandManager, hookManager, workdir, configurationService, logger, aiManager, } = context;
4
+ const { messageManager, slashCommandManager, hookManager, workdir, logger, aiManager, } = context;
5
5
  try {
6
6
  // Handle slash command - check if it's a slash command (starts with /)
7
7
  if (content.startsWith("/")) {
@@ -39,7 +39,7 @@ export class InteractionService {
39
39
  transcriptPath: messageManager.getTranscriptPath(),
40
40
  cwd: workdir,
41
41
  userPrompt: content,
42
- env: configurationService.getEnvironmentVars(), // Include configuration environment variables
42
+ env: Object.fromEntries(Object.entries(process.env).filter((e) => e[1] !== undefined)), // Include environment variables
43
43
  });
44
44
  // Process hook results and determine if we should continue
45
45
  const processResult = hookManager.processHookResults("UserPromptSubmit", hookResults, messageManager);
@@ -0,0 +1,6 @@
1
+ import type { ToolPlugin } from "./types.js";
2
+ /**
3
+ * Enter Plan Mode Tool Plugin
4
+ */
5
+ export declare const enterPlanModeTool: ToolPlugin;
6
+ //# sourceMappingURL=enterPlanMode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enterPlanMode.d.ts","sourceRoot":"","sources":["../../src/tools/enterPlanMode.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAItE;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,UAkG/B,CAAC"}
@@ -0,0 +1,87 @@
1
+ import { logger } from "../utils/globalLogger.js";
2
+ import { ENTER_PLAN_MODE_TOOL_NAME } from "../constants/tools.js";
3
+ import { OPERATION_CANCELLED_BY_USER } from "../types/permissions.js";
4
+ /**
5
+ * Enter Plan Mode Tool Plugin
6
+ */
7
+ export const enterPlanModeTool = {
8
+ name: ENTER_PLAN_MODE_TOOL_NAME,
9
+ config: {
10
+ type: "function",
11
+ function: {
12
+ name: ENTER_PLAN_MODE_TOOL_NAME,
13
+ description: "Request to enter plan mode for complex tasks requiring user approval before coding",
14
+ parameters: {
15
+ type: "object",
16
+ properties: {},
17
+ required: [],
18
+ additionalProperties: false,
19
+ },
20
+ },
21
+ },
22
+ prompt: () => `Use this tool to proactively request entering plan mode when a task is non-trivial and benefits from planning before implementation.
23
+
24
+ ## When to Use This Tool
25
+ - Multi-file changes or refactoring that requires architectural decisions
26
+ - New features with multiple implementation steps or design trade-offs
27
+ - Tasks where you want user approval on approach before writing code
28
+ - Complex bug fixes that span multiple components
29
+
30
+ ## When NOT to Use This Tool
31
+ - Simple fixes (typos, small logic changes in a single file)
32
+ - Research tasks (searching files, reading code, gathering information)
33
+ - Tasks where the implementation approach is straightforward and unambiguous
34
+ - When already in plan mode
35
+
36
+ ## Examples
37
+
38
+ 1. Task: "Refactor the authentication system to use OAuth2" - Use EnterPlanMode to propose an approach before implementation.
39
+ 2. Task: "Add input validation to the login form" - Do NOT use EnterPlanMode, just implement it.
40
+ 3. Task: "Migrate the database schema to support multi-tenancy" - Use EnterPlanMode to plan the migration steps.
41
+ 4. Task: "Fix the off-by-one error in the pagination logic" - Do NOT use EnterPlanMode, just fix the bug.
42
+ `,
43
+ execute: async (_args, context) => {
44
+ try {
45
+ if (!context.permissionManager) {
46
+ return {
47
+ success: false,
48
+ content: "",
49
+ error: "Permission manager is not available",
50
+ };
51
+ }
52
+ const permissionContext = context.permissionManager.createContext(ENTER_PLAN_MODE_TOOL_NAME, context.permissionMode || "default", context.canUseToolCallback, {}, context.toolCallId);
53
+ // No "allow always" option for plan mode transitions (matching Claude Code behavior)
54
+ permissionContext.hidePersistentOption = true;
55
+ const permissionResult = await context.permissionManager.checkPermission(permissionContext);
56
+ if (permissionResult.behavior === "deny") {
57
+ if (permissionResult.message === OPERATION_CANCELLED_BY_USER) {
58
+ return {
59
+ success: false,
60
+ content: OPERATION_CANCELLED_BY_USER,
61
+ };
62
+ }
63
+ return {
64
+ success: false,
65
+ content: `User declined to enter plan mode. Proceed in current mode.`,
66
+ error: permissionResult.message
67
+ ? undefined
68
+ : "Operation declined by user",
69
+ };
70
+ }
71
+ return {
72
+ success: true,
73
+ content: "Plan mode entered successfully. Please write your plan to the plan file and use ExitPlanMode when ready for approval.",
74
+ shortResult: "Plan mode entered",
75
+ };
76
+ }
77
+ catch (error) {
78
+ const errorMessage = error instanceof Error ? error.message : String(error);
79
+ logger.error(`EnterPlanMode tool error: ${errorMessage}`);
80
+ return {
81
+ success: false,
82
+ content: "",
83
+ error: errorMessage,
84
+ };
85
+ }
86
+ },
87
+ };
@@ -19,7 +19,9 @@ export type MessageBlock = TextBlock | ErrorBlock | ToolBlock | ImageBlock | Ban
19
19
  export interface TextBlock {
20
20
  type: "text";
21
21
  content: string;
22
+ customCommandContent?: string;
22
23
  source?: MessageSource;
24
+ stage?: "streaming" | "end";
23
25
  }
24
26
  export interface ErrorBlock {
25
27
  type: "error";
@@ -59,7 +61,7 @@ export interface BangBlock {
59
61
  type: "bang";
60
62
  command: string;
61
63
  output: string;
62
- isRunning: boolean;
64
+ stage: "running" | "end";
63
65
  exitCode: number | null;
64
66
  }
65
67
  export interface CompressBlock {
@@ -70,6 +72,7 @@ export interface CompressBlock {
70
72
  export interface ReasoningBlock {
71
73
  type: "reasoning";
72
74
  content: string;
75
+ stage?: "streaming" | "end";
73
76
  }
74
77
  export interface FileHistoryBlock {
75
78
  type: "file_history";
@@ -1 +1 @@
1
- {"version":3,"file":"messaging.d.ts","sourceRoot":"","sources":["../../src/types/messaging.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAEvC,oBAAY,aAAa;IACvB,IAAI,SAAS;IACb,IAAI,SAAS;CACd;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,UAAU,GACV,SAAS,GACT,UAAU,GACV,SAAS,GACT,aAAa,GACb,cAAc,GACd,gBAAgB,CAAC;AAErB,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC;QAEb,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,GAAG,KAAK,CAAC;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,OAAO,gBAAgB,EAAE,YAAY,EAAE,CAAC;CACpD"}
1
+ {"version":3,"file":"messaging.d.ts","sourceRoot":"","sources":["../../src/types/messaging.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAEvC,oBAAY,aAAa;IACvB,IAAI,SAAS;IACb,IAAI,SAAS;CACd;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,UAAU,GACV,SAAS,GACT,UAAU,GACV,SAAS,GACT,aAAa,GACb,cAAc,GACd,gBAAgB,CAAC;AAErB,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,KAAK,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC;QAEb,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,GAAG,KAAK,CAAC;IACjD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,GAAG,KAAK,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,OAAO,gBAAgB,EAAE,YAAY,EAAE,CAAC;CACpD"}
@@ -40,7 +40,7 @@ export interface ToolPermissionContext {
40
40
  planContent?: string;
41
41
  }
42
42
  /** List of tools that require permission checks in default mode */
43
- export declare const RESTRICTED_TOOLS: readonly ["Edit", "Bash", "Write", "ExitPlanMode", "AskUserQuestion"];
43
+ export declare const RESTRICTED_TOOLS: readonly ["Edit", "Bash", "Write", "EnterPlanMode", "ExitPlanMode", "AskUserQuestion"];
44
44
  /** Type for restricted tool names */
45
45
  export type RestrictedTool = (typeof RESTRICTED_TOOLS)[number];
46
46
  export declare const OPERATION_CANCELLED_BY_USER = "Operation cancelled by user";
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/types/permissions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AASpB,oCAAoC;AACpC,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,mBAAmB,GACnB,aAAa,GACb,MAAM,GACN,SAAS,CAAC;AAEd,mCAAmC;AACnC,MAAM,WAAW,kBAAkB;IACjC,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,cAAc,CAAC;IACnC,2CAA2C;IAC3C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,oDAAoD;AACpD,MAAM,MAAM,kBAAkB,GAAG,CAC/B,OAAO,EAAE,qBAAqB,KAC3B,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAEjC,mDAAmD;AACnD,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,cAAc,EAAE,cAAc,CAAC;IAC/B,6CAA6C;IAC7C,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,yCAAyC;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2FAA2F;IAC3F,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,uEAMnB,CAAC;AAEX,qCAAqC;AACrC,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AAEzE,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,CAAC"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/types/permissions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAUpB,oCAAoC;AACpC,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,mBAAmB,GACnB,aAAa,GACb,MAAM,GACN,SAAS,CAAC;AAEd,mCAAmC;AACnC,MAAM,WAAW,kBAAkB;IACjC,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,cAAc,CAAC;IACnC,2CAA2C;IAC3C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,oDAAoD;AACpD,MAAM,MAAM,kBAAkB,GAAG,CAC/B,OAAO,EAAE,qBAAqB,KAC3B,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAEjC,mDAAmD;AACnD,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,cAAc,EAAE,cAAc,CAAC;IAC/B,6CAA6C;IAC7C,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,yCAAyC;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2FAA2F;IAC3F,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,wFAOnB,CAAC;AAEX,qCAAqC;AACrC,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AAEzE,YAAY,EAAE,eAAe,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,CAAC"}
@@ -2,12 +2,13 @@
2
2
  * Permission system types for Wave Agent SDK
3
3
  * Dependencies: None
4
4
  */
5
- import { EDIT_TOOL_NAME, BASH_TOOL_NAME, WRITE_TOOL_NAME, EXIT_PLAN_MODE_TOOL_NAME, ASK_USER_QUESTION_TOOL_NAME, } from "../constants/tools.js";
5
+ import { EDIT_TOOL_NAME, BASH_TOOL_NAME, WRITE_TOOL_NAME, ENTER_PLAN_MODE_TOOL_NAME, EXIT_PLAN_MODE_TOOL_NAME, ASK_USER_QUESTION_TOOL_NAME, } from "../constants/tools.js";
6
6
  /** List of tools that require permission checks in default mode */
7
7
  export const RESTRICTED_TOOLS = [
8
8
  EDIT_TOOL_NAME,
9
9
  BASH_TOOL_NAME,
10
10
  WRITE_TOOL_NAME,
11
+ ENTER_PLAN_MODE_TOOL_NAME,
11
12
  EXIT_PLAN_MODE_TOOL_NAME,
12
13
  ASK_USER_QUESTION_TOOL_NAME,
13
14
  ];
@@ -59,9 +59,7 @@ export function setupAgentContainer(setupOptions) {
59
59
  workdir,
60
60
  });
61
61
  container.register("MessageManager", messageManager);
62
- const resolvedTaskListId = configurationService.getEnvironmentVars().WAVE_TASK_LIST_ID ||
63
- process.env.WAVE_TASK_LIST_ID ||
64
- messageManager.getRootSessionId();
62
+ const resolvedTaskListId = process.env.WAVE_TASK_LIST_ID || messageManager.getRootSessionId();
65
63
  const taskManager = new TaskManager(container, resolvedTaskListId);
66
64
  container.register("TaskManager", taskManager);
67
65
  taskManager.on("tasksChange", async () => {
@@ -126,7 +124,7 @@ export function setupAgentContainer(setupOptions) {
126
124
  cwd: workdir,
127
125
  toolName: context.toolName,
128
126
  toolInput: context.toolInput,
129
- env: configurationService.getEnvironmentVars(),
127
+ env: Object.fromEntries(Object.entries(process.env).filter((e) => e[1] !== undefined)),
130
128
  });
131
129
  if (results.length > 0) {
132
130
  const processResult = hookManager.processHookResults("PermissionRequest", results, messageManager);
@@ -1 +1 @@
1
- {"version":3,"file":"convertMessagesForAPI.d.ts","sourceRoot":"","sources":["../../src/utils/convertMessagesForAPI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIjD,OAAO,EAEL,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AA0B7B;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,OAAO,EAAE,GAClB,0BAA0B,EAAE,CA8N9B"}
1
+ {"version":3,"file":"convertMessagesForAPI.d.ts","sourceRoot":"","sources":["../../src/utils/convertMessagesForAPI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIjD,OAAO,EAEL,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AA0B7B;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,OAAO,EAAE,GAClB,0BAA0B,EAAE,CA+N9B"}
@@ -150,9 +150,10 @@ export function convertMessagesForAPI(messages) {
150
150
  if (block.type === "text" &&
151
151
  block.content &&
152
152
  block.content.trim().length > 0) {
153
+ const textForApi = block.customCommandContent ?? block.content;
153
154
  contentParts.push({
154
155
  type: "text",
155
- text: block.content,
156
+ text: textForApi,
156
157
  });
157
158
  }
158
159
  // If there is an image, add image content
@@ -3,6 +3,7 @@ import { MessageSource } from "../types/index.js";
3
3
  import { ChatCompletionMessageFunctionToolCall } from "openai/resources.js";
4
4
  export interface UserMessageParams {
5
5
  content: string;
6
+ customCommandContent?: string;
6
7
  images?: Array<{
7
8
  path: string;
8
9
  mimeType: string;
@@ -68,7 +69,7 @@ export interface CompleteBangParams {
68
69
  */
69
70
  export declare const convertImageToBase64: (imagePath: string) => string;
70
71
  export declare const generateMessageId: () => string;
71
- export declare const addUserMessageToMessages: ({ messages, content, images, source, id, isMeta, }: AddUserMessageParams) => Message[];
72
+ export declare const addUserMessageToMessages: ({ messages, content, customCommandContent, images, source, id, isMeta, }: AddUserMessageParams) => Message[];
72
73
  /**
73
74
  * Update a user message's content by its ID.
74
75
  */
@@ -1 +1 @@
1
- {"version":3,"file":"messageOperations.d.ts","sourceRoot":"","sources":["../../src/utils/messageOperations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"messageOperations.d.ts","sourceRoot":"","sources":["../../src/utils/messageOperations.ts"],"names":[],"mappings":"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"}
@@ -44,12 +44,13 @@ export const convertImageToBase64 = (imagePath) => {
44
44
  };
45
45
  export const generateMessageId = () => `msg-${randomUUID()}`;
46
46
  // Add user message
47
- export const addUserMessageToMessages = ({ messages, content, images, source, id, isMeta, }) => {
47
+ export const addUserMessageToMessages = ({ messages, content, customCommandContent, images, source, id, isMeta, }) => {
48
48
  const blocks = [];
49
- // Create text block with optional source
49
+ // Create text block with optional source and customCommandContent
50
50
  const textBlock = {
51
51
  type: "text",
52
52
  content,
53
+ ...(customCommandContent && { customCommandContent }),
53
54
  ...(source && { source }),
54
55
  };
55
56
  blocks.push(textBlock);
@@ -80,6 +81,9 @@ export const updateUserMessageInMessages = (messages, id, params) => {
80
81
  return {
81
82
  ...block,
82
83
  ...(params.content !== undefined && { content: params.content }),
84
+ ...(params.customCommandContent !== undefined && {
85
+ customCommandContent: params.customCommandContent,
86
+ }),
83
87
  ...(params.source !== undefined && { source: params.source }),
84
88
  };
85
89
  }
@@ -288,7 +292,7 @@ export const addBangMessage = ({ messages, command, }) => {
288
292
  type: "bang",
289
293
  command,
290
294
  output: "",
291
- isRunning: true,
295
+ stage: "running",
292
296
  exitCode: null,
293
297
  },
294
298
  ],
@@ -302,7 +306,9 @@ export const updateBangInMessage = ({ messages, command, output, }) => {
302
306
  for (let i = newMessages.length - 1; i >= 0; i--) {
303
307
  const msg = newMessages[i];
304
308
  if (msg.role === "user") {
305
- const commandBlock = msg.blocks.find((block) => block.type === "bang" && block.command === command && block.isRunning);
309
+ const commandBlock = msg.blocks.find((block) => block.type === "bang" &&
310
+ block.command === command &&
311
+ block.stage === "running");
306
312
  if (commandBlock && commandBlock.type === "bang") {
307
313
  commandBlock.output = output.trim();
308
314
  break;
@@ -318,9 +324,11 @@ export const completeBangInMessage = ({ messages, command, exitCode, output, })
318
324
  for (let i = newMessages.length - 1; i >= 0; i--) {
319
325
  const msg = newMessages[i];
320
326
  if (msg.role === "user") {
321
- const commandBlock = msg.blocks.find((block) => block.type === "bang" && block.command === command && block.isRunning);
327
+ const commandBlock = msg.blocks.find((block) => block.type === "bang" &&
328
+ block.command === command &&
329
+ block.stage === "running");
322
330
  if (commandBlock && commandBlock.type === "bang") {
323
- commandBlock.isRunning = false;
331
+ commandBlock.stage = "end";
324
332
  commandBlock.exitCode = exitCode;
325
333
  if (output !== undefined) {
326
334
  commandBlock.output = output.trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-agent-sdk",
3
- "version": "0.12.10",
3
+ "version": "0.13.0",
4
4
  "description": "SDK for building AI-powered development tools and agents",
5
5
  "keywords": [
6
6
  "ai",
@@ -2,6 +2,7 @@ export const ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
2
2
  export const BASH_TOOL_NAME = "Bash";
3
3
  export const TASK_STOP_TOOL_NAME = "TaskStop";
4
4
  export const EDIT_TOOL_NAME = "Edit";
5
+ export const ENTER_PLAN_MODE_TOOL_NAME = "EnterPlanMode";
5
6
  export const EXIT_PLAN_MODE_TOOL_NAME = "ExitPlanMode";
6
7
  export const GLOB_TOOL_NAME = "Glob";
7
8
  export const GREP_TOOL_NAME = "Grep";
@@ -778,6 +778,9 @@ export class AIManager {
778
778
  model,
779
779
  );
780
780
 
781
+ // Finalize text/reasoning blocks for the final response (no tools)
782
+ this.messageManager.finalizeStreamingBlocks();
783
+
781
784
  // Check if there are tool operations or response was truncated, if so automatically initiate next AI service call
782
785
  if (toolCalls.length > 0 || result.finish_reason === "length") {
783
786
  // Record committed snapshots to message history
@@ -961,7 +964,9 @@ export class AIManager {
961
964
  cwd: this.workdir,
962
965
  subagentType: this.subagentType, // Include subagent type in hook context
963
966
  // Stop hooks don't need toolName, toolInput, toolResponse, or userPrompt
964
- env: this.configurationService.getEnvironmentVars(), // Include configuration environment variables
967
+ env: Object.fromEntries(
968
+ Object.entries(process.env).filter((e) => e[1] !== undefined),
969
+ ) as Record<string, string>, // Include environment variables
965
970
  };
966
971
 
967
972
  const results = await this.hookManager.executeHooks(hookName, context);
@@ -1047,7 +1052,9 @@ export class AIManager {
1047
1052
  cwd: this.workdir,
1048
1053
  toolInput,
1049
1054
  subagentType: this.subagentType, // Include subagent type in hook context
1050
- env: this.configurationService.getEnvironmentVars(), // Include configuration environment variables
1055
+ env: Object.fromEntries(
1056
+ Object.entries(process.env).filter((e) => e[1] !== undefined),
1057
+ ) as Record<string, string>, // Include environment variables
1051
1058
  };
1052
1059
 
1053
1060
  const results = await this.hookManager.executeHooks(
@@ -1113,7 +1120,9 @@ export class AIManager {
1113
1120
  toolInput,
1114
1121
  toolResponse,
1115
1122
  subagentType: this.subagentType, // Include subagent type in hook context
1116
- env: this.configurationService.getEnvironmentVars(), // Include configuration environment variables
1123
+ env: Object.fromEntries(
1124
+ Object.entries(process.env).filter((e) => e[1] !== undefined),
1125
+ ) as Record<string, string>, // Include environment variables
1117
1126
  };
1118
1127
 
1119
1128
  const results = await this.hookManager.executeHooks(
@@ -34,6 +34,61 @@ export interface McpManagerOptions {
34
34
  logger?: Logger;
35
35
  }
36
36
 
37
+ /**
38
+ * Expand environment variables in a string value.
39
+ * Supports ${VAR} and ${VAR:-default} patterns.
40
+ */
41
+ export function expandEnvVars(value: string): string {
42
+ return value.replace(/\$\{([^}]+)\}/g, (_match, expr: string) => {
43
+ const [varName, ...rest] = expr.split(":-");
44
+ const defaultValue = rest.join(":-");
45
+ return process.env[varName] ?? defaultValue;
46
+ });
47
+ }
48
+
49
+ /**
50
+ * Walk an MCP config and expand env vars in all string fields.
51
+ */
52
+ export function resolveMcpConfig(config: McpConfig): McpConfig {
53
+ const resolved: McpConfig = { mcpServers: {} };
54
+
55
+ for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
56
+ const resolvedServer: McpServerConfig = { ...serverConfig };
57
+
58
+ if (resolvedServer.command) {
59
+ resolvedServer.command = expandEnvVars(resolvedServer.command);
60
+ }
61
+
62
+ if (resolvedServer.args) {
63
+ resolvedServer.args = resolvedServer.args.map(expandEnvVars);
64
+ }
65
+
66
+ if (resolvedServer.env) {
67
+ const resolvedEnv: Record<string, string> = {};
68
+ for (const [key, val] of Object.entries(resolvedServer.env)) {
69
+ resolvedEnv[key] = expandEnvVars(val);
70
+ }
71
+ resolvedServer.env = resolvedEnv;
72
+ }
73
+
74
+ if (resolvedServer.url) {
75
+ resolvedServer.url = expandEnvVars(resolvedServer.url);
76
+ }
77
+
78
+ if (resolvedServer.headers) {
79
+ const resolvedHeaders: Record<string, string> = {};
80
+ for (const [key, val] of Object.entries(resolvedServer.headers)) {
81
+ resolvedHeaders[key] = expandEnvVars(val);
82
+ }
83
+ resolvedServer.headers = resolvedHeaders;
84
+ }
85
+
86
+ resolved.mcpServers[name] = resolvedServer;
87
+ }
88
+
89
+ return resolved;
90
+ }
91
+
37
92
  export class McpManager {
38
93
  private config: McpConfig | null = null;
39
94
  private servers: Map<string, McpServerStatus> = new Map();
@@ -109,7 +164,7 @@ export class McpManager {
109
164
 
110
165
  try {
111
166
  const configContent = await fs.readFile(this.configPath, "utf-8");
112
- this.config = JSON.parse(configContent);
167
+ this.config = resolveMcpConfig(JSON.parse(configContent));
113
168
 
114
169
  // Initialize server statuses (preserve existing status for already known servers)
115
170
  if (this.config) {