wave-agent-sdk 0.0.6 → 0.0.8

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 (180) hide show
  1. package/dist/agent.d.ts +32 -20
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +209 -24
  4. package/dist/constants/events.d.ts +28 -0
  5. package/dist/constants/events.d.ts.map +1 -0
  6. package/dist/constants/events.js +27 -0
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +2 -0
  10. package/dist/managers/aiManager.d.ts +34 -1
  11. package/dist/managers/aiManager.d.ts.map +1 -1
  12. package/dist/managers/aiManager.js +248 -132
  13. package/dist/managers/backgroundBashManager.d.ts.map +1 -1
  14. package/dist/managers/backgroundBashManager.js +7 -6
  15. package/dist/managers/hookManager.d.ts +13 -16
  16. package/dist/managers/hookManager.d.ts.map +1 -1
  17. package/dist/managers/hookManager.js +81 -44
  18. package/dist/managers/liveConfigManager.d.ts +58 -0
  19. package/dist/managers/liveConfigManager.d.ts.map +1 -0
  20. package/dist/managers/liveConfigManager.js +160 -0
  21. package/dist/managers/messageManager.d.ts +41 -24
  22. package/dist/managers/messageManager.d.ts.map +1 -1
  23. package/dist/managers/messageManager.js +168 -49
  24. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  25. package/dist/managers/slashCommandManager.js +9 -3
  26. package/dist/managers/subagentManager.d.ts +51 -0
  27. package/dist/managers/subagentManager.d.ts.map +1 -1
  28. package/dist/managers/subagentManager.js +190 -19
  29. package/dist/services/aiService.d.ts +13 -5
  30. package/dist/services/aiService.d.ts.map +1 -1
  31. package/dist/services/aiService.js +350 -74
  32. package/dist/services/configurationWatcher.d.ts +120 -0
  33. package/dist/services/configurationWatcher.d.ts.map +1 -0
  34. package/dist/services/configurationWatcher.js +439 -0
  35. package/dist/services/fileWatcher.d.ts +69 -0
  36. package/dist/services/fileWatcher.d.ts.map +1 -0
  37. package/dist/services/fileWatcher.js +213 -0
  38. package/dist/services/hook.d.ts +91 -9
  39. package/dist/services/hook.d.ts.map +1 -1
  40. package/dist/services/hook.js +393 -43
  41. package/dist/services/jsonlHandler.d.ts +62 -0
  42. package/dist/services/jsonlHandler.d.ts.map +1 -0
  43. package/dist/services/jsonlHandler.js +257 -0
  44. package/dist/services/memory.d.ts +9 -0
  45. package/dist/services/memory.d.ts.map +1 -1
  46. package/dist/services/memory.js +81 -12
  47. package/dist/services/memoryStore.d.ts +81 -0
  48. package/dist/services/memoryStore.d.ts.map +1 -0
  49. package/dist/services/memoryStore.js +200 -0
  50. package/dist/services/session.d.ts +64 -49
  51. package/dist/services/session.d.ts.map +1 -1
  52. package/dist/services/session.js +310 -132
  53. package/dist/tools/bashTool.d.ts.map +1 -1
  54. package/dist/tools/bashTool.js +5 -4
  55. package/dist/tools/deleteFileTool.d.ts.map +1 -1
  56. package/dist/tools/deleteFileTool.js +2 -1
  57. package/dist/tools/editTool.d.ts.map +1 -1
  58. package/dist/tools/editTool.js +3 -2
  59. package/dist/tools/multiEditTool.d.ts.map +1 -1
  60. package/dist/tools/multiEditTool.js +4 -3
  61. package/dist/tools/readTool.d.ts.map +1 -1
  62. package/dist/tools/readTool.js +2 -1
  63. package/dist/tools/todoWriteTool.d.ts.map +1 -1
  64. package/dist/tools/todoWriteTool.js +3 -10
  65. package/dist/tools/writeTool.d.ts.map +1 -1
  66. package/dist/tools/writeTool.js +5 -6
  67. package/dist/types/commands.d.ts +4 -0
  68. package/dist/types/commands.d.ts.map +1 -1
  69. package/dist/types/core.d.ts +35 -0
  70. package/dist/types/core.d.ts.map +1 -1
  71. package/dist/types/environment.d.ts +42 -0
  72. package/dist/types/environment.d.ts.map +1 -0
  73. package/dist/types/environment.js +21 -0
  74. package/dist/types/hooks.d.ts +8 -2
  75. package/dist/types/hooks.d.ts.map +1 -1
  76. package/dist/types/hooks.js +8 -2
  77. package/dist/types/index.d.ts +2 -0
  78. package/dist/types/index.d.ts.map +1 -1
  79. package/dist/types/index.js +2 -0
  80. package/dist/types/memoryStore.d.ts +82 -0
  81. package/dist/types/memoryStore.d.ts.map +1 -0
  82. package/dist/types/memoryStore.js +7 -0
  83. package/dist/types/messaging.d.ts +21 -9
  84. package/dist/types/messaging.d.ts.map +1 -1
  85. package/dist/types/messaging.js +5 -1
  86. package/dist/types/session.d.ts +20 -0
  87. package/dist/types/session.d.ts.map +1 -0
  88. package/dist/types/session.js +7 -0
  89. package/dist/utils/bashHistory.d.ts.map +1 -1
  90. package/dist/utils/bashHistory.js +27 -26
  91. package/dist/utils/cacheControlUtils.d.ts +121 -0
  92. package/dist/utils/cacheControlUtils.d.ts.map +1 -0
  93. package/dist/utils/cacheControlUtils.js +367 -0
  94. package/dist/utils/commandPathResolver.d.ts +52 -0
  95. package/dist/utils/commandPathResolver.d.ts.map +1 -0
  96. package/dist/utils/commandPathResolver.js +145 -0
  97. package/dist/utils/configPaths.d.ts +85 -0
  98. package/dist/utils/configPaths.d.ts.map +1 -0
  99. package/dist/utils/configPaths.js +121 -0
  100. package/dist/utils/configResolver.d.ts +37 -10
  101. package/dist/utils/configResolver.d.ts.map +1 -1
  102. package/dist/utils/configResolver.js +127 -23
  103. package/dist/utils/constants.d.ts +1 -1
  104. package/dist/utils/constants.js +1 -1
  105. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  106. package/dist/utils/convertMessagesForAPI.js +8 -13
  107. package/dist/utils/customCommands.d.ts.map +1 -1
  108. package/dist/utils/customCommands.js +66 -21
  109. package/dist/utils/fileUtils.d.ts +15 -0
  110. package/dist/utils/fileUtils.d.ts.map +1 -0
  111. package/dist/utils/fileUtils.js +61 -0
  112. package/dist/utils/globalLogger.d.ts +102 -0
  113. package/dist/utils/globalLogger.d.ts.map +1 -0
  114. package/dist/utils/globalLogger.js +136 -0
  115. package/dist/utils/hookMatcher.d.ts +1 -6
  116. package/dist/utils/hookMatcher.d.ts.map +1 -1
  117. package/dist/utils/mcpUtils.d.ts.map +1 -1
  118. package/dist/utils/mcpUtils.js +25 -3
  119. package/dist/utils/messageOperations.d.ts +27 -27
  120. package/dist/utils/messageOperations.d.ts.map +1 -1
  121. package/dist/utils/messageOperations.js +46 -36
  122. package/dist/utils/pathEncoder.d.ts +104 -0
  123. package/dist/utils/pathEncoder.d.ts.map +1 -0
  124. package/dist/utils/pathEncoder.js +272 -0
  125. package/dist/utils/subagentParser.d.ts.map +1 -1
  126. package/dist/utils/subagentParser.js +2 -1
  127. package/dist/utils/tokenCalculation.d.ts +26 -0
  128. package/dist/utils/tokenCalculation.d.ts.map +1 -0
  129. package/dist/utils/tokenCalculation.js +36 -0
  130. package/package.json +6 -3
  131. package/src/agent.ts +301 -37
  132. package/src/constants/events.ts +38 -0
  133. package/src/index.ts +2 -0
  134. package/src/managers/aiManager.ts +325 -173
  135. package/src/managers/backgroundBashManager.ts +7 -6
  136. package/src/managers/hookManager.ts +106 -84
  137. package/src/managers/liveConfigManager.ts +248 -0
  138. package/src/managers/messageManager.ts +237 -100
  139. package/src/managers/slashCommandManager.ts +9 -7
  140. package/src/managers/subagentManager.ts +284 -22
  141. package/src/services/aiService.ts +474 -83
  142. package/src/services/configurationWatcher.ts +622 -0
  143. package/src/services/fileWatcher.ts +301 -0
  144. package/src/services/hook.ts +538 -47
  145. package/src/services/jsonlHandler.ts +319 -0
  146. package/src/services/memory.ts +92 -12
  147. package/src/services/memoryStore.ts +279 -0
  148. package/src/services/session.ts +381 -157
  149. package/src/tools/bashTool.ts +5 -4
  150. package/src/tools/deleteFileTool.ts +2 -1
  151. package/src/tools/editTool.ts +3 -2
  152. package/src/tools/multiEditTool.ts +4 -3
  153. package/src/tools/readTool.ts +2 -1
  154. package/src/tools/todoWriteTool.ts +3 -11
  155. package/src/tools/writeTool.ts +7 -6
  156. package/src/types/commands.ts +6 -0
  157. package/src/types/core.ts +44 -0
  158. package/src/types/environment.ts +60 -0
  159. package/src/types/hooks.ts +21 -8
  160. package/src/types/index.ts +2 -0
  161. package/src/types/memoryStore.ts +94 -0
  162. package/src/types/messaging.ts +21 -10
  163. package/src/types/session.ts +25 -0
  164. package/src/utils/bashHistory.ts +27 -27
  165. package/src/utils/cacheControlUtils.ts +540 -0
  166. package/src/utils/commandPathResolver.ts +189 -0
  167. package/src/utils/configPaths.ts +163 -0
  168. package/src/utils/configResolver.ts +182 -22
  169. package/src/utils/constants.ts +1 -1
  170. package/src/utils/convertMessagesForAPI.ts +8 -14
  171. package/src/utils/customCommands.ts +90 -22
  172. package/src/utils/fileUtils.ts +65 -0
  173. package/src/utils/globalLogger.ts +145 -0
  174. package/src/utils/hookMatcher.ts +1 -12
  175. package/src/utils/mcpUtils.ts +34 -3
  176. package/src/utils/messageOperations.ts +77 -60
  177. package/src/utils/pathEncoder.ts +379 -0
  178. package/src/utils/subagentParser.ts +2 -1
  179. package/src/utils/tokenCalculation.ts +43 -0
  180. package/src/types/index.ts.backup +0 -357
