wave-agent-sdk 0.17.1 → 0.17.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.
Files changed (173) hide show
  1. package/builtin/skills/deep-research/SKILL.md +90 -0
  2. package/builtin/skills/settings/ENV.md +6 -3
  3. package/dist/agent.d.ts +28 -1
  4. package/dist/agent.d.ts.map +1 -1
  5. package/dist/agent.js +128 -34
  6. package/dist/constants/goalPrompts.d.ts +2 -0
  7. package/dist/constants/goalPrompts.d.ts.map +1 -0
  8. package/dist/constants/goalPrompts.js +10 -0
  9. package/dist/constants/tools.d.ts +1 -0
  10. package/dist/constants/tools.d.ts.map +1 -1
  11. package/dist/constants/tools.js +1 -0
  12. package/dist/managers/aiManager.d.ts +7 -0
  13. package/dist/managers/aiManager.d.ts.map +1 -1
  14. package/dist/managers/aiManager.js +77 -41
  15. package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
  16. package/dist/managers/backgroundTaskManager.js +10 -2
  17. package/dist/managers/goalManager.d.ts +43 -0
  18. package/dist/managers/goalManager.d.ts.map +1 -0
  19. package/dist/managers/goalManager.js +177 -0
  20. package/dist/managers/messageManager.d.ts +2 -2
  21. package/dist/managers/messageManager.d.ts.map +1 -1
  22. package/dist/managers/messageQueue.d.ts +10 -0
  23. package/dist/managers/messageQueue.d.ts.map +1 -1
  24. package/dist/managers/messageQueue.js +53 -1
  25. package/dist/managers/pluginManager.d.ts.map +1 -1
  26. package/dist/managers/pluginManager.js +7 -1
  27. package/dist/managers/skillManager.d.ts +2 -0
  28. package/dist/managers/skillManager.d.ts.map +1 -1
  29. package/dist/managers/skillManager.js +19 -9
  30. package/dist/managers/slashCommandManager.d.ts +6 -0
  31. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  32. package/dist/managers/slashCommandManager.js +105 -0
  33. package/dist/managers/toolManager.d.ts.map +1 -1
  34. package/dist/managers/toolManager.js +5 -0
  35. package/dist/managers/workflowManager.d.ts +65 -0
  36. package/dist/managers/workflowManager.d.ts.map +1 -0
  37. package/dist/managers/workflowManager.js +380 -0
  38. package/dist/prompts/index.d.ts +2 -1
  39. package/dist/prompts/index.d.ts.map +1 -1
  40. package/dist/prompts/index.js +3 -3
  41. package/dist/services/MarketplaceService.d.ts +2 -2
  42. package/dist/services/MarketplaceService.d.ts.map +1 -1
  43. package/dist/services/MarketplaceService.js +11 -32
  44. package/dist/services/aiService.d.ts +23 -0
  45. package/dist/services/aiService.d.ts.map +1 -1
  46. package/dist/services/aiService.js +102 -9
  47. package/dist/services/configurationService.d.ts +1 -1
  48. package/dist/services/configurationService.d.ts.map +1 -1
  49. package/dist/services/configurationService.js +3 -16
  50. package/dist/services/hook.d.ts.map +1 -1
  51. package/dist/services/hook.js +4 -0
  52. package/dist/services/session.d.ts +9 -1
  53. package/dist/services/session.d.ts.map +1 -1
  54. package/dist/services/session.js +28 -1
  55. package/dist/tools/bashTool.d.ts.map +1 -1
  56. package/dist/tools/bashTool.js +49 -7
  57. package/dist/tools/readTool.d.ts.map +1 -1
  58. package/dist/tools/readTool.js +1 -1
  59. package/dist/tools/taskManagementTools.d.ts.map +1 -1
  60. package/dist/tools/taskManagementTools.js +103 -157
  61. package/dist/tools/types.d.ts +2 -0
  62. package/dist/tools/types.d.ts.map +1 -1
  63. package/dist/tools/webFetchTool.d.ts.map +1 -1
  64. package/dist/tools/webFetchTool.js +0 -9
  65. package/dist/tools/workflowTool.d.ts +11 -0
  66. package/dist/tools/workflowTool.d.ts.map +1 -0
  67. package/dist/tools/workflowTool.js +190 -0
  68. package/dist/types/agent.d.ts +2 -0
  69. package/dist/types/agent.d.ts.map +1 -1
  70. package/dist/types/commands.d.ts +4 -0
  71. package/dist/types/commands.d.ts.map +1 -1
  72. package/dist/types/config.d.ts +2 -2
  73. package/dist/types/config.d.ts.map +1 -1
  74. package/dist/types/core.d.ts +1 -1
  75. package/dist/types/core.d.ts.map +1 -1
  76. package/dist/types/hooks.d.ts +2 -0
  77. package/dist/types/hooks.d.ts.map +1 -1
  78. package/dist/types/index.d.ts +1 -0
  79. package/dist/types/index.d.ts.map +1 -1
  80. package/dist/types/index.js +1 -0
  81. package/dist/types/messaging.d.ts +2 -2
  82. package/dist/types/messaging.d.ts.map +1 -1
  83. package/dist/types/processes.d.ts +6 -2
  84. package/dist/types/processes.d.ts.map +1 -1
  85. package/dist/types/workflow.d.ts +2 -0
  86. package/dist/types/workflow.d.ts.map +1 -0
  87. package/dist/types/workflow.js +1 -0
  88. package/dist/utils/cacheControlUtils.d.ts +13 -8
  89. package/dist/utils/cacheControlUtils.d.ts.map +1 -1
  90. package/dist/utils/cacheControlUtils.js +73 -102
  91. package/dist/utils/containerSetup.d.ts.map +1 -1
  92. package/dist/utils/containerSetup.js +7 -0
  93. package/dist/utils/markdownParser.d.ts.map +1 -1
  94. package/dist/utils/markdownParser.js +21 -6
  95. package/dist/utils/messageOperations.d.ts +2 -2
  96. package/dist/utils/messageOperations.d.ts.map +1 -1
  97. package/dist/utils/notificationXml.d.ts.map +1 -1
  98. package/dist/workflow/budgetTracker.d.ts +12 -0
  99. package/dist/workflow/budgetTracker.d.ts.map +1 -0
  100. package/dist/workflow/budgetTracker.js +30 -0
  101. package/dist/workflow/concurrencyLimiter.d.ts +14 -0
  102. package/dist/workflow/concurrencyLimiter.d.ts.map +1 -0
  103. package/dist/workflow/concurrencyLimiter.js +39 -0
  104. package/dist/workflow/journal.d.ts +19 -0
  105. package/dist/workflow/journal.d.ts.map +1 -0
  106. package/dist/workflow/journal.js +74 -0
  107. package/dist/workflow/progressReporter.d.ts +21 -0
  108. package/dist/workflow/progressReporter.d.ts.map +1 -0
  109. package/dist/workflow/progressReporter.js +118 -0
  110. package/dist/workflow/runState.d.ts +16 -0
  111. package/dist/workflow/runState.d.ts.map +1 -0
  112. package/dist/workflow/runState.js +57 -0
  113. package/dist/workflow/scriptRuntime.d.ts +35 -0
  114. package/dist/workflow/scriptRuntime.d.ts.map +1 -0
  115. package/dist/workflow/scriptRuntime.js +196 -0
  116. package/dist/workflow/structuredOutput.d.ts +27 -0
  117. package/dist/workflow/structuredOutput.d.ts.map +1 -0
  118. package/dist/workflow/structuredOutput.js +106 -0
  119. package/dist/workflow/types.d.ts +81 -0
  120. package/dist/workflow/types.d.ts.map +1 -0
  121. package/dist/workflow/types.js +1 -0
  122. package/dist/workflow/workflowApis.d.ts +46 -0
  123. package/dist/workflow/workflowApis.d.ts.map +1 -0
  124. package/dist/workflow/workflowApis.js +280 -0
  125. package/package.json +1 -1
  126. package/src/agent.ts +144 -34
  127. package/src/constants/goalPrompts.ts +10 -0
  128. package/src/constants/tools.ts +1 -0
  129. package/src/managers/aiManager.ts +91 -47
  130. package/src/managers/backgroundTaskManager.ts +16 -4
  131. package/src/managers/goalManager.ts +232 -0
  132. package/src/managers/messageManager.ts +2 -2
  133. package/src/managers/messageQueue.ts +59 -1
  134. package/src/managers/pluginManager.ts +8 -1
  135. package/src/managers/skillManager.ts +20 -9
  136. package/src/managers/slashCommandManager.ts +119 -0
  137. package/src/managers/toolManager.ts +7 -0
  138. package/src/managers/workflowManager.ts +491 -0
  139. package/src/prompts/index.ts +4 -2
  140. package/src/services/MarketplaceService.ts +14 -38
  141. package/src/services/aiService.ts +166 -12
  142. package/src/services/configurationService.ts +2 -22
  143. package/src/services/hook.ts +5 -0
  144. package/src/services/session.ts +42 -2
  145. package/src/tools/bashTool.ts +64 -9
  146. package/src/tools/readTool.ts +1 -2
  147. package/src/tools/taskManagementTools.ts +146 -195
  148. package/src/tools/types.ts +2 -0
  149. package/src/tools/webFetchTool.ts +0 -12
  150. package/src/tools/workflowTool.ts +205 -0
  151. package/src/types/agent.ts +6 -0
  152. package/src/types/commands.ts +4 -0
  153. package/src/types/config.ts +2 -2
  154. package/src/types/core.ts +3 -3
  155. package/src/types/hooks.ts +2 -0
  156. package/src/types/index.ts +1 -0
  157. package/src/types/messaging.ts +2 -2
  158. package/src/types/processes.ts +10 -2
  159. package/src/types/workflow.ts +5 -0
  160. package/src/utils/cacheControlUtils.ts +106 -131
  161. package/src/utils/containerSetup.ts +9 -0
  162. package/src/utils/markdownParser.ts +26 -8
  163. package/src/utils/messageOperations.ts +2 -2
  164. package/src/utils/notificationXml.ts +6 -1
  165. package/src/workflow/budgetTracker.ts +34 -0
  166. package/src/workflow/concurrencyLimiter.ts +47 -0
  167. package/src/workflow/journal.ts +95 -0
  168. package/src/workflow/progressReporter.ts +141 -0
  169. package/src/workflow/runState.ts +65 -0
  170. package/src/workflow/scriptRuntime.ts +274 -0
  171. package/src/workflow/structuredOutput.ts +123 -0
  172. package/src/workflow/types.ts +95 -0
  173. package/src/workflow/workflowApis.ts +412 -0
