wave-agent-sdk 0.0.7 → 0.0.10

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 (240) hide show
  1. package/dist/agent.d.ts +105 -24
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +438 -53
  4. package/dist/index.d.ts +4 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +4 -0
  7. package/dist/managers/aiManager.d.ts +18 -7
  8. package/dist/managers/aiManager.d.ts.map +1 -1
  9. package/dist/managers/aiManager.js +254 -142
  10. package/dist/managers/backgroundBashManager.d.ts.map +1 -1
  11. package/dist/managers/backgroundBashManager.js +11 -9
  12. package/dist/managers/hookManager.d.ts +6 -6
  13. package/dist/managers/hookManager.d.ts.map +1 -1
  14. package/dist/managers/hookManager.js +81 -39
  15. package/dist/managers/liveConfigManager.d.ts +95 -0
  16. package/dist/managers/liveConfigManager.d.ts.map +1 -0
  17. package/dist/managers/liveConfigManager.js +442 -0
  18. package/dist/managers/lspManager.d.ts +43 -0
  19. package/dist/managers/lspManager.d.ts.map +1 -0
  20. package/dist/managers/lspManager.js +326 -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 +184 -73
  24. package/dist/managers/permissionManager.d.ts +66 -0
  25. package/dist/managers/permissionManager.d.ts.map +1 -0
  26. package/dist/managers/permissionManager.js +208 -0
  27. package/dist/managers/skillManager.d.ts +1 -0
  28. package/dist/managers/skillManager.d.ts.map +1 -1
  29. package/dist/managers/skillManager.js +2 -1
  30. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  31. package/dist/managers/slashCommandManager.js +4 -2
  32. package/dist/managers/subagentManager.d.ts +42 -6
  33. package/dist/managers/subagentManager.d.ts.map +1 -1
  34. package/dist/managers/subagentManager.js +213 -62
  35. package/dist/managers/toolManager.d.ts +38 -1
  36. package/dist/managers/toolManager.d.ts.map +1 -1
  37. package/dist/managers/toolManager.js +66 -2
  38. package/dist/services/aiService.d.ts +15 -5
  39. package/dist/services/aiService.d.ts.map +1 -1
  40. package/dist/services/aiService.js +446 -77
  41. package/dist/services/configurationService.d.ts +116 -0
  42. package/dist/services/configurationService.d.ts.map +1 -0
  43. package/dist/services/configurationService.js +585 -0
  44. package/dist/services/fileWatcher.d.ts +69 -0
  45. package/dist/services/fileWatcher.d.ts.map +1 -0
  46. package/dist/services/fileWatcher.js +212 -0
  47. package/dist/services/hook.d.ts +5 -40
  48. package/dist/services/hook.d.ts.map +1 -1
  49. package/dist/services/hook.js +47 -109
  50. package/dist/services/jsonlHandler.d.ts +71 -0
  51. package/dist/services/jsonlHandler.d.ts.map +1 -0
  52. package/dist/services/jsonlHandler.js +236 -0
  53. package/dist/services/memory.d.ts.map +1 -1
  54. package/dist/services/memory.js +33 -11
  55. package/dist/services/session.d.ts +116 -52
  56. package/dist/services/session.d.ts.map +1 -1
  57. package/dist/services/session.js +415 -143
  58. package/dist/tools/bashTool.d.ts.map +1 -1
  59. package/dist/tools/bashTool.js +77 -17
  60. package/dist/tools/deleteFileTool.d.ts.map +1 -1
  61. package/dist/tools/deleteFileTool.js +27 -1
  62. package/dist/tools/editTool.d.ts.map +1 -1
  63. package/dist/tools/editTool.js +33 -8
  64. package/dist/tools/lspTool.d.ts +6 -0
  65. package/dist/tools/lspTool.d.ts.map +1 -0
  66. package/dist/tools/lspTool.js +589 -0
  67. package/dist/tools/multiEditTool.d.ts.map +1 -1
  68. package/dist/tools/multiEditTool.js +30 -10
  69. package/dist/tools/readTool.d.ts.map +1 -1
  70. package/dist/tools/readTool.js +113 -3
  71. package/dist/tools/skillTool.js +2 -2
  72. package/dist/tools/todoWriteTool.d.ts.map +1 -1
  73. package/dist/tools/todoWriteTool.js +23 -0
  74. package/dist/tools/types.d.ts +11 -8
  75. package/dist/tools/types.d.ts.map +1 -1
  76. package/dist/tools/writeTool.d.ts.map +1 -1
  77. package/dist/tools/writeTool.js +30 -15
  78. package/dist/types/commands.d.ts +4 -1
  79. package/dist/types/commands.d.ts.map +1 -1
  80. package/dist/types/config.d.ts +4 -0
  81. package/dist/types/config.d.ts.map +1 -1
  82. package/dist/types/configuration.d.ts +69 -0
  83. package/dist/types/configuration.d.ts.map +1 -0
  84. package/dist/types/configuration.js +8 -0
  85. package/dist/types/core.d.ts +45 -0
  86. package/dist/types/core.d.ts.map +1 -1
  87. package/dist/types/environment.d.ts +83 -0
  88. package/dist/types/environment.d.ts.map +1 -0
  89. package/dist/types/environment.js +21 -0
  90. package/dist/types/fileSearch.d.ts +5 -0
  91. package/dist/types/fileSearch.d.ts.map +1 -0
  92. package/dist/types/fileSearch.js +1 -0
  93. package/dist/types/hooks.d.ts +18 -3
  94. package/dist/types/hooks.d.ts.map +1 -1
  95. package/dist/types/hooks.js +8 -8
  96. package/dist/types/index.d.ts +7 -0
  97. package/dist/types/index.d.ts.map +1 -1
  98. package/dist/types/index.js +7 -0
  99. package/dist/types/lsp.d.ts +90 -0
  100. package/dist/types/lsp.d.ts.map +1 -0
  101. package/dist/types/lsp.js +4 -0
  102. package/dist/types/messaging.d.ts +19 -12
  103. package/dist/types/messaging.d.ts.map +1 -1
  104. package/dist/types/permissions.d.ts +35 -0
  105. package/dist/types/permissions.d.ts.map +1 -0
  106. package/dist/types/permissions.js +12 -0
  107. package/dist/types/session.d.ts +15 -0
  108. package/dist/types/session.d.ts.map +1 -0
  109. package/dist/types/session.js +7 -0
  110. package/dist/types/skills.d.ts +1 -0
  111. package/dist/types/skills.d.ts.map +1 -1
  112. package/dist/types/tools.d.ts +35 -0
  113. package/dist/types/tools.d.ts.map +1 -0
  114. package/dist/types/tools.js +4 -0
  115. package/dist/utils/abortUtils.d.ts +34 -0
  116. package/dist/utils/abortUtils.d.ts.map +1 -0
  117. package/dist/utils/abortUtils.js +92 -0
  118. package/dist/utils/bashHistory.d.ts +4 -0
  119. package/dist/utils/bashHistory.d.ts.map +1 -1
  120. package/dist/utils/bashHistory.js +48 -30
  121. package/dist/utils/builtinSubagents.d.ts +7 -0
  122. package/dist/utils/builtinSubagents.d.ts.map +1 -0
  123. package/dist/utils/builtinSubagents.js +65 -0
  124. package/dist/utils/cacheControlUtils.d.ts +96 -0
  125. package/dist/utils/cacheControlUtils.d.ts.map +1 -0
  126. package/dist/utils/cacheControlUtils.js +324 -0
  127. package/dist/utils/commandPathResolver.d.ts +52 -0
  128. package/dist/utils/commandPathResolver.d.ts.map +1 -0
  129. package/dist/utils/commandPathResolver.js +145 -0
  130. package/dist/utils/configPaths.d.ts +85 -0
  131. package/dist/utils/configPaths.d.ts.map +1 -0
  132. package/dist/utils/configPaths.js +121 -0
  133. package/dist/utils/constants.d.ts +1 -13
  134. package/dist/utils/constants.d.ts.map +1 -1
  135. package/dist/utils/constants.js +2 -14
  136. package/dist/utils/convertMessagesForAPI.d.ts +2 -1
  137. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  138. package/dist/utils/convertMessagesForAPI.js +39 -18
  139. package/dist/utils/customCommands.d.ts.map +1 -1
  140. package/dist/utils/customCommands.js +66 -21
  141. package/dist/utils/fileSearch.d.ts +14 -0
  142. package/dist/utils/fileSearch.d.ts.map +1 -0
  143. package/dist/utils/fileSearch.js +88 -0
  144. package/dist/utils/fileUtils.d.ts +27 -0
  145. package/dist/utils/fileUtils.d.ts.map +1 -0
  146. package/dist/utils/fileUtils.js +145 -0
  147. package/dist/utils/globalLogger.d.ts +88 -0
  148. package/dist/utils/globalLogger.d.ts.map +1 -0
  149. package/dist/utils/globalLogger.js +120 -0
  150. package/dist/utils/largeOutputHandler.d.ts +15 -0
  151. package/dist/utils/largeOutputHandler.d.ts.map +1 -0
  152. package/dist/utils/largeOutputHandler.js +40 -0
  153. package/dist/utils/markdownParser.d.ts.map +1 -1
  154. package/dist/utils/markdownParser.js +1 -17
  155. package/dist/utils/mcpUtils.d.ts.map +1 -1
  156. package/dist/utils/mcpUtils.js +25 -3
  157. package/dist/utils/messageOperations.d.ts +20 -18
  158. package/dist/utils/messageOperations.d.ts.map +1 -1
  159. package/dist/utils/messageOperations.js +30 -38
  160. package/dist/utils/pathEncoder.d.ts +108 -0
  161. package/dist/utils/pathEncoder.d.ts.map +1 -0
  162. package/dist/utils/pathEncoder.js +279 -0
  163. package/dist/utils/subagentParser.d.ts +2 -2
  164. package/dist/utils/subagentParser.d.ts.map +1 -1
  165. package/dist/utils/subagentParser.js +12 -8
  166. package/dist/utils/tokenCalculation.d.ts +26 -0
  167. package/dist/utils/tokenCalculation.d.ts.map +1 -0
  168. package/dist/utils/tokenCalculation.js +36 -0
  169. package/dist/utils/tokenEstimator.d.ts +39 -0
  170. package/dist/utils/tokenEstimator.d.ts.map +1 -0
  171. package/dist/utils/tokenEstimator.js +55 -0
  172. package/package.json +6 -6
  173. package/src/agent.ts +586 -78
  174. package/src/index.ts +4 -0
  175. package/src/managers/aiManager.ts +341 -192
  176. package/src/managers/backgroundBashManager.ts +11 -9
  177. package/src/managers/hookManager.ts +102 -54
  178. package/src/managers/liveConfigManager.ts +634 -0
  179. package/src/managers/lspManager.ts +434 -0
  180. package/src/managers/messageManager.ts +258 -121
  181. package/src/managers/permissionManager.ts +276 -0
  182. package/src/managers/skillManager.ts +3 -1
  183. package/src/managers/slashCommandManager.ts +5 -3
  184. package/src/managers/subagentManager.ts +295 -76
  185. package/src/managers/toolManager.ts +95 -3
  186. package/src/services/aiService.ts +656 -84
  187. package/src/services/configurationService.ts +762 -0
  188. package/src/services/fileWatcher.ts +300 -0
  189. package/src/services/hook.ts +54 -144
  190. package/src/services/jsonlHandler.ts +303 -0
  191. package/src/services/memory.ts +34 -11
  192. package/src/services/session.ts +522 -173
  193. package/src/tools/bashTool.ts +94 -20
  194. package/src/tools/deleteFileTool.ts +38 -1
  195. package/src/tools/editTool.ts +44 -9
  196. package/src/tools/lspTool.ts +760 -0
  197. package/src/tools/multiEditTool.ts +41 -11
  198. package/src/tools/readTool.ts +127 -3
  199. package/src/tools/skillTool.ts +2 -2
  200. package/src/tools/todoWriteTool.ts +33 -1
  201. package/src/tools/types.ts +15 -9
  202. package/src/tools/writeTool.ts +43 -16
  203. package/src/types/commands.ts +6 -1
  204. package/src/types/config.ts +5 -0
  205. package/src/types/configuration.ts +73 -0
  206. package/src/types/core.ts +55 -0
  207. package/src/types/environment.ts +104 -0
  208. package/src/types/fileSearch.ts +4 -0
  209. package/src/types/hooks.ts +32 -16
  210. package/src/types/index.ts +7 -0
  211. package/src/types/lsp.ts +96 -0
  212. package/src/types/messaging.ts +21 -14
  213. package/src/types/permissions.ts +48 -0
  214. package/src/types/session.ts +20 -0
  215. package/src/types/skills.ts +1 -0
  216. package/src/types/tools.ts +38 -0
  217. package/src/utils/abortUtils.ts +118 -0
  218. package/src/utils/bashHistory.ts +55 -31
  219. package/src/utils/builtinSubagents.ts +71 -0
  220. package/src/utils/cacheControlUtils.ts +475 -0
  221. package/src/utils/commandPathResolver.ts +189 -0
  222. package/src/utils/configPaths.ts +163 -0
  223. package/src/utils/constants.ts +2 -17
  224. package/src/utils/convertMessagesForAPI.ts +44 -18
  225. package/src/utils/customCommands.ts +90 -22
  226. package/src/utils/fileSearch.ts +107 -0
  227. package/src/utils/fileUtils.ts +160 -0
  228. package/src/utils/globalLogger.ts +128 -0
  229. package/src/utils/largeOutputHandler.ts +55 -0
  230. package/src/utils/markdownParser.ts +1 -19
  231. package/src/utils/mcpUtils.ts +34 -3
  232. package/src/utils/messageOperations.ts +47 -53
  233. package/src/utils/pathEncoder.ts +394 -0
  234. package/src/utils/subagentParser.ts +13 -9
  235. package/src/utils/tokenCalculation.ts +43 -0
  236. package/src/utils/tokenEstimator.ts +68 -0
  237. package/dist/utils/configResolver.d.ts +0 -38
  238. package/dist/utils/configResolver.d.ts.map +0 -1
  239. package/dist/utils/configResolver.js +0 -106
  240. package/src/utils/configResolver.ts +0 -142