@@ -1,5 +1,7 @@
1
- import { type AgentToolBlockUpdateParams } from "../utils/messageOperations.js";
1
+ import { UserMessageParams, type AgentToolBlockUpdateParams } from "../utils/messageOperations.js";
2
+ import type { SubagentConfiguration } from "../utils/subagentParser.js";
2
3
  import type { Logger, Message, Usage } from "../types/index.js";
4
+ import { SessionData } from "../services/session.js";
3
5
  import { ChatCompletionMessageFunctionToolCall } from "openai/resources.js";
4
6
  export interface MessageManagerCallbacks {
5
7
  onMessagesChange?: (messages: Message[]) => void;
@@ -7,18 +9,15 @@ export interface MessageManagerCallbacks {
7
9
  onLatestTotalTokensChange?: (latestTotalTokens: number) => void;
8
10
  onUserInputHistoryChange?: (history: string[]) => void;
9
11
  onUsagesChange?: (usages: Usage[]) => void;
10
- onUserMessageAdded?: (content: string, images?: Array<{
11
- path: string;
12
- mimeType: string;
13
- }>) => void;
14
- onAssistantMessageAdded?: (content?: string, toolCalls?: ChatCompletionMessageFunctionToolCall[]) => void;
12
+ onUserMessageAdded?: (params: UserMessageParams) => void;
13
+ onAssistantMessageAdded?: () => void;
14
+ onAssistantContentUpdated?: (chunk: string, accumulated: string) => void;
15
15
  onToolBlockUpdated?: (params: AgentToolBlockUpdateParams) => void;
16
16
  onDiffBlockAdded?: (filePath: string, diffResult: string) => void;
17
17
  onErrorBlockAdded?: (error: string) => void;
18
18
  onCompressBlockAdded?: (insertIndex: number, content: string) => void;
19
19
  onCompressionStateChange?: (isCompressing: boolean) => void;
20
20
  onMemoryBlockAdded?: (content: string, success: boolean, type: "project" | "user", storagePath: string) => void;
21
- onCustomCommandAdded?: (commandName: string, content: string, originalInput?: string) => void;
22
21
  onAddCommandOutputMessage?: (command: string) => void;
23
22
  onUpdateCommandOutputMessage?: (command: string, output: string) => void;
24
23
  onCompleteCommandMessage?: (command: string, exitCode: number) => void;
@@ -27,17 +26,15 @@ export interface MessageManagerCallbacks {
27
26
  prompt: string;
28
27
  subagent_type: string;
29
28
  }) => void;
30
- onSubAgentBlockUpdated?: (subagentId: string, messages: Message[], status: "active" | "completed" | "error" | "aborted") => void;
29
+ onSubAgentBlockUpdated?: (subagentId: string, status: "active" | "completed" | "error" | "aborted") => void;
31
30
  }