@@ -1,11 +1,13 @@
1
1
  import { OpenAIClient } from "../utils/openaiClient.js";
2
2
  import { logger } from "../utils/globalLogger.js";
3
3
  import { addOnceAbortListener } from "../utils/abortUtils.js";
4
+ import { ConfigurationError, CONFIG_ERRORS } from "../types/index.js";
4
5
  import { transformMessagesForClaudeCache, addCacheControlToLastTool, supportsPromptCaching, extendUsageWithCacheMetrics, } from "../utils/cacheControlUtils.js";
5
6
  import * as os from "os";
6
7
  import * as fs from "fs";
7
8
  import * as path from "path";
8
9
  import { COMPACT_MESSAGES_SYSTEM_PROMPT, WEB_CONTENT_SYSTEM_PROMPT, BTW_SYSTEM_PROMPT, } from "../prompts/index.js";
10
+ import { GOAL_EVALUATION_SYSTEM_PROMPT } from "../constants/goalPrompts.js";
9
11
  // Global rate limiter state for 1 QPS
10
12
  let nextAllowedTime = 0;
11
13
  const MIN_INTERVAL = 1000; // 1 second for 1 QPS
@@ -63,8 +65,24 @@ function getModelConfig(modelName, baseConfig = {}) {
63
65
  }