@@ -1,17 +1,22 @@
1
- import { randomUUID } from "crypto";
2
- 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";
1
+ import { addAssistantMessageToMessages, updateToolBlockInMessage, addErrorBlockToMessage, addUserMessageToMessages, extractUserInputHistory, addMemoryBlockToMessage, addCommandOutputMessage, updateCommandOutputInMessage, completeCommandInMessage, addSubagentBlockToMessage, updateSubagentBlockInMessage, removeLastUserMessage, } from "../utils/messageOperations.js";
2
+ import { join } from "path";
3
+ import { 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
- this.sessionStartTime = new Date().toISOString();
11
11
  this.workdir = options.workdir;
12
+ this.encodedWorkdir = pathEncoder.encodeSync(this.workdir); // Cache encoded workdir
12
13
  this.callbacks = options.callbacks;
13
14
  this.logger = options.logger;
14
- this.sessionDir = options.sessionDir;
15
+ this.savedMessageCount = 0; // Initialize saved message count tracker
16
+ this.sessionType = options.sessionType || "main";
17
+ this.subagentType = options.subagentType;
18
+ // Compute and cache the transcript path
19
+ this.transcriptPath = this.computeTranscriptPath();
15
20
  }
16
21
  // Getter methods
17
22
  getSessionId() {
@@ -26,70 +31,75 @@ export class MessageManager {
26
31
  getUserInputHistory() {
27
32
  return [...this.userInputHistory];
28
33
  }
34
+ getWorkdir() {
35
+ return this.workdir;
36
+ }
37
+ getSessionDir() {
38
+ return SESSION_DIR;
39
+ }
29
40
  getTranscriptPath() {
30
- return getSessionFilePath(this.sessionId, this.sessionDir);
41
+ return this.transcriptPath;
42
+ }
43
+ /**
44
+ * Compute the transcript path using cached encoded workdir
45
+ * Called during construction and when sessionId changes
46
+ */
47
+ computeTranscriptPath() {
48
+ const baseDir = join(SESSION_DIR, this.encodedWorkdir);
49
+ // All sessions now go in the same directory
50
+ // Session type is determined by metadata, not file path
51
+ return join(baseDir, `${this.sessionId}.jsonl`);
31
52
  }
32
53
  // Setter methods, will trigger callbacks
33
54
  setSessionId(sessionId) {
34
55
  if (this.sessionId !== sessionId) {
35
56
  this.sessionId = sessionId;
57
+ // Reset saved message count for new session
58
+ this.savedMessageCount = 0;
59
+ // Recompute transcript path since session ID changed
60
+ this.transcriptPath = this.computeTranscriptPath();
36
61
  this.callbacks.onSessionIdChange?.(sessionId);
37
62
  }
38
63
  }
39
- setMessages(messages) {
40
- this.messages = [...messages];
41
- this.callbacks.onMessagesChange?.([...messages]);
42
- }
43
64
  /**
44
- * Save current session
65
+ * Create session if needed (async helper)
45
66
  */
46
- async saveSession() {
67
+ async createSessionIfNeeded() {
47
68
  try {
48
- await saveSession(this.sessionId, this.messages, this.workdir, this.latestTotalTokens, this.sessionStartTime, this.sessionDir);
69
+ await createSession(this.sessionId, this.workdir, this.sessionType);
49
70
  }
50
71
  catch (error) {
51
- this.logger?.error("Failed to save session:", error);
72
+ this.logger?.error("Failed to create session:", error);
52
73
  }
53
74
  }
75
+ setMessages(messages) {
76
+ this.messages = [...messages];
77
+ this.callbacks.onMessagesChange?.([...messages]);
78
+ }
54
79
  /**
55
- * Handle session restoration logic
80
+ * Save current session
56
81
  */
57
- async handleSessionRestoration(restoreSessionId, continueLastSession) {
58
- // Clean up expired sessions first
59
- try {
60
- await cleanupExpiredSessions(this.workdir, this.sessionDir);
61
- }
62
- catch (error) {
63
- this.logger?.warn("Failed to cleanup expired sessions:", error);
64
- }
65
- if (!restoreSessionId && !continueLastSession) {
66
- return;
67
- }
82
+ async saveSession() {
68
83
  try {
69
- let sessionToRestore = null;
70
- if (restoreSessionId) {
71
- sessionToRestore = await loadSession(restoreSessionId, this.sessionDir);
72
- if (!sessionToRestore) {
73
- console.error(`Session not found: ${restoreSessionId}`);
74
- process.exit(1);
75
- }
76
- }
77
- else if (continueLastSession) {
78
- sessionToRestore = await getLatestSession(this.workdir, this.sessionDir);
79
- if (!sessionToRestore) {
80
- console.error(`No previous session found for workdir: ${this.workdir}`);
81
- process.exit(1);
82
- }
84
+ // Only save messages that haven't been saved yet
85
+ const unsavedMessages = this.messages.slice(this.savedMessageCount);
86
+ if (unsavedMessages.length === 0) {
87
+ // No new messages to save
88
+ return;
83
89
  }
84
- if (sessionToRestore) {
85
- console.log(`Restoring session: ${sessionToRestore.id}`);
86
- // Initialize from session data
87
- this.initializeFromSession(sessionToRestore.id, sessionToRestore.messages, sessionToRestore.metadata.latestTotalTokens);
90
+ // Create session if needed (only when we have messages to save)
91
+ if (this.savedMessageCount === 0) {
92
+ // This is the first time saving messages, so create the session
93
+ await this.createSessionIfNeeded();
88
94
  }
95
+ // Use JSONL format for new sessions
96
+ await appendMessages(this.sessionId, unsavedMessages, // Only append new messages
97
+ this.workdir, this.sessionType);
98
+ // Update the saved message count
99
+ this.savedMessageCount = this.messages.length;
89
100
  }
90
101
  catch (error) {
91
- console.error("Failed to restore session:", error);
92
- process.exit(1);
102
+ this.logger?.error("Failed to save session:", error);
93
103
  }
94
104
  }
95
105
  setlatestTotalTokens(latestTotalTokens) {
@@ -108,17 +118,20 @@ export class MessageManager {
108
118
  clearMessages() {
109
119
  this.setMessages([]);
110
120
  this.setUserInputHistory([]);
111
- this.setSessionId(randomUUID());
121
+ this.setSessionId(generateSessionId());
112
122
  this.setlatestTotalTokens(0);
113
- this.sessionStartTime = new Date().toISOString();
123
+ this.savedMessageCount = 0; // Reset saved message count
114
124
  }
115
125
  // Initialize state from session data
116
- initializeFromSession(sessionId, messages, latestTotalTokens) {
117
- this.setSessionId(sessionId);
118
- this.setMessages([...messages]);
119
- this.setlatestTotalTokens(latestTotalTokens);
126
+ initializeFromSession(sessionData) {
127
+ this.setSessionId(sessionData.id);
128
+ this.setMessages([...sessionData.messages]);
129
+ this.setlatestTotalTokens(sessionData.metadata.latestTotalTokens);
120
130
  // Extract user input history from session messages
121
- this.setUserInputHistory(extractUserInputHistory(messages));
131
+ this.setUserInputHistory(extractUserInputHistory(sessionData.messages));
132
+ // Set saved message count to the number of loaded messages since they're already saved
133
+ // This must be done after setSessionId which resets it to 0
134
+ this.savedMessageCount = sessionData.messages.length;
122
135
  }
123
136
  // Add to input history
124
137
  addToInputHistory(input) {
@@ -142,11 +155,42 @@ export class MessageManager {
142
155
  });
143
156
  this.setMessages(newMessages);
144
157
  this.callbacks.onUserMessageAdded?.(params);
158
+ // Note: Subagent-specific callbacks are now handled by SubagentManager
145
159
  }
146
- addAssistantMessage(content, toolCalls, usage) {
147
- const newMessages = addAssistantMessageToMessages(this.messages, content, toolCalls, usage);
160
+ addAssistantMessage(content, toolCalls, usage, additionalFields) {
161
+ const additionalFieldsRecord = additionalFields
162
+ ? Object.fromEntries(Object.entries(additionalFields).filter(([, value]) => value !== undefined))
163
+ : undefined;
164
+ const newMessages = addAssistantMessageToMessages(this.messages, content, toolCalls, usage, additionalFieldsRecord);
148
165
  this.setMessages(newMessages);
149
- this.callbacks.onAssistantMessageAdded?.(content, toolCalls);
166
+ this.callbacks.onAssistantMessageAdded?.();
167
+ // Note: Subagent-specific callbacks are now handled by SubagentManager
168
+ }
169
+ mergeAssistantAdditionalFields(additionalFields) {
170
+ if (!additionalFields || Object.keys(additionalFields).length === 0) {
171
+ return;
172
+ }
173
+ const newMessages = [...this.messages];
174
+ for (let i = newMessages.length - 1; i >= 0; i--) {
175
+ const message = newMessages[i];
176
+ if (message.role === "assistant") {
177
+ const mergedAdditionalFields = {
178
+ ...(message.additionalFields || {}),
179
+ };
180
+ for (const [key, value] of Object.entries(additionalFields)) {
181
+ if (value === undefined) {
182
+ continue;
183
+ }
184
+ mergedAdditionalFields[key] = value;
185
+ }
186
+ if (Object.keys(mergedAdditionalFields).length === 0) {
187
+ return;
188
+ }
189
+ message.additionalFields = mergedAdditionalFields;
190
+ this.setMessages(newMessages);
191
+ return;
192
+ }
193
+ }
150
194
  }
151
195
  updateToolBlock(params) {
152
196
  const newMessages = updateToolBlockInMessage({
@@ -156,23 +200,16 @@ export class MessageManager {
156
200
  result: params.result,
157
201
  success: params.success,
158
202
  error: params.error,
159
- isRunning: params.isRunning,
203
+ stage: params.stage,
160
204
  name: params.name,
161
205
  shortResult: params.shortResult,
162
206
  images: params.images,
163
207
  compactParams: params.compactParams,
208
+ parametersChunk: params.parametersChunk,
164
209
  });
165
210
  this.setMessages(newMessages);
166
211
  this.callbacks.onToolBlockUpdated?.(params);
167
- }
168
- addDiffBlock(filePath, diffResult) {
169
- const newMessages = addDiffBlockToMessage({
170
- messages: this.messages,
171
- path: filePath,
172
- diffResult,
173
- });
174
- this.setMessages(newMessages);
175
- this.callbacks.onDiffBlockAdded?.(filePath, JSON.stringify(diffResult));
212
+ // Note: Subagent-specific callbacks are now handled by SubagentManager
176
213
  }
177
214
  addErrorBlock(error) {
178
215
  const newMessages = addErrorBlockToMessage({
@@ -185,7 +222,7 @@ export class MessageManager {
185
222
  /**
186
223
  * Compress messages and update session, delete compressed messages, only keep compressed messages and subsequent messages
187
224
  */
188
- compressMessagesAndUpdateSession(insertIndex, compressedContent) {
225
+ compressMessagesAndUpdateSession(insertIndex, compressedContent, usage) {
189
226
  const currentMessages = this.messages;
190
227
  // Create compressed message
191
228
  const compressMessage = {
@@ -194,8 +231,10 @@ export class MessageManager {
194
231
  {
195
232
  type: "compress",
196
233
  content: compressedContent,
234
+ sessionId: this.sessionId,
197
235
  },
198
236
  ],
237
+ ...(usage && { usage }),
199
238
  };
200
239
  // Convert negative index to positive index
201
240
  const actualIndex = insertIndex < 0 ? currentMessages.length + insertIndex : insertIndex;
@@ -205,7 +244,7 @@ export class MessageManager {
205
244
  ...currentMessages.slice(actualIndex),
206
245
  ];
207
246
  // Update sessionId
208
- this.setSessionId(randomUUID());
247
+ this.setSessionId(generateSessionId());
209
248
  // Set new message list
210
249
  this.setMessages(newMessages);
211
250
  // Trigger compression callback, insertIndex remains unchanged
@@ -250,13 +289,14 @@ export class MessageManager {
250
289
  this.callbacks.onCompleteCommandMessage?.(command, exitCode);
251
290
  }
252
291
  // Subagent block methods
253
- addSubagentBlock(subagentId, subagentName, status = "active", subagentMessages = [], parameters) {
292
+ addSubagentBlock(subagentId, subagentName, sessionId, configuration, status = "active", parameters) {
254
293
  const params = {
255
294
  messages: this.messages,
256
295
  subagentId,
257
296
  subagentName,
297
+ sessionId,
258
298
  status,
259
- subagentMessages,
299
+ configuration,
260
300
  };
261
301
  const updatedMessages = addSubagentBlockToMessage(params);
262
302
  this.setMessages(updatedMessages);
@@ -269,9 +309,8 @@ export class MessageManager {
269
309
  messages: this.messages,
270
310
  subagentId,
271
311
  status: updates.status || "active",
272
- subagentMessages: updates.messages || [],
273
312
  };
274
- this.callbacks.onSubAgentBlockUpdated?.(params.subagentId, params.messages, params.status);
313
+ this.callbacks.onSubAgentBlockUpdated?.(params.subagentId, params.status);
275
314
  }
276
315
  /**
277
316
  * Trigger usage change callback with all usage data from assistant messages
@@ -285,6 +324,78 @@ export class MessageManager {
285
324
  }
286
325
  this.callbacks.onUsagesChange?.(usages);
287
326
  }
327
+ /**
328
+ * Update the current assistant message content during streaming
329
+ * This method updates the last assistant message's content without creating a new message
330
+ * FR-001: Tracks and provides both chunk (new content) and accumulated (total content)
331
+ */
332
+ updateCurrentMessageContent(newAccumulatedContent) {
333
+ if (this.messages.length === 0)
334
+ return;
335
+ const lastMessage = this.messages[this.messages.length - 1];
336
+ if (lastMessage.role !== "assistant")
337
+ return;
338
+ // Get the current content to calculate the chunk
339
+ const textBlockIndex = lastMessage.blocks.findIndex((block) => block.type === "text");
340
+ const currentContent = textBlockIndex >= 0
341
+ ? lastMessage.blocks[textBlockIndex].content || ""
342
+ : "";
343
+ // Calculate the chunk (new content since last update)
344
+ const chunk = newAccumulatedContent.slice(currentContent.length);
345
+ if (textBlockIndex >= 0) {
346
+ // Update existing text block
347
+ lastMessage.blocks[textBlockIndex] = {
348
+ type: "text",
349
+ content: newAccumulatedContent,
350
+ };
351
+ }
352
+ else {
353
+ // Add new text block if none exists
354
+ lastMessage.blocks.push({
355
+ type: "text",
356
+ content: newAccumulatedContent,
357
+ });
358
+ }
359
+ // FR-001: Trigger callbacks with chunk and accumulated content
360
+ this.callbacks.onAssistantContentUpdated?.(chunk, newAccumulatedContent);
361
+ // Note: Subagent-specific callbacks are now handled by SubagentManager
362
+ this.callbacks.onMessagesChange?.([...this.messages]); // Still need to notify of changes
363
+ }
364
+ /**
365
+ * Update the current assistant message reasoning during streaming
366
+ * This method updates the last assistant message's reasoning content without creating a new message
367
+ */
368
+ updateCurrentMessageReasoning(newAccumulatedReasoning) {
369
+ if (this.messages.length === 0)
370
+ return;
371
+ const lastMessage = this.messages[this.messages.length - 1];
372
+ if (lastMessage.role !== "assistant")
373
+ return;
374
+ // Get the current reasoning content to calculate the chunk
375
+ const reasoningBlockIndex = lastMessage.blocks.findIndex((block) => block.type === "reasoning");
376
+ const currentReasoning = reasoningBlockIndex >= 0
377
+ ? lastMessage.blocks[reasoningBlockIndex].content || ""
378
+ : "";
379
+ // Calculate the chunk (new content since last update)
380
+ const chunk = newAccumulatedReasoning.slice(currentReasoning.length);
381
+ if (reasoningBlockIndex >= 0) {
382
+ // Update existing reasoning block
383
+ lastMessage.blocks[reasoningBlockIndex] = {
384
+ type: "reasoning",
385
+ content: newAccumulatedReasoning,
386
+ };
387
+ }
388
+ else {
389
+ // Add new reasoning block if none exists
390
+ lastMessage.blocks.push({
391
+ type: "reasoning",
392
+ content: newAccumulatedReasoning,
393
+ });
394
+ }
395
+ // Trigger callbacks with chunk and accumulated reasoning content
396
+ this.callbacks.onAssistantReasoningUpdated?.(chunk, newAccumulatedReasoning);
397
+ this.callbacks.onMessagesChange?.([...this.messages]); // Still need to notify of changes
398
+ }
288
399
  /**
289
400
  * Remove the last user message from the conversation
290
401
  * Used for hook error handling when the user prompt needs to be erased
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Permission Manager for handling tool permission checks
3
+ *
4
+ * This manager provides utilities for checking permissions before tool execution.
5
+ * It implements the permission logic for different modes (default vs bypass) and
6
+ * handles custom callback integration.
7
+ */
8
+ import type { PermissionDecision, ToolPermissionContext, PermissionCallback, PermissionMode } from "../types/permissions.js";
9
+ import type { Logger } from "../types/index.js";
10
+ export interface PermissionManagerOptions {
11
+ /** Logger for debugging permission decisions */
12
+ logger?: Logger;
13
+ /** Configured default permission mode from settings */
14
+ configuredDefaultMode?: PermissionMode;
15
+ /** Allowed rules from settings */
16
+ allowedRules?: string[];
17
+ }
18
+ export declare class PermissionManager {
19
+ private logger?;
20
+ private configuredDefaultMode?;
21
+ private allowedRules;
22
+ private onConfiguredDefaultModeChange?;
23
+ constructor(options?: PermissionManagerOptions);
24
+ /**
25
+ * Set a callback to be notified when the effective permission mode changes due to configuration updates
26
+ */
27
+ setOnConfiguredDefaultModeChange(callback: (mode: PermissionMode) => void): void;
28
+ /**
29
+ * Update the configured default mode (e.g., when configuration reloads)
30
+ */
31
+ updateConfiguredDefaultMode(defaultMode?: PermissionMode): void;
32
+ /**
33
+ * Get all currently allowed rules
34
+ */
35
+ getAllowedRules(): string[];
36
+ /**
37
+ * Update the allowed rules (e.g., when configuration reloads)
38
+ */
39
+ updateAllowedRules(rules: string[]): void;
40
+ /**
41
+ * Get the current effective permission mode for tool execution context
42
+ */
43
+ getCurrentEffectiveMode(cliPermissionMode?: PermissionMode): PermissionMode;
44
+ /**
45
+ * Resolve the effective permission mode based on CLI override and configured default
46
+ */
47
+ resolveEffectivePermissionMode(cliPermissionMode?: PermissionMode): PermissionMode;
48
+ /**
49
+ * Check if a tool execution requires permission and handle the authorization flow
50
+ * Called by individual tools after validation/diff, before real operation
51
+ */
52
+ checkPermission(context: ToolPermissionContext): Promise<PermissionDecision>;
53
+ /**
54
+ * Determine if a tool requires permission checks based on its name
55
+ */
56
+ isRestrictedTool(toolName: string): boolean;
57
+ /**
58
+ * Helper method to create a permission context for CLI integration
59
+ */
60
+ createContext(toolName: string, permissionMode: PermissionMode, callback?: PermissionCallback, toolInput?: Record<string, unknown>): ToolPermissionContext;
61
+ /**
62
+ * Check if a tool call is allowed by persistent rules
63
+ */
64
+ private isAllowedByRule;
65
+ }
66
+ //# sourceMappingURL=permissionManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissionManager.d.ts","sourceRoot":"","sources":["../../src/managers/permissionManager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACf,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,wBAAwB;IACvC,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,qBAAqB,CAAC,EAAE,cAAc,CAAC;IACvC,kCAAkC;IAClC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,qBAAqB,CAAC,CAAiB;IAC/C,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,6BAA6B,CAAC,CAAiC;gBAE3D,OAAO,GAAE,wBAA6B;IAMlD;;OAEG;IACI,gCAAgC,CACrC,QAAQ,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,GACvC,IAAI;IAIP;;OAEG;IACH,2BAA2B,CAAC,WAAW,CAAC,EAAE,cAAc,GAAG,IAAI;IAyB/D;;OAEG;IACI,eAAe,IAAI,MAAM,EAAE;IAIlC;;OAEG;IACH,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAOzC;;OAEG;IACH,uBAAuB,CAAC,iBAAiB,CAAC,EAAE,cAAc,GAAG,cAAc;IAI3E;;OAEG;IACH,8BAA8B,CAC5B,iBAAiB,CAAC,EAAE,cAAc,GACjC,cAAc;IAuBjB;;;OAGG;IACG,eAAe,CACnB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,kBAAkB,CAAC;IAqF9B;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAW3C;;OAEG;IACH,aAAa,CACX,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,cAAc,EAC9B,QAAQ,CAAC,EAAE,kBAAkB,EAC7B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,qBAAqB;IAkBxB;;OAEG;IACH,OAAO,CAAC,eAAe;CAcxB"}
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Permission Manager for handling tool permission checks
3
+ *
4
+ * This manager provides utilities for checking permissions before tool execution.
5
+ * It implements the permission logic for different modes (default vs bypass) and
6
+ * handles custom callback integration.
7
+ */
8
+ import { RESTRICTED_TOOLS } from "../types/permissions.js";
9
+ export class PermissionManager {
10
+ constructor(options = {}) {
11
+ this.allowedRules = [];
12
+ this.logger = options.logger;
13
+ this.configuredDefaultMode = options.configuredDefaultMode;
14
+ this.allowedRules = options.allowedRules || [];
15
+ }
16
+ /**
17
+ * Set a callback to be notified when the effective permission mode changes due to configuration updates
18
+ */
19
+ setOnConfiguredDefaultModeChange(callback) {
20
+ this.onConfiguredDefaultModeChange = callback;
21
+ }
22
+ /**
23
+ * Update the configured default mode (e.g., when configuration reloads)
24
+ */
25
+ updateConfiguredDefaultMode(defaultMode) {
26
+ const oldEffectiveMode = this.getCurrentEffectiveMode();
27
+ this.logger?.debug("Updating configured default permission mode", {
28
+ previous: this.configuredDefaultMode,
29
+ new: defaultMode,
30
+ });
31
+ this.configuredDefaultMode = defaultMode;
32
+ const newEffectiveMode = this.getCurrentEffectiveMode();
33
+ if (oldEffectiveMode !== newEffectiveMode &&
34
+ this.onConfiguredDefaultModeChange) {
35
+ this.logger?.debug("Effective permission mode changed due to configuration update", {
36
+ oldMode: oldEffectiveMode,
37
+ newMode: newEffectiveMode,
38
+ });
39
+ this.onConfiguredDefaultModeChange(newEffectiveMode);
40
+ }
41
+ }
42
+ /**
43
+ * Get all currently allowed rules
44
+ */
45
+ getAllowedRules() {
46
+ return [...this.allowedRules];
47
+ }
48
+ /**
49
+ * Update the allowed rules (e.g., when configuration reloads)
50
+ */
51
+ updateAllowedRules(rules) {
52
+ this.logger?.debug("Updating allowed permission rules", {
53
+ count: rules.length,
54
+ });
55
+ this.allowedRules = rules;
56
+ }
57
+ /**
58
+ * Get the current effective permission mode for tool execution context
59
+ */
60
+ getCurrentEffectiveMode(cliPermissionMode) {
61
+ return this.resolveEffectivePermissionMode(cliPermissionMode);
62
+ }
63
+ /**
64
+ * Resolve the effective permission mode based on CLI override and configured default
65
+ */
66
+ resolveEffectivePermissionMode(cliPermissionMode) {
67
+ // CLI override takes highest precedence
68
+ if (cliPermissionMode !== undefined) {
69
+ this.logger?.debug("Using CLI permission mode override", {
70
+ cliMode: cliPermissionMode,
71
+ configuredDefault: this.configuredDefaultMode,
72
+ });
73
+ return cliPermissionMode;
74
+ }
75
+ // Use configured default mode if available
76
+ if (this.configuredDefaultMode !== undefined) {
77
+ this.logger?.debug("Using configured default permission mode", {
78
+ configuredDefault: this.configuredDefaultMode,
79
+ });
80
+ return this.configuredDefaultMode;
81
+ }
82
+ // Fall back to system default
83
+ this.logger?.debug("Using system default permission mode");
84
+ return "default";
85
+ }
86
+ /**
87
+ * Check if a tool execution requires permission and handle the authorization flow
88
+ * Called by individual tools after validation/diff, before real operation
89
+ */
90
+ async checkPermission(context) {
91
+ this.logger?.debug("Checking permission for tool", {
92
+ toolName: context.toolName,
93
+ permissionMode: context.permissionMode,
94
+ hasCallback: !!context.canUseToolCallback,
95
+ });
96
+ // 1. If bypassPermissions mode, always allow
97
+ if (context.permissionMode === "bypassPermissions") {
98
+ this.logger?.debug("Permission bypassed for tool", {
99
+ toolName: context.toolName,
100
+ });
101
+ return { behavior: "allow" };
102
+ }
103
+ // 1.1 If acceptEdits mode, allow Edit, MultiEdit, Delete, Write
104
+ if (context.permissionMode === "acceptEdits") {
105
+ const autoAcceptedTools = ["Edit", "MultiEdit", "Delete", "Write"];
106
+ if (autoAcceptedTools.includes(context.toolName)) {
107
+ this.logger?.debug("Permission automatically accepted for tool in acceptEdits mode", {
108
+ toolName: context.toolName,
109
+ });
110
+ return { behavior: "allow" };
111
+ }
112
+ }
113
+ // 1.2 Check if tool call matches any allowed rule
114
+ if (this.isAllowedByRule(context)) {
115
+ this.logger?.debug("Permission allowed by persistent rule", {
116
+ toolName: context.toolName,
117
+ });
118
+ return { behavior: "allow" };
119
+ }
120
+ // 2. If not a restricted tool, always allow
121
+ if (!this.isRestrictedTool(context.toolName)) {
122
+ this.logger?.debug("Tool is not restricted, allowing", {
123
+ toolName: context.toolName,
124
+ });
125
+ return { behavior: "allow" };
126
+ }
127
+ // 3. If custom callback provided, call it and return result
128
+ if (context.canUseToolCallback) {
129
+ try {
130
+ this.logger?.debug("Calling custom permission callback for tool", {
131
+ toolName: context.toolName,
132
+ });
133
+ const decision = await context.canUseToolCallback(context);
134
+ this.logger?.debug("Custom callback returned decision", {
135
+ toolName: context.toolName,
136
+ decision,
137
+ });
138
+ return decision;
139
+ }
140
+ catch (error) {
141
+ const errorMessage = error instanceof Error ? error.message : String(error);
142
+ this.logger?.error("Error in permission callback", {
143
+ toolName: context.toolName,
144
+ error: errorMessage,
145
+ });
146
+ return {
147
+ behavior: "deny",
148
+ message: "Error in permission callback",
149
+ };
150
+ }
151
+ }
152
+ // 4. For default mode on restricted tools without callback, integrate with CLI confirmation
153
+ // Note: CLI confirmation integration will be implemented in Phase 2
154
+ this.logger?.warn("No permission callback provided for restricted tool in default mode", {
155
+ toolName: context.toolName,
156
+ });
157
+ return {
158
+ behavior: "deny",
159
+ message: `Tool '${context.toolName}' requires permission approval. No permission callback configured.`,
160
+ };
161
+ }
162
+ /**
163
+ * Determine if a tool requires permission checks based on its name
164
+ */
165
+ isRestrictedTool(toolName) {
166
+ const isRestricted = RESTRICTED_TOOLS.includes(toolName);
167
+ this.logger?.debug("Checking if tool is restricted", {
168
+ toolName,
169
+ isRestricted,
170
+ });
171
+ return isRestricted;
172
+ }
173
+ /**
174
+ * Helper method to create a permission context for CLI integration
175
+ */
176
+ createContext(toolName, permissionMode, callback, toolInput) {
177
+ const context = {
178
+ toolName,
179
+ permissionMode,
180
+ canUseToolCallback: callback,
181
+ toolInput,
182
+ };
183
+ this.logger?.debug("Created permission context", {
184
+ toolName,
185
+ permissionMode,
186
+ hasCallback: !!callback,
187
+ hasToolInput: !!toolInput,
188
+ });
189
+ return context;
190
+ }
191
+ /**
192
+ * Check if a tool call is allowed by persistent rules
193
+ */
194
+ isAllowedByRule(context) {
195
+ if (context.toolName === "Bash" && context.toolInput?.command) {
196
+ const action = `Bash(${context.toolInput.command})`;
197
+ return this.allowedRules.some((rule) => {
198
+ if (rule.endsWith(":*)")) {
199
+ const prefix = rule.slice(0, -3);
200
+ return action.startsWith(prefix);
201
+ }
202
+ return action === rule;
203
+ });
204
+ }
205
+ // Add other tools if needed in the future
206
+ return false;
207
+ }
208
+ }
@@ -6,6 +6,7 @@ export declare class SkillManager {
6
6
  private personalSkillsPath;
7
7
  private scanTimeout;
8
8
  private logger?;
9
+ private workdir;
9
10
  private skillMetadata;
10
11
  private skillContent;
11
12
  private initialized;
@@ -1 +1 @@
1
- {"version":3,"file":"skillManager.d.ts","sourceRoot":"","sources":["../../src/managers/skillManager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EACb,KAAK,EAGL,aAAa,EACb,sBAAsB,EAEvB,MAAM,mBAAmB,CAAC;AAG3B;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAC,CAAS;IAExB,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,GAAE,mBAAwB;IAO7C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAwCjC;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,kBAAkB,IAAI,aAAa,EAAE;IAQrC;;;OAGG;IACG,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAgBzD;;OAEG;YACW,cAAc;IAkB5B;;OAEG;YACW,uBAAuB;IAiFrC;;OAEG;YACW,oBAAoB;IAkBlC;;OAEG;IACG,YAAY,CAChB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,sBAAsB,CAAA;KAAE,CAAC;IAqCjE;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAY1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAa9B"}
1
+ {"version":3,"file":"skillManager.d.ts","sourceRoot":"","sources":["../../src/managers/skillManager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EACb,KAAK,EAGL,aAAa,EACb,sBAAsB,EAEvB,MAAM,mBAAmB,CAAC;AAG3B;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,GAAE,mBAAwB;IAQ7C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAwCjC;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,kBAAkB,IAAI,aAAa,EAAE;IAQrC;;;OAGG;IACG,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAgBzD;;OAEG;YACW,cAAc;IAkB5B;;OAEG;YACW,uBAAuB;IAiFrC;;OAEG;YACW,oBAAoB;IAkBlC;;OAEG;IACG,YAAY,CAChB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,sBAAsB,CAAA;KAAE,CAAC;IAqCjE;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAY1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAa9B"}