32
31
  export interface MessageManagerOptions {
33
32
  callbacks: MessageManagerCallbacks;
34
33
  workdir: string;
35
34
  logger?: Logger;
36
- /**
37
- * Custom session directory path
38
- * @default join(homedir(), ".wave", "sessions")
39
- */
40
- sessionDir?: string;
35
+ sessionType?: "main" | "subagent";
36
+ parentSessionId?: string;
37
+ subagentType?: string;
41
38
  }
42
39
  export declare class MessageManager {
43
40
  private sessionId;
@@ -46,16 +43,33 @@ export declare class MessageManager {
46
43
  private userInputHistory;
47
44
  private sessionStartTime;
48
45
  private workdir;
46
+ private encodedWorkdir;
49
47
  private logger?;
50
48
  private callbacks;
51
- private sessionDir?;
49
+ private transcriptPath;
50
+ private savedMessageCount;
51
+ private sessionType;
52
+ private parentSessionId?;
53
+ private subagentType?;
52
54
  constructor(options: MessageManagerOptions);
53
55
  getSessionId(): string;
54
56
  getMessages(): Message[];
55
57
  getlatestTotalTokens(): number;
56
58
  getUserInputHistory(): string[];
59
+ getSessionStartTime(): string;
60
+ getWorkdir(): string;
61
+ getSessionDir(): string;
57
62
  getTranscriptPath(): string;
63
+ /**
64
+ * Compute the transcript path using cached encoded workdir
65
+ * Called during construction and when sessionId changes
66
+ */
67
+ private computeTranscriptPath;
58
68
  setSessionId(sessionId: string): void;
69
+ /**
70
+ * Create session if needed (async helper)
71
+ */
72
+ private createSessionIfNeeded;
59
73
  setMessages(messages: Message[]): void;
60
74
  /**
61
75
  * Save current session
@@ -71,15 +85,12 @@ export declare class MessageManager {
71
85
  * Clear messages and input history
72
86
  */
73
87
  clearMessages(): void;
74
- initializeFromSession(sessionId: string, messages: Message[], latestTotalTokens: number): void;
88
+ initializeFromSession(sessionData: SessionData): void;
75
89
  addToInputHistory(input: string): void;
76
90
  clearInputHistory(): void;
77
- addUserMessage(content: string, images?: Array<{
78
- path: string;
79
- mimeType: string;
80
- }>): void;
81
- addCustomCommandMessage(commandName: string, content: string, originalInput?: string): void;
82
- addAssistantMessage(content?: string, toolCalls?: ChatCompletionMessageFunctionToolCall[], usage?: Usage): void;
91
+ addUserMessage(params: UserMessageParams): void;
92
+ addAssistantMessage(content?: string, toolCalls?: ChatCompletionMessageFunctionToolCall[], usage?: Usage, metadata?: Record<string, unknown>): void;
93
+ mergeAssistantMetadata(metadata: Record<string, unknown>): void;
83
94
  updateToolBlock(params: AgentToolBlockUpdateParams): void;
84
95
  addDiffBlock(filePath: string, diffResult: Array<{
85
96
  value: string;
@@ -90,24 +101,30 @@ export declare class MessageManager {
90
101
  /**
91
102
  * Compress messages and update session, delete compressed messages, only keep compressed messages and subsequent messages
92
103
  */
93
- compressMessagesAndUpdateSession(insertIndex: number, compressedContent: string): void;
104
+ compressMessagesAndUpdateSession(insertIndex: number, compressedContent: string, usage?: Usage): void;
94
105
  addMemoryBlock(content: string, success: boolean, type: "project" | "user", storagePath: string): void;
95
106
  addCommandOutputMessage(command: string): void;
96
107
  updateCommandOutputMessage(command: string, output: string): void;
97
108
  completeCommandMessage(command: string, exitCode: number): void;
98
- addSubagentBlock(subagentId: string, subagentName: string, status: "active" | "completed" | "error" | undefined, subagentMessages: Message[] | undefined, parameters: {
109
+ addSubagentBlock(subagentId: string, subagentName: string, sessionId: string, configuration: SubagentConfiguration, status: "active" | "completed" | "error" | undefined, parameters: {
99
110
  description: string;
100
111
  prompt: string;
101
112
  subagent_type: string;
102
113
  }): void;
103
114
  updateSubagentBlock(subagentId: string, updates: Partial<{
104
115
  status: "active" | "completed" | "error" | "aborted";
105
- messages: Message[];
116
+ sessionId: string;
106
117
  }>): void;
107
118
  /**
108
119
  * Trigger usage change callback with all usage data from assistant messages
109
120
  */
110
121
  triggerUsageChange(): void;
122
+ /**
123
+ * Update the current assistant message content during streaming
124
+ * This method updates the last assistant message's content without creating a new message
125
+ * FR-001: Tracks and provides both chunk (new content) and accumulated (total content)
126
+ */
127
+ updateCurrentMessageContent(newAccumulatedContent: string): void;
111
128
  /**
112
129
  * Remove the last user message from the conversation
113
130
  * Used for hook error handling when the user prompt needs to be erased
@@ -1 +1 @@
1
- {"version":3,"file":"messageManager.d.ts","sourceRoot":"","sources":["../../src/managers/messageManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"messageManager.d.ts","sourceRoot":"","sources":["../../src/managers/messageManager.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,24 @@
1
- import { randomUUID } from "crypto";
2
1
  import { addAssistantMessageToMessages, updateToolBlockInMessage, addErrorBlockToMessage, addDiffBlockToMessage, addUserMessageToMessages, extractUserInputHistory, addMemoryBlockToMessage, addCommandOutputMessage, updateCommandOutputInMessage, completeCommandInMessage, addSubagentBlockToMessage, updateSubagentBlockInMessage, removeLastUserMessage, } from "../utils/messageOperations.js";
3
- import { cleanupExpiredSessions, getLatestSession, loadSession, saveSession, getSessionFilePath, } from "../services/session.js";
2
+ import { join } from "path";
3
+ import { cleanupExpiredSessionsFromJsonl, getLatestSessionFromJsonl, loadSessionFromJsonl, appendMessages, createSession, generateSessionId, SESSION_DIR, } from "../services/session.js";
4
+ import { pathEncoder } from "../utils/pathEncoder.js";
4
5
  export class MessageManager {
5
6
  constructor(options) {
6
- this.sessionId = randomUUID();
7
+ this.sessionId = generateSessionId();
7
8
  this.messages = [];
8
9
  this.latestTotalTokens = 0;
9
10
  this.userInputHistory = [];
10
11
  this.sessionStartTime = new Date().toISOString();
11
12
  this.workdir = options.workdir;
13
+ this.encodedWorkdir = pathEncoder.encodeSync(this.workdir); // Cache encoded workdir
12
14
  this.callbacks = options.callbacks;
13
15
  this.logger = options.logger;
14
- this.sessionDir = options.sessionDir;
16
+ this.savedMessageCount = 0; // Initialize saved message count tracker
17
+ this.sessionType = options.sessionType || "main";
18
+ this.parentSessionId = options.parentSessionId;
19
+ this.subagentType = options.subagentType;
20
+ // Compute and cache the transcript path
21
+ this.transcriptPath = this.computeTranscriptPath();
15
22
  }
16
23
  // Getter methods
17
24
  getSessionId() {
@@ -26,16 +33,50 @@ export class MessageManager {
26
33
  getUserInputHistory() {
27
34
  return [...this.userInputHistory];
28
35
  }
36
+ getSessionStartTime() {
37
+ return this.sessionStartTime;
38
+ }
39
+ getWorkdir() {
40
+ return this.workdir;
41
+ }
42
+ getSessionDir() {
43
+ return SESSION_DIR;
44
+ }
29
45
  getTranscriptPath() {
30
- return getSessionFilePath(this.sessionId, this.sessionDir);
46
+ return this.transcriptPath;
47
+ }
48
+ /**
49
+ * Compute the transcript path using cached encoded workdir
50
+ * Called during construction and when sessionId changes
51
+ */
52
+ computeTranscriptPath() {
53
+ const baseDir = join(SESSION_DIR, this.encodedWorkdir);
54
+ // All sessions now go in the same directory
55
+ // Session type is determined by metadata, not file path
56
+ return join(baseDir, `${this.sessionId}.jsonl`);
31
57
  }
32
58
  // Setter methods, will trigger callbacks
33
59
  setSessionId(sessionId) {
34
60
  if (this.sessionId !== sessionId) {
35
61
  this.sessionId = sessionId;
62
+ // Reset saved message count for new session
63
+ this.savedMessageCount = 0;
64
+ // Recompute transcript path since session ID changed
65
+ this.transcriptPath = this.computeTranscriptPath();
36
66
  this.callbacks.onSessionIdChange?.(sessionId);
37
67
  }
38
68
  }
69
+ /**
70
+ * Create session if needed (async helper)
71
+ */
72
+ async createSessionIfNeeded() {
73
+ try {
74
+ await createSession(this.sessionId, this.workdir, this.sessionType, this.parentSessionId, this.subagentType);
75
+ }
76
+ catch (error) {
77
+ this.logger?.error("Failed to create session:", error);
78
+ }
79
+ }
39
80
  setMessages(messages) {
40
81
  this.messages = [...messages];
41
82
  this.callbacks.onMessagesChange?.([...messages]);
@@ -45,7 +86,22 @@ export class MessageManager {
45
86
  */
46
87
  async saveSession() {
47
88
  try {
48
- await saveSession(this.sessionId, this.messages, this.workdir, this.latestTotalTokens, this.sessionStartTime, this.sessionDir);
89
+ // Only save messages that haven't been saved yet
90
+ const unsavedMessages = this.messages.slice(this.savedMessageCount);
91
+ if (unsavedMessages.length === 0) {
92
+ // No new messages to save
93
+ return;
94
+ }
95
+ // Create session if needed (only when we have messages to save)
96
+ if (this.savedMessageCount === 0) {
97
+ // This is the first time saving messages, so create the session
98
+ await this.createSessionIfNeeded();
99
+ }
100
+ // Use JSONL format for new sessions
101
+ await appendMessages(this.sessionId, unsavedMessages, // Only append new messages
102
+ this.workdir);
103
+ // Update the saved message count
104
+ this.savedMessageCount = this.messages.length;
49
105
  }
50
106
  catch (error) {
51
107
  this.logger?.error("Failed to save session:", error);
@@ -56,26 +112,25 @@ export class MessageManager {
56
112
  */
57
113
  async handleSessionRestoration(restoreSessionId, continueLastSession) {
58
114
  // Clean up expired sessions first
59
- try {
60
- await cleanupExpiredSessions(this.workdir, this.sessionDir);
61
- }
62
- catch (error) {
115
+ cleanupExpiredSessionsFromJsonl(this.workdir).catch((error) => {
63
116
  this.logger?.warn("Failed to cleanup expired sessions:", error);
64
- }
117
+ });
65
118
  if (!restoreSessionId && !continueLastSession) {
66
119
  return;
67
120
  }
68
121
  try {
69
122
  let sessionToRestore = null;
70
123
  if (restoreSessionId) {
71
- sessionToRestore = await loadSession(restoreSessionId, this.sessionDir);
124
+ // Use only JSONL format - no legacy support
125
+ sessionToRestore = await loadSessionFromJsonl(restoreSessionId, this.workdir);
72
126
  if (!sessionToRestore) {
73
127
  console.error(`Session not found: ${restoreSessionId}`);
74
128
  process.exit(1);
75
129
  }
76
130
  }
77
131
  else if (continueLastSession) {
78
- sessionToRestore = await getLatestSession(this.workdir, this.sessionDir);
132
+ // Use only JSONL format - no legacy support
133
+ sessionToRestore = await getLatestSessionFromJsonl(this.workdir);
79
134
  if (!sessionToRestore) {
80
135
  console.error(`No previous session found for workdir: ${this.workdir}`);
81
136
  process.exit(1);
@@ -84,7 +139,7 @@ export class MessageManager {
84
139
  if (sessionToRestore) {
85
140
  console.log(`Restoring session: ${sessionToRestore.id}`);
86
141
  // Initialize from session data
87
- this.initializeFromSession(sessionToRestore.id, sessionToRestore.messages, sessionToRestore.metadata.latestTotalTokens);
142
+ this.initializeFromSession(sessionToRestore);
88
143
  }
89
144
  }
90
145
  catch (error) {
@@ -108,17 +163,23 @@ export class MessageManager {
108
163
  clearMessages() {
109
164
  this.setMessages([]);
110
165
  this.setUserInputHistory([]);
111
- this.setSessionId(randomUUID());
166
+ this.setSessionId(generateSessionId());
112
167
  this.setlatestTotalTokens(0);
113
168
  this.sessionStartTime = new Date().toISOString();
169
+ this.savedMessageCount = 0; // Reset saved message count
114
170
  }
115
171
  // Initialize state from session data
116
- initializeFromSession(sessionId, messages, latestTotalTokens) {
117
- this.setSessionId(sessionId);
118
- this.setMessages([...messages]);
119
- this.setlatestTotalTokens(latestTotalTokens);
172
+ initializeFromSession(sessionData) {
173
+ this.setSessionId(sessionData.id);
174
+ this.setMessages([...sessionData.messages]);
175
+ this.setlatestTotalTokens(sessionData.metadata.latestTotalTokens);
176
+ // Restore the original session start time
177
+ this.sessionStartTime = sessionData.metadata.startedAt;
120
178
  // Extract user input history from session messages
121
- this.setUserInputHistory(extractUserInputHistory(messages));
179
+ this.setUserInputHistory(extractUserInputHistory(sessionData.messages));
180
+ // Set saved message count to the number of loaded messages since they're already saved
181
+ // This must be done after setSessionId which resets it to 0
182
+ this.savedMessageCount = sessionData.messages.length;
122
183
  }
123
184
  // Add to input history
124
185
  addToInputHistory(input) {
@@ -135,49 +196,68 @@ export class MessageManager {
135
196
  this.setUserInputHistory([]);
136
197
  }
137
198
  // Encapsulated message operation functions
138
- addUserMessage(content, images) {
199
+ addUserMessage(params) {
139
200
  const newMessages = addUserMessageToMessages({
140
201
  messages: this.messages,
141
- content,
142
- images,
202
+ ...params,
143
203
  });
144
204
  this.setMessages(newMessages);
145
- this.callbacks.onUserMessageAdded?.(content, images);
205
+ this.callbacks.onUserMessageAdded?.(params);
206
+ // Note: Subagent-specific callbacks are now handled by SubagentManager
146
207
  }
147
- addCustomCommandMessage(commandName, content, originalInput) {
148
- const newMessages = addUserMessageToMessages({
149
- messages: this.messages,
150
- content: "", // Empty content, as we will use CustomCommandBlock
151
- customCommandBlock: {
152
- type: "custom_command",
153
- commandName,
154
- content,
155
- originalInput,
156
- },
157
- });
208
+ addAssistantMessage(content, toolCalls, usage, metadata) {
209
+ const metadataRecord = metadata
210
+ ? Object.fromEntries(Object.entries(metadata).filter(([, value]) => value !== undefined))
211
+ : undefined;
212
+ const newMessages = addAssistantMessageToMessages(this.messages, content, toolCalls, usage, metadataRecord);
158
213
  this.setMessages(newMessages);
159
- this.callbacks.onCustomCommandAdded?.(commandName, content, originalInput);
214
+ this.callbacks.onAssistantMessageAdded?.();
215
+ // Note: Subagent-specific callbacks are now handled by SubagentManager
160
216
  }
161
- addAssistantMessage(content, toolCalls, usage) {
162
- const newMessages = addAssistantMessageToMessages(this.messages, content, toolCalls, usage);
163
- this.setMessages(newMessages);
164
- this.callbacks.onAssistantMessageAdded?.(content, toolCalls);
217
+ mergeAssistantMetadata(metadata) {
218
+ if (!metadata || Object.keys(metadata).length === 0) {
219
+ return;
220
+ }
221
+ const newMessages = [...this.messages];
222
+ for (let i = newMessages.length - 1; i >= 0; i--) {
223
+ const message = newMessages[i];
224
+ if (message.role === "assistant") {
225
+ const mergedMetadata = {
226
+ ...(message.metadata || {}),
227
+ };
228
+ for (const [key, value] of Object.entries(metadata)) {
229
+ if (value === undefined) {
230
+ continue;
231
+ }
232
+ mergedMetadata[key] = value;
233
+ }
234
+ if (Object.keys(mergedMetadata).length === 0) {
235
+ return;
236
+ }
237
+ message.metadata = mergedMetadata;
238
+ this.setMessages(newMessages);
239
+ return;
240
+ }
241
+ }
165
242
  }
166
243
  updateToolBlock(params) {
167
244
  const newMessages = updateToolBlockInMessage({
168
245
  messages: this.messages,
169
- id: params.toolId,
170
- parameters: params.args || "",
246
+ id: params.id,
247
+ parameters: params.parameters,
171
248
  result: params.result,
172
249
  success: params.success,
173
250
  error: params.error,
174
- isRunning: params.isRunning,
251
+ stage: params.stage,
175
252
  name: params.name,
176
253
  shortResult: params.shortResult,
254
+ images: params.images,
177
255
  compactParams: params.compactParams,
256
+ parametersChunk: params.parametersChunk,
178
257
  });
179
258
  this.setMessages(newMessages);
180
259
  this.callbacks.onToolBlockUpdated?.(params);
260
+ // Note: Subagent-specific callbacks are now handled by SubagentManager
181
261
  }
182
262
  addDiffBlock(filePath, diffResult) {
183
263
  const newMessages = addDiffBlockToMessage({
@@ -199,7 +279,7 @@ export class MessageManager {
199
279
  /**
200
280
  * Compress messages and update session, delete compressed messages, only keep compressed messages and subsequent messages
201
281
  */
202
- compressMessagesAndUpdateSession(insertIndex, compressedContent) {
282
+ compressMessagesAndUpdateSession(insertIndex, compressedContent, usage) {
203
283
  const currentMessages = this.messages;
204
284
  // Create compressed message
205
285
  const compressMessage = {
@@ -208,8 +288,10 @@ export class MessageManager {
208
288
  {
209
289
  type: "compress",
210
290
  content: compressedContent,
291
+ sessionId: this.sessionId,
211
292
  },
212
293
  ],
294
+ ...(usage && { usage }),
213
295
  };
214
296
  // Convert negative index to positive index
215
297
  const actualIndex = insertIndex < 0 ? currentMessages.length + insertIndex : insertIndex;
@@ -219,7 +301,7 @@ export class MessageManager {
219
301
  ...currentMessages.slice(actualIndex),
220
302
  ];
221
303
  // Update sessionId
222
- this.setSessionId(randomUUID());
304
+ this.setSessionId(generateSessionId());
223
305
  // Set new message list
224
306
  this.setMessages(newMessages);
225
307
  // Trigger compression callback, insertIndex remains unchanged
@@ -264,13 +346,14 @@ export class MessageManager {
264
346
  this.callbacks.onCompleteCommandMessage?.(command, exitCode);
265
347
  }
266
348
  // Subagent block methods
267
- addSubagentBlock(subagentId, subagentName, status = "active", subagentMessages = [], parameters) {
349
+ addSubagentBlock(subagentId, subagentName, sessionId, configuration, status = "active", parameters) {
268
350
  const params = {
269
351
  messages: this.messages,
270
352
  subagentId,
271
353
  subagentName,
354
+ sessionId,
272
355
  status,
273
- subagentMessages,
356
+ configuration,
274
357
  };
275
358
  const updatedMessages = addSubagentBlockToMessage(params);
276
359
  this.setMessages(updatedMessages);
@@ -283,9 +366,8 @@ export class MessageManager {
283
366
  messages: this.messages,
284
367
  subagentId,
285
368
  status: updates.status || "active",
286
- subagentMessages: updates.messages || [],
287
369
  };
288
- this.callbacks.onSubAgentBlockUpdated?.(params.subagentId, params.messages, params.status);
370
+ this.callbacks.onSubAgentBlockUpdated?.(params.subagentId, params.status);
289
371
  }
290
372
  /**
291
373
  * Trigger usage change callback with all usage data from assistant messages
@@ -299,6 +381,43 @@ export class MessageManager {
299
381
  }
300
382
  this.callbacks.onUsagesChange?.(usages);
301
383
  }
384
+ /**
385
+ * Update the current assistant message content during streaming
386
+ * This method updates the last assistant message's content without creating a new message
387
+ * FR-001: Tracks and provides both chunk (new content) and accumulated (total content)
388
+ */
389
+ updateCurrentMessageContent(newAccumulatedContent) {
390
+ if (this.messages.length === 0)
391
+ return;
392
+ const lastMessage = this.messages[this.messages.length - 1];
393
+ if (lastMessage.role !== "assistant")
394
+ return;
395
+ // Get the current content to calculate the chunk
396
+ const textBlockIndex = lastMessage.blocks.findIndex((block) => block.type === "text");
397
+ const currentContent = textBlockIndex >= 0
398
+ ? lastMessage.blocks[textBlockIndex].content || ""
399
+ : "";
400
+ // Calculate the chunk (new content since last update)
401
+ const chunk = newAccumulatedContent.slice(currentContent.length);
402
+ if (textBlockIndex >= 0) {
403
+ // Update existing text block
404
+ lastMessage.blocks[textBlockIndex] = {
405
+ type: "text",
406
+ content: newAccumulatedContent,
407
+ };
408
+ }
409
+ else {
410
+ // Add new text block if none exists
411
+ lastMessage.blocks.unshift({
412
+ type: "text",
413
+ content: newAccumulatedContent,
414
+ });
415
+ }
416
+ // FR-001: Trigger callbacks with chunk and accumulated content
417
+ this.callbacks.onAssistantContentUpdated?.(chunk, newAccumulatedContent);
418
+ // Note: Subagent-specific callbacks are now handled by SubagentManager
419
+ this.callbacks.onMessagesChange?.([...this.messages]); // Still need to notify of changes
420
+ }
302
421
  /**
303
422
  * Remove the last user message from the conversation
304
423
  * Used for hook error handling when the user prompt needs to be erased
@@ -1 +1 @@
1
- {"version":3,"file":"slashCommandManager.d.ts","sourceRoot":"","sources":["../../src/managers/slashCommandManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,MAAM,EACP,MAAM,mBAAmB,CAAC;AAkB3B,MAAM,WAAW,0BAA0B;IACzC,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,cAAc,CAAyC;IAC/D,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,OAAO,EAAE,0BAA0B;IAU/C,OAAO,CAAC,yBAAyB;IAYjC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAwC1B;;OAEG;IACI,oBAAoB,IAAI,IAAI;IAWnC;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACI,WAAW,IAAI,YAAY,EAAE;IAIpC;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI9D;;OAEG;IACU,cAAc,CACzB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC;IAenB;;;OAGG;IACI,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG;QAClD,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf;IAeD;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI7C;;OAEG;IACI,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI1E;;OAEG;IACI,iBAAiB,IAAI,kBAAkB,EAAE;IAIhD;;OAEG;YACW,+BAA+B;IA2E7C;;OAEG;IACI,mBAAmB,IAAI,IAAI;CAInC"}
1
+ {"version":3,"file":"slashCommandManager.d.ts","sourceRoot":"","sources":["../../src/managers/slashCommandManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,MAAM,EACP,MAAM,mBAAmB,CAAC;AAkB3B,MAAM,WAAW,0BAA0B;IACzC,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,cAAc,CAAyC;IAC/D,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,OAAO,EAAE,0BAA0B;IAU/C,OAAO,CAAC,yBAAyB;IAejC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAwC1B;;OAEG;IACI,oBAAoB,IAAI,IAAI;IAWnC;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACI,WAAW,IAAI,YAAY,EAAE;IAIpC;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI9D;;OAEG;IACU,cAAc,CACzB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC;IAenB;;;OAGG;IACI,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG;QAClD,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf;IAeD;;OAEG;IACI,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI7C;;OAEG;IACI,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI1E;;OAEG;IACI,iBAAiB,IAAI,kBAAkB,EAAE;IAIhD;;OAEG;YACW,+BAA+B;IA0E7C;;OAEG;IACI,mBAAmB,IAAI,IAAI;CAInC"}
@@ -20,9 +20,12 @@ export class SlashCommandManager {
20
20
  this.registerCommand({
21
21
  id: "clear",
22
22
  name: "clear",
23
- description: "Clear the chat session",
23
+ description: "Clear the chat session and terminal",
24
24
  handler: () => {
25
+ // Clear chat messages
25
26
  this.messageManager.clearMessages();
27
+ // Clear terminal screen
28
+ process.stdout.write("\x1Bc");
26
29
  },
27
30
  });
28
31
  }
@@ -181,11 +184,14 @@ export class SlashCommandManager {
181
184
  const finalContent = bashResults.length > 0
182
185
  ? replaceBashCommandsWithOutput(processedContent, bashResults)
183
186
  : processedContent;
184
- // Add custom command block to show the command being executed
187
+ // Add custom command message to show the command being executed
185
188
  const originalInput = args
186
189
  ? `/${commandName} ${args}`
187
190
  : `/${commandName}`;
188
- this.messageManager.addCustomCommandMessage(commandName, finalContent, originalInput);
191
+ this.messageManager.addUserMessage({
192
+ content: originalInput,
193
+ customCommandContent: finalContent,
194
+ });
189
195
  // Execute the AI conversation with custom configuration
190
196
  await this.aiManager.sendAIMessage({
191
197
  model: config?.model,