64
66
  return config;
65
67
  }
68
+ function validateModelConfig(modelConfig) {
69
+ if (!modelConfig.model) {
70
+ throw new ConfigurationError(CONFIG_ERRORS.MISSING_MODEL, "model", {
71
+ constructor: undefined,
72
+ environment: process.env.WAVE_MODEL,
73
+ });
74
+ }
75
+ if (!modelConfig.fastModel) {
76
+ throw new ConfigurationError(CONFIG_ERRORS.MISSING_FAST_MODEL, "fastModel", {
77
+ constructor: undefined,
78
+ environment: process.env.WAVE_FAST_MODEL,
79
+ });
80
+ }
81
+ }
66
82
  export async function callAgent(options) {
67
83
  const { gatewayConfig, modelConfig, messages, abortSignal, workdir, tools, model, systemPrompt, onContentUpdate, onToolUpdate, onReasoningUpdate, } = options;
84
+ // Validate model config at call time
85
+ validateModelConfig(modelConfig);
68
86
  // Apply global 1 QPS rate limit
69
87
  if (process.env.NODE_ENV !== "test" ||
70
88
  modelConfig.model === "rate-limit-test") {
@@ -127,6 +145,10 @@ export async function callAgent(options) {
127
145
  if (processedTools && processedTools.length > 0) {
128
146
  createParams.tools = processedTools;
129
147
  }
148
+ // Add tool_choice if specified
149
+ if (options.toolChoice) {
150
+ createParams.tool_choice = options.toolChoice;
151
+ }
130
152
  if (isStreaming) {
131
153
  // Handle streaming response
132
154
  const { data: stream, response } = await openai.chat.completions
@@ -139,7 +161,7 @@ export async function callAgent(options) {
139
161
  response.headers.forEach((value, key) => {
140
162
  responseHeaders[key] = value;
141
163
  });
142
- return await processStreamingResponse(stream, onContentUpdate, onToolUpdate, onReasoningUpdate, abortSignal, responseHeaders, currentModel);
164
+ return await processStreamingResponse(stream, onContentUpdate, onToolUpdate, onReasoningUpdate, abortSignal, responseHeaders);
143
165
  }
144
166
  else {
145
167
  // Handle non-streaming response
@@ -162,8 +184,8 @@ export async function callAgent(options) {
162
184
  total_tokens: response.usage.total_tokens,
163
185
  }
164
186
  : undefined;
165
- // Extend usage with cache metrics for Claude models
166
- if (totalUsage && supportsPromptCaching(currentModel) && response.usage) {
187
+ // Extend usage with cache metrics (Claude top-level + OpenAI prompt_tokens_details)
188
+ if (totalUsage && response.usage) {
167
189
  totalUsage = extendUsageWithCacheMetrics(totalUsage, response.usage);
168
190
  }
169
191
  const result = {};
@@ -288,10 +310,9 @@ export async function callAgent(options) {
288
310
  * @param onToolUpdate Callback for tool updates
289
311
  * @param abortSignal Optional abort signal
290
312
  * @param responseHeaders Response headers from the initial request
291
- * @param modelName Model name for cache control processing
292
313
  * @returns Final result with accumulated content and tool calls
293
314
  */
294
- async function processStreamingResponse(stream, onContentUpdate, onToolUpdate, onReasoningUpdate, abortSignal, responseHeaders, modelName) {
315
+ async function processStreamingResponse(stream, onContentUpdate, onToolUpdate, onReasoningUpdate, abortSignal, responseHeaders) {
295
316
  let accumulatedContent = "";
296
317
  let accumulatedReasoningContent = "";
297
318
  let hasReasoningContent = false;
@@ -312,10 +333,8 @@ async function processStreamingResponse(stream, onContentUpdate, onToolUpdate, o
312
333
  completion_tokens: chunk.usage.completion_tokens,
313
334
  total_tokens: chunk.usage.total_tokens,
314
335
  };
315
- // Extend usage with cache metrics for Claude models
316
- if (modelName && supportsPromptCaching(modelName)) {
317
- chunkUsage = extendUsageWithCacheMetrics(chunkUsage, chunk.usage);
318
- }
336
+ // Extend usage with cache metrics (Claude top-level + OpenAI prompt_tokens_details)
337
+ chunkUsage = extendUsageWithCacheMetrics(chunkUsage, chunk.usage);
319
338
  usage = chunkUsage;
320
339
  }
321
340
  // Check for finish_reason in the choice
@@ -454,6 +473,8 @@ async function processStreamingResponse(stream, onContentUpdate, onToolUpdate, o
454
473
  }
455
474
  export async function compactMessages(options) {
456
475
  const { gatewayConfig, modelConfig, messages, abortSignal } = options;
476
+ // Validate model config at call time
477
+ validateModelConfig(modelConfig);
457
478
  // Apply global 1 QPS rate limit
458
479
  if (process.env.NODE_ENV !== "test" ||
459
480
  modelConfig.model === "rate-limit-test") {
@@ -534,6 +555,8 @@ export async function compactMessages(options) {
534
555
  }
535
556
  export async function processWebContent(options) {
536
557
  const { gatewayConfig, modelConfig, content, prompt, abortSignal } = options;
558
+ // Validate model config at call time
559
+ validateModelConfig(modelConfig);
537
560
  // Apply global 1 QPS rate limit
538
561
  if (process.env.NODE_ENV !== "test" ||
539
562
  modelConfig.model === "rate-limit-test") {
@@ -601,6 +624,8 @@ export async function processWebContent(options) {
601
624
  }
602
625
  export async function btw(options) {
603
626
  const { gatewayConfig, modelConfig, messages, question, abortSignal } = options;
627
+ // Validate model config at call time
628
+ validateModelConfig(modelConfig);
604
629
  // Apply global 1 QPS rate limit
605
630
  if (process.env.NODE_ENV !== "test" ||
606
631
  modelConfig.model === "rate-limit-test") {
@@ -667,3 +692,71 @@ export async function btw(options) {
667
692
  throw error;
668
693
  }
669
694
  }
695
+ export async function evaluateGoal(options) {
696
+ const { gatewayConfig, modelConfig, model, goalCondition, messages, abortSignal, } = options;
697
+ // Create OpenAI client with injected configuration (no rate limiter — bypasses 1 QPS)
698
+ const openai = new OpenAIClient({
699
+ apiKey: gatewayConfig.apiKey,
700
+ baseURL: gatewayConfig.baseURL,
701
+ defaultHeaders: gatewayConfig.defaultHeaders,
702
+ fetchOptions: gatewayConfig.fetchOptions,
703
+ fetch: gatewayConfig.fetch,
704
+ });
705
+ const { model: _model, fastModel: _fastModel, maxTokens: _maxTokens, permissionMode: _permissionMode, ...extraParams } = modelConfig;
706
+ void _model;
707
+ void _fastModel;
708
+ void _maxTokens;
709
+ void _permissionMode;
710
+ const openaiModelConfig = getModelConfig(model, {
711
+ temperature: 0,
712
+ max_tokens: 200,
713
+ ...extraParams,
714
+ });
715
+ // Strip images from messages to reduce token usage (same as compact)
716
+ const cleanedMessages = messages.map((msg) => {
717
+ if (Array.isArray(msg.content)) {
718
+ const textParts = msg.content.filter((part) => part.type === "text");
719
+ const text = textParts.map((p) => p.text).join("\n");
720
+ return { ...msg, content: text || "(empty message)" };
721
+ }
722
+ return msg;
723
+ });
724
+ try {
725
+ const response = await openai.chat.completions.create({
726
+ ...openaiModelConfig,
727
+ messages: [
728
+ {
729
+ role: "system",
730
+ content: GOAL_EVALUATION_SYSTEM_PROMPT,
731
+ },
732
+ ...cleanedMessages,
733
+ {
734
+ role: "user",
735
+ content: `Goal condition: ${goalCondition}\n\nHas this goal been achieved based on the conversation above?`,
736
+ },
737
+ ],
738
+ }, {
739
+ signal: abortSignal,
740
+ });
741
+ const result = response.choices[0]?.message?.content?.trim();
742
+ if (!result) {
743
+ throw new Error("Goal evaluation returned empty response");
744
+ }
745
+ const usage = response.usage
746
+ ? {
747
+ prompt_tokens: response.usage.prompt_tokens,
748
+ completion_tokens: response.usage.completion_tokens,
749
+ total_tokens: response.usage.total_tokens,
750
+ }
751
+ : undefined;
752
+ return { content: result, usage };
753
+ }
754
+ catch (error) {
755
+ if (error.name === "AbortError") {
756
+ logger.info("Goal evaluation was aborted");
757
+ throw new Error("Goal evaluation was aborted");
758
+ }
759
+ logger.error("Goal evaluation failed:", error);
760
+ throw error;
761
+ }
762
+ }
@@ -52,7 +52,7 @@ export declare class ConfigurationService {
52
52
  * @param fetchOptions - Fetch options override (optional)
53
53
  * @param fetch - Custom fetch implementation override (optional)
54
54
  * @returns Resolved gateway configuration
55
- * @throws ConfigurationError if required configuration is missing after fallbacks
55
+ * @returns Resolved model configuration (model/fastModel may be undefined if not yet configured)
56
56
  */
57
57
  resolveGatewayConfig(apiKey?: string, baseURL?: string, defaultHeaders?: Record<string, string>, fetchOptions?: ClientOptions["fetchOptions"], fetch?: ClientOptions["fetch"]): GatewayConfig;
58
58
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"configurationService.d.ts","sourceRoot":"","sources":["../../src/services/configurationService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"configurationService.d.ts","sourceRoot":"","sources":["../../src/services/configurationService.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,6 @@ import { isValidHookEvent } from "../types/hooks.js";
11
11
  import { logger } from "../utils/globalLogger.js";
12
12
  import { getAllConfigPaths, getExistingConfigPaths, getUserConfigPaths, getProjectConfigPaths, } from "../utils/configPaths.js";
13
13
  import { isValidEnvironmentVars, } from "../types/environment.js";
14
- import { ConfigurationError, CONFIG_ERRORS, } from "../types/index.js";
15
14
  import { DEFAULT_WAVE_MAX_INPUT_TOKENS, DEFAULT_WAVE_MAX_OUTPUT_TOKENS, } from "../utils/constants.js";
16
15
  import { parseCustomHeaders } from "../utils/stringUtils.js";
17
16
  import { getRemoteSettingsSync, mergeRemoteSettings, } from "./remoteSettingsService.js";
@@ -320,7 +319,7 @@ export class ConfigurationService {
320
319
  * @param fetchOptions - Fetch options override (optional)
321
320
  * @param fetch - Custom fetch implementation override (optional)
322
321
  * @returns Resolved gateway configuration
323
- * @throws ConfigurationError if required configuration is missing after fallbacks
322
+ * @returns Resolved model configuration (model/fastModel may be undefined if not yet configured)
324
323
  */
325
324
  resolveGatewayConfig(apiKey, baseURL, defaultHeaders, fetchOptions, fetch) {
326
325
  // Check for SSO token first - if present and server URL is available, use SSO mode
@@ -411,19 +410,6 @@ export class ConfigurationService {
411
410
  process.env.WAVE_MODEL;
412
411
  // Resolve fast model: override > options > process.env (includes settings.json env)
413
412
  const resolvedFastModel = fastModel || this.options.fastModel || process.env.WAVE_FAST_MODEL;
414
- // Validate required fields
415
- if (!resolvedAgentModel) {
416
- throw new ConfigurationError(CONFIG_ERRORS.MISSING_MODEL, "model", {
417
- constructor: model,
418
- environment: process.env.WAVE_MODEL,
419
- });
420
- }
421
- if (!resolvedFastModel) {
422
- throw new ConfigurationError(CONFIG_ERRORS.MISSING_FAST_MODEL, "fastModel", {
423
- constructor: fastModel,
424
- environment: process.env.WAVE_FAST_MODEL,
425
- });
426
- }
427
413
  // Resolve max output tokens
428
414
  const resolvedMaxTokens = this.resolveMaxOutputTokens(maxTokens);
429
415
  const baseConfig = {
@@ -433,7 +419,8 @@ export class ConfigurationService {
433
419
  permissionMode: permissionMode ?? this.options.permissionMode,
434
420
  };
435
421
  // Merge model-specific settings from configuration
436
- const modelSpecificConfig = this.currentConfiguration?.models?.[resolvedAgentModel];
422
+ const modelSpecificConfig = resolvedAgentModel &&
423
+ this.currentConfiguration?.models?.[resolvedAgentModel];
437
424
  if (modelSpecificConfig) {
438
425
  return {
439
426
  ...baseConfig,
@@ -1 +1 @@
1
- {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/services/hook.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EAElC,MAAM,mBAAmB,CAAC;AA2F3B;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,EAC5D,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CA6I9B;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,EAC5D,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAchC;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAMhC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsBtD"}
1
+ {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/services/hook.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EAElC,MAAM,mBAAmB,CAAC;AAgG3B;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,EAC5D,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CA6I9B;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,EAAE,oBAAoB,GAAG,4BAA4B,EAC5D,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAchC;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAMhC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAsBtD"}
@@ -48,6 +48,10 @@ async function buildHookJsonInput(context) {
48
48
  context.userPrompt !== undefined) {
49
49
  jsonInput.user_prompt = context.userPrompt;
50
50
  }
51
+ // Add plan_file_path if present
52
+ if (context.planFilePath !== undefined) {
53
+ jsonInput.plan_file_path = context.planFilePath;
54
+ }
51
55
  // Add subagent_type if present
52
56
  if (context.subagentType !== undefined) {
53
57
  jsonInput.subagent_type = context.subagentType;
@@ -33,13 +33,15 @@ export interface SessionMetadata {
33
33
  sessionType: "main" | "subagent";
34
34
  subagentType?: string;
35
35
  workdir: string;
36
+ createdAt: Date;
36
37
  lastActiveAt: Date;
37
38
  latestTotalTokens: number;
38
39
  firstMessage?: string;
39
40
  }
40
41
  export interface SessionIndex {
41
- sessions: Record<string, Omit<SessionMetadata, "id" | "lastActiveAt"> & {
42
+ sessions: Record<string, Omit<SessionMetadata, "id" | "lastActiveAt" | "createdAt"> & {
42
43
  lastActiveAt: string;
44
+ createdAt: string;
43
45
  }>;
44
46
  lastUpdated: string;
45
47
  }
@@ -49,6 +51,12 @@ export interface SessionIndex {
49
51
  * @returns Timestamp-prefixed session ID string
50
52
  */
51
53
  export declare function generateSessionId(): string;
54
+ /**
55
+ * Parse the timestamp prefix from a session ID back into a Date
56
+ * Format: {YYYYMMDDHHmmss}-{8hex} (e.g. 20260527143025-a1b2c3d4)
57
+ * @returns Date from the session ID timestamp prefix
58
+ */
59
+ export declare function parseSessionIdTimestamp(sessionId: string): Date;
52
60
  /**
53
61
  * Generate filename for subagent sessions
54
62
  * @param sessionId - UUID session identifier
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/services/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/services/session.ts"],"names":[],"mappings":"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"}
@@ -41,6 +41,19 @@ export function generateSessionId() {
41
41
  const shortId = randomUUID().slice(0, 8);
42
42
  return `${ts}-${shortId}`;
43
43
  }
44
+ /**
45
+ * Parse the timestamp prefix from a session ID back into a Date
46
+ * Format: {YYYYMMDDHHmmss}-{8hex} (e.g. 20260527143025-a1b2c3d4)
47
+ * @returns Date from the session ID timestamp prefix
48
+ */
49
+ export function parseSessionIdTimestamp(sessionId) {
50
+ const match = sessionId.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/);
51
+ if (!match) {
52
+ return new Date(); // Fallback to now for legacy UUID-format session IDs
53
+ }
54
+ const [, year, month, day, hour, minute, second] = match;
55
+ return new Date(Number(year), Number(month) - 1, Number(day), Number(hour), Number(minute), Number(second));
56
+ }
44
57
  /**
45
58
  * Generate filename for subagent sessions
46
59
  * @param sessionId - UUID session identifier
@@ -72,6 +85,7 @@ async function updateSessionIndex(projectDirPath, metadata) {
72
85
  const { id, ...rest } = metadata;
73
86
  index.sessions[id] = {
74
87
  ...rest,
88
+ createdAt: metadata.createdAt.toISOString(),
75
89
  lastActiveAt: metadata.lastActiveAt.toISOString(),
76
90
  firstMessage: metadata.firstMessage || index.sessions[id]?.firstMessage,
77
91
  parentSessionId: metadata.parentSessionId,
@@ -165,8 +179,9 @@ export async function appendMessages(sessionId, newMessages, workdir, sessionTyp
165
179
  const encoder = new PathEncoder();
166
180
  const projectDir = await encoder.getProjectDirectory(workdir, SESSION_DIR);
167
181
  const lastMessage = newMessages[newMessages.length - 1];
168
- // Get first message content if it's a new session or we don't have it
182
+ // Get first message content and createdAt from existing index
169
183
  let firstMessage;
184
+ let createdAt;
170
185
  try {
171
186
  const indexPath = join(projectDir.encodedPath, SESSION_INDEX_FILENAME);
172
187
  const content = await fs.readFile(indexPath, "utf8");
@@ -175,18 +190,26 @@ export async function appendMessages(sessionId, newMessages, workdir, sessionTyp
175
190
  firstMessage =
176
191
  (await getFirstMessageContent(sessionId, workdir)) || undefined;
177
192
  }
193
+ if (index.sessions[sessionId]?.createdAt) {
194
+ createdAt = new Date(index.sessions[sessionId].createdAt);
195
+ }
178
196
  }
179
197
  catch {
180
198
  // If index doesn't exist, this might be the first message
181
199
  firstMessage =
182
200
  (await getFirstMessageContent(sessionId, workdir)) || undefined;
183
201
  }
202
+ // Derive createdAt from session ID timestamp if not in index
203
+ if (!createdAt) {
204
+ createdAt = new Date(parseSessionIdTimestamp(sessionId));
205
+ }
184
206
  await updateSessionIndex(projectDir.encodedPath, {
185
207
  id: sessionId,
186
208
  rootSessionId,
187
209
  parentSessionId,
188
210
  sessionType,
189
211
  workdir,
212
+ createdAt,
190
213
  lastActiveAt: new Date(lastMessage.timestamp),
191
214
  latestTotalTokens: lastMessage.usage
192
215
  ? extractLatestTotalTokens([lastMessage])
@@ -327,6 +350,7 @@ export async function listSessionsFromJsonl(workdir) {
327
350
  .map(([id, meta]) => ({
328
351
  id,
329
352
  ...meta,
353
+ createdAt: new Date(meta.createdAt),
330
354
  lastActiveAt: new Date(meta.lastActiveAt),
331
355
  }));
332
356
  return sessions.sort((a, b) => b.lastActiveAt.getTime() - a.lastActiveAt.getTime());
@@ -386,6 +410,7 @@ export async function listSessionsFromJsonl(workdir) {
386
410
  sessionType: "main",
387
411
  subagentType: undefined, // No longer stored in metadata
388
412
  workdir: projectDir.originalPath,
413
+ createdAt: new Date(parseSessionIdTimestamp(sessionId)),
389
414
  lastActiveAt,
390
415
  latestTotalTokens: lastMessage?.usage
391
416
  ? extractLatestTotalTokens([lastMessage])
@@ -420,6 +445,7 @@ export async function listSessionsFromJsonl(workdir) {
420
445
  const { id, ...rest } = session;
421
446
  index.sessions[id] = {
422
447
  ...rest,
448
+ createdAt: session.createdAt.toISOString(),
423
449
  lastActiveAt: session.lastActiveAt.toISOString(),
424
450
  };
425
451
  }
@@ -473,6 +499,7 @@ export async function listAllSessions() {
473
499
  allSessions.push({
474
500
  id,
475
501
  ...meta,
502
+ createdAt: new Date(meta.createdAt),
476
503
  lastActiveAt,
477
504
  });
478
505
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAYtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAyetB,CAAC"}
1
+ {"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAuBtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAqhBtB,CAAC"}
@@ -8,6 +8,16 @@ import { processToolResult } from "../utils/toolResultStorage.js";
8
8
  import { BASH_MAX_OUTPUT_CHARS } from "../constants/toolLimits.js";
9
9
  import { BASH_TOOL_NAME, GLOB_TOOL_NAME, GREP_TOOL_NAME, READ_TOOL_NAME, EDIT_TOOL_NAME, WRITE_TOOL_NAME, } from "../constants/tools.js";
10
10
  const BASH_DEFAULT_TIMEOUT_MS = 120000;
11
+ // Commands that should not be auto-backgrounded on timeout (e.g. sleep should just be killed)
12
+ const DISALLOWED_AUTO_BACKGROUND_COMMANDS = ["sleep"];
13
+ function isAutobackgroundingAllowed(command) {
14
+ const trimmed = command.trim();
15
+ // Get the first word of the command
16
+ const baseCommand = trimmed.split(/\s+/)[0];
17
+ if (!baseCommand)
18
+ return true;
19
+ return !DISALLOWED_AUTO_BACKGROUND_COMMANDS.includes(baseCommand);
20
+ }
11
21
  /**
12
22
  * Bash command execution tool - supports both foreground and background execution
13
23
  */
@@ -111,8 +121,12 @@ The working directory persists between commands. Try to maintain your current wo
111
121
  const runInBackground = args.run_in_background;
112
122
  const description = args.description;
113
123
  // Set default timeout: BASH_DEFAULT_TIMEOUT_MS for foreground, no timeout for background
114
- const timeout = args.timeout ??
115
- (runInBackground ? undefined : BASH_DEFAULT_TIMEOUT_MS);
124
+ // When run_in_background is explicitly set, cancel any timeout — the intent is to
125
+ // let the process run to completion (matching Claude Code behavior where background()
126
+ // clears the timeout via cleanupListeners).
127
+ const timeout = runInBackground
128
+ ? undefined
129
+ : (args.timeout ?? BASH_DEFAULT_TIMEOUT_MS);
116
130
  if (!command || typeof command !== "string") {
117
131
  return {
118
132
  success: false,
@@ -166,7 +180,7 @@ The working directory persists between commands. Try to maintain your current wo
166
180
  error: "Background task manager not available",
167
181
  };
168
182
  }
169
- const { id: taskId } = backgroundTaskManager.startShell(command, timeout);
183
+ const { id: taskId } = backgroundTaskManager.startShell(command);
170
184
  const task = backgroundTaskManager.getTask(taskId);
171
185
  const outputPath = task?.outputPath;
172
186
  const backgroundMsg = [
@@ -249,12 +263,36 @@ The working directory persists between commands. Try to maintain your current wo
249
263
  },
250
264
  });
251
265
  }
252
- // Set up timeout
266
+ // Set up timeout — auto-background if allowed, otherwise kill
253
267
  let timeoutHandle;
268
+ const shouldAutoBackground = !!context.backgroundTaskManager && isAutobackgroundingAllowed(command);
254
269
  if (timeout && timeout > 0) {
255
270
  timeoutHandle = setTimeout(() => {
256
- if (!isAborted) {
257
- handleAbort("Command timed out");
271
+ if (!isAborted && !isBackgrounded) {
272
+ if (shouldAutoBackground) {
273
+ // Auto-background: move the process to background task manager instead of killing it
274
+ isBackgrounded = true;
275
+ if (timeoutHandle) {
276
+ clearTimeout(timeoutHandle);
277
+ }
278
+ // Unregister foreground task since it's now backgrounded
279
+ if (context.foregroundTaskManager) {
280
+ context.foregroundTaskManager.unregisterForegroundTask(foregroundTaskId);
281
+ }
282
+ const backgroundTaskManager = context.backgroundTaskManager;
283
+ const taskId = backgroundTaskManager.adoptProcess(child, command, outputBuffer, errorBuffer);
284
+ const task = backgroundTaskManager.getTask(taskId);
285
+ const outputPath = task?.outputPath;
286
+ logger.info(`[Bash] Command timed out after ${timeout}ms, auto-backgrounded as ${taskId}`);
287
+ resolve({
288
+ success: true,
289
+ content: `Command timed out after ${timeout / 1000} seconds and was moved to background with ID: ${taskId}.${outputPath ? ` Real-time output: ${outputPath}` : ""}`,
290
+ shortResult: `Process ${taskId} auto-backgrounded (timeout)`,
291
+ });
292
+ }
293
+ else {
294
+ handleAbort("Command timed out");
295
+ }
258
296
  }
259
297
  }, timeout);
260
298
  }
@@ -277,7 +315,11 @@ The working directory persists between commands. Try to maintain your current wo
277
315
  process.kill(-child.pid, "SIGKILL");
278
316
  }
279
317
  catch (killError) {
280
- logger.error("Failed to force kill process:", killError);
318
+ // ESRCH means the process already exited — not an error
319
+ if (!(killError instanceof Error) ||
320
+ killError.code !== "ESRCH") {
321
+ logger.error("Failed to force kill process:", killError);
322
+ }
281
323
  }
282
324
  }
283
325
  }, 1000);
@@ -1 +1 @@
1
- {"version":3,"file":"readTool.d.ts","sourceRoot":"","sources":["../../src/tools/readTool.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAkItE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UA6RtB,CAAC"}
1
+ {"version":3,"file":"readTool.d.ts","sourceRoot":"","sources":["../../src/tools/readTool.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAkItE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UA4RtB,CAAC"}
@@ -250,7 +250,7 @@ Usage:
250
250
  logger.warn(`File ${filePath} exists but has empty contents`);
251
251
  return {
252
252
  success: true,
253
- content: "⚠️ System reminder: This file exists but has empty contents.",
253
+ content: "System reminder: This file exists but has empty contents.",
254
254
  shortResult: "Empty file",
255
255
  metadata: {
256
256
  type: "text",
@@ -1 +1 @@
1
- {"version":3,"file":"taskManagementTools.d.ts","sourceRoot":"","sources":["../../src/tools/taskManagementTools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AASjE,eAAO,MAAM,cAAc,EAAE,UAoI5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,UAyDzB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,UAgW5B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,UAkE1B,CAAC"}
1
+ {"version":3,"file":"taskManagementTools.d.ts","sourceRoot":"","sources":["../../src/tools/taskManagementTools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AA6CjE,eAAO,MAAM,cAAc,EAAE,UAgG5B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,UAwEzB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,UAyR5B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,UAyE1B,CAAC"}