@codemieai/code 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/agents/core/AgentCLI.d.ts.map +1 -1
  2. package/dist/agents/core/AgentCLI.js +11 -3
  3. package/dist/agents/core/AgentCLI.js.map +1 -1
  4. package/dist/agents/core/BaseAgentAdapter.d.ts +3 -1
  5. package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
  6. package/dist/agents/core/BaseAgentAdapter.js +34 -2
  7. package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
  8. package/dist/agents/core/config-redaction.d.ts +7 -0
  9. package/dist/agents/core/config-redaction.d.ts.map +1 -0
  10. package/dist/agents/core/config-redaction.js +20 -0
  11. package/dist/agents/core/config-redaction.js.map +1 -0
  12. package/dist/agents/core/print-config.d.ts +8 -0
  13. package/dist/agents/core/print-config.d.ts.map +1 -0
  14. package/dist/agents/core/print-config.js +17 -0
  15. package/dist/agents/core/print-config.js.map +1 -0
  16. package/dist/agents/core/session/BaseSessionAdapter.d.ts +5 -1
  17. package/dist/agents/core/session/BaseSessionAdapter.d.ts.map +1 -1
  18. package/dist/agents/core/types.d.ts +34 -4
  19. package/dist/agents/core/types.d.ts.map +1 -1
  20. package/dist/agents/plugins/claude/claude.plugin.d.ts.map +1 -1
  21. package/dist/agents/plugins/claude/claude.plugin.js +73 -0
  22. package/dist/agents/plugins/claude/claude.plugin.js.map +1 -1
  23. package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.d.ts.map +1 -1
  24. package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js +115 -32
  25. package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js.map +1 -1
  26. package/dist/agents/plugins/claude/settings-conflict.d.ts +8 -0
  27. package/dist/agents/plugins/claude/settings-conflict.d.ts.map +1 -0
  28. package/dist/agents/plugins/claude/settings-conflict.js +35 -0
  29. package/dist/agents/plugins/claude/settings-conflict.js.map +1 -0
  30. package/dist/agents/plugins/codemie-code-hooks/shell-hooks-source.d.ts +14 -2
  31. package/dist/agents/plugins/codemie-code-hooks/shell-hooks-source.d.ts.map +1 -1
  32. package/dist/agents/plugins/codemie-code-hooks/shell-hooks-source.js +218 -263
  33. package/dist/agents/plugins/codemie-code-hooks/shell-hooks-source.js.map +1 -1
  34. package/dist/agents/plugins/opencode/opencode-message-types.d.ts +13 -0
  35. package/dist/agents/plugins/opencode/opencode-message-types.d.ts.map +1 -1
  36. package/dist/agents/plugins/opencode/opencode-message-types.js.map +1 -1
  37. package/dist/agents/plugins/opencode/opencode.incremental-sync.d.ts +38 -0
  38. package/dist/agents/plugins/opencode/opencode.incremental-sync.d.ts.map +1 -0
  39. package/dist/agents/plugins/opencode/opencode.incremental-sync.js +153 -0
  40. package/dist/agents/plugins/opencode/opencode.incremental-sync.js.map +1 -0
  41. package/dist/agents/plugins/opencode/opencode.paths.d.ts +18 -2
  42. package/dist/agents/plugins/opencode/opencode.paths.d.ts.map +1 -1
  43. package/dist/agents/plugins/opencode/opencode.paths.js +39 -6
  44. package/dist/agents/plugins/opencode/opencode.paths.js.map +1 -1
  45. package/dist/agents/plugins/opencode/opencode.plugin.d.ts.map +1 -1
  46. package/dist/agents/plugins/opencode/opencode.plugin.js +241 -75
  47. package/dist/agents/plugins/opencode/opencode.plugin.js.map +1 -1
  48. package/dist/agents/plugins/opencode/opencode.session.d.ts +18 -1
  49. package/dist/agents/plugins/opencode/opencode.session.d.ts.map +1 -1
  50. package/dist/agents/plugins/opencode/opencode.session.js +58 -17
  51. package/dist/agents/plugins/opencode/opencode.session.js.map +1 -1
  52. package/dist/agents/plugins/opencode/opencode.sqlite-reader.d.ts +8 -2
  53. package/dist/agents/plugins/opencode/opencode.sqlite-reader.d.ts.map +1 -1
  54. package/dist/agents/plugins/opencode/opencode.sqlite-reader.js +67 -42
  55. package/dist/agents/plugins/opencode/opencode.sqlite-reader.js.map +1 -1
  56. package/dist/agents/plugins/opencode/opencode.storage-utils.d.ts +19 -0
  57. package/dist/agents/plugins/opencode/opencode.storage-utils.d.ts.map +1 -1
  58. package/dist/agents/plugins/opencode/opencode.storage-utils.js +51 -0
  59. package/dist/agents/plugins/opencode/opencode.storage-utils.js.map +1 -1
  60. package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.d.ts +13 -19
  61. package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.d.ts.map +1 -1
  62. package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.js +339 -82
  63. package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.js.map +1 -1
  64. package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.d.ts +37 -33
  65. package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.d.ts.map +1 -1
  66. package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.js +204 -246
  67. package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.js.map +1 -1
  68. package/dist/cli/commands/proxy/connectors/desktop.d.ts.map +1 -1
  69. package/dist/cli/commands/proxy/connectors/desktop.js +6 -0
  70. package/dist/cli/commands/proxy/connectors/desktop.js.map +1 -1
  71. package/dist/cli/commands/proxy/connectors/vscode-models.d.ts +21 -0
  72. package/dist/cli/commands/proxy/connectors/vscode-models.d.ts.map +1 -0
  73. package/dist/cli/commands/proxy/connectors/vscode-models.js +286 -0
  74. package/dist/cli/commands/proxy/connectors/vscode-models.js.map +1 -0
  75. package/dist/cli/commands/proxy/connectors/vscode.d.ts +2 -2
  76. package/dist/cli/commands/proxy/connectors/vscode.d.ts.map +1 -1
  77. package/dist/cli/commands/proxy/connectors/vscode.js +47 -66
  78. package/dist/cli/commands/proxy/connectors/vscode.js.map +1 -1
  79. package/dist/cli/commands/proxy/health-check.d.ts.map +1 -1
  80. package/dist/cli/commands/proxy/health-check.js +9 -0
  81. package/dist/cli/commands/proxy/health-check.js.map +1 -1
  82. package/dist/cli/commands/proxy/index.d.ts.map +1 -1
  83. package/dist/cli/commands/proxy/index.js +10 -13
  84. package/dist/cli/commands/proxy/index.js.map +1 -1
  85. package/dist/cli/commands/setup.d.ts +31 -0
  86. package/dist/cli/commands/setup.d.ts.map +1 -1
  87. package/dist/cli/commands/setup.js +137 -45
  88. package/dist/cli/commands/setup.js.map +1 -1
  89. package/dist/providers/core/types.d.ts +12 -1
  90. package/dist/providers/core/types.d.ts.map +1 -1
  91. package/dist/providers/core/types.js.map +1 -1
  92. package/dist/providers/plugins/bedrock/bedrock.template.d.ts.map +1 -1
  93. package/dist/providers/plugins/bedrock/bedrock.template.js +21 -2
  94. package/dist/providers/plugins/bedrock/bedrock.template.js.map +1 -1
  95. package/dist/providers/plugins/litellm/litellm.setup-steps.d.ts.map +1 -1
  96. package/dist/providers/plugins/litellm/litellm.setup-steps.js +21 -5
  97. package/dist/providers/plugins/litellm/litellm.setup-steps.js.map +1 -1
  98. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts +7 -6
  99. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts.map +1 -1
  100. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js +13 -7
  101. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js.map +1 -1
  102. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts +2 -1
  103. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts.map +1 -1
  104. package/dist/providers/plugins/sso/proxy/plugins/index.js +4 -2
  105. package/dist/providers/plugins/sso/proxy/plugins/index.js.map +1 -1
  106. package/dist/providers/plugins/sso/proxy/plugins/vscode-request-normalizer.plugin.d.ts +22 -0
  107. package/dist/providers/plugins/sso/proxy/plugins/vscode-request-normalizer.plugin.d.ts.map +1 -0
  108. package/dist/providers/plugins/sso/proxy/plugins/vscode-request-normalizer.plugin.js +69 -0
  109. package/dist/providers/plugins/sso/proxy/plugins/vscode-request-normalizer.plugin.js.map +1 -0
  110. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js +3 -0
  111. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js.map +1 -1
  112. package/dist/utils/config.d.ts +6 -2
  113. package/dist/utils/config.d.ts.map +1 -1
  114. package/dist/utils/config.js +30 -8
  115. package/dist/utils/config.js.map +1 -1
  116. package/dist/utils/extensions-scan.d.ts.map +1 -1
  117. package/dist/utils/extensions-scan.js +59 -22
  118. package/dist/utils/extensions-scan.js.map +1 -1
  119. package/dist/utils/mcp-config.d.ts.map +1 -1
  120. package/dist/utils/mcp-config.js +11 -6
  121. package/dist/utils/mcp-config.js.map +1 -1
  122. package/package.json +2 -1
@@ -1,118 +1,375 @@
1
- import { isTextPart, isToolPart, isFilePart, isReasoningPart } from '../../opencode-message-types.js';
2
- import { logger } from '../../../../../utils/logger.js';
1
+ // src/agents/plugins/opencode/session/processors/opencode.conversations-processor.ts
3
2
  /**
4
3
  * OpenCode Conversations Processor
5
4
  *
6
- * Normalizes OpenCode messages and parts into unified conversation format.
7
- * Implements SessionProcessor interface for processor chain.
5
+ * Transforms OpenCode messages and parts into incremental CodeMie conversation
6
+ * payloads and queues them in {sessionId}_conversation.jsonl, where the shared
7
+ * conversation-sync processor picks them up and PUTs them to
8
+ * /v1/conversations/{id}/history.
9
+ *
10
+ * Shape matches the other agents: the visible history holds the user prompt and
11
+ * the assistant's reply, while tool calls and reasoning are attached as
12
+ * `thoughts` on the assistant entry.
13
+ *
14
+ * Structurally modelled on codex.conversations-processor.ts — same checkpoint
15
+ * sentinel, turn-continuation handling and syncUpdates contract.
8
16
  */
17
+ import { isTextPart, isToolPart, isReasoningPart, } from '../../opencode-message-types.js';
18
+ import { CONVERSATION_SYNC_STATUS } from '../../../../../providers/plugins/sso/session/processors/conversations/types.js';
19
+ import { CODEMIE_ASSISTANT_ID } from '../../../../../providers/plugins/sso/session/processors/conversations/constants.js';
20
+ import { getSessionConversationPath } from '../../../../core/session/session-config.js';
21
+ import { loadPartsForMessage } from '../../opencode.storage-utils.js';
22
+ import { logger } from '../../../../../utils/logger.js';
23
+ /**
24
+ * The conversation folder these payloads are filed under in CodeMie.
25
+ * Set explicitly so the payload does not depend on the sync processor's
26
+ * client-type fallback, which defaults to 'Claude Desktop'.
27
+ */
28
+ const OPENCODE_CONVERSATION_FOLDER = 'opencode';
9
29
  export class OpenCodeConversationsProcessor {
10
30
  name = 'opencode-conversations';
11
31
  priority = 2; // Run after metrics
12
- /**
13
- * Check if session has data to process
14
- */
15
32
  shouldProcess(session) {
16
33
  if (process.env.CODEMIE_CONV_SYNC_DISABLED === '1')
17
34
  return false;
18
35
  return session.messages.length > 0;
19
36
  }
20
- /**
21
- * Process session to normalize conversations
22
- */
37
+ // _context is intentionally unused: conversation identity comes from
38
+ // session.metadata.openCodeSessionId, never from context.agentSessionId,
39
+ // which differs between the timer/Stop and in-process SessionEnd paths.
23
40
  async process(session, _context) {
24
41
  try {
25
- const messages = session.messages;
26
- const normalizedMessages = [];
27
- for (const message of messages) {
28
- // UPDATED (GPT-5.9): Use time.created (numeric) instead of createdAt (string)
29
- // For full implementation, parts would be loaded from part/{messageId}/*.json
30
- // For now, create basic normalized message from message data
31
- const normalized = {
32
- id: message.id,
33
- role: message.role,
34
- content: '', // Would be populated from text parts (AC-EXT-1)
35
- // UPDATED (GPT-5.9): Convert numeric timestamp to ISO string
36
- timestamp: message.time?.created
37
- ? new Date(message.time.created).toISOString()
38
- : new Date().toISOString(),
39
- // UPDATED (GPT-5.9): modelID is on assistant messages only
40
- model: message.role === 'assistant'
41
- ? message.modelID
42
- : undefined,
43
- agent: message.role === 'assistant'
44
- ? message.agent
45
- : undefined
42
+ const metadata = session.metadata;
43
+ const openCodeSessionId = metadata?.openCodeSessionId;
44
+ const storagePath = metadata?.storagePath;
45
+ if (!openCodeSessionId || !storagePath) {
46
+ return {
47
+ success: false,
48
+ message: 'Missing openCodeSessionId or storagePath in session.metadata',
49
+ metadata: { failureReason: 'NO_OPENCODE_SESSION_ID' }
46
50
  };
47
- normalizedMessages.push(normalized);
48
51
  }
49
- logger.debug(`[opencode-conversations] Normalized ${normalizedMessages.length} messages`);
52
+ const messages = session.messages;
53
+ const events = await normalizeEvents(messages, storagePath, openCodeSessionId, metadata?.partsMap);
54
+ logger.debug(`[opencode-conversations] Normalised ${events.length} events from ${messages.length} messages`);
55
+ if (events.length === 0) {
56
+ return { success: true, message: 'No conversation events generated', metadata: { recordsProcessed: 0 } };
57
+ }
58
+ const { SessionStore } = await import('../../../../core/session/SessionStore.js');
59
+ const sessionStore = new SessionStore();
60
+ const sessionMetadata = await sessionStore.loadSession(session.sessionId);
61
+ const persistedHistoryIndex = sessionMetadata?.sync?.conversations?.lastSyncedHistoryIndex ?? -1;
62
+ const lastSyncedSourceIndex = parseLastSyncedSourceIndex(sessionMetadata?.sync?.conversations?.lastSyncedMessageUuid, persistedHistoryIndex);
63
+ const conversationsPath = getSessionConversationPath(session.sessionId);
64
+ const { readJSONL } = await import('../../../../../providers/plugins/sso/session/utils/jsonl-reader.js');
65
+ const existingPayloads = await readJSONL(conversationsPath);
66
+ // Payloads already queued but not yet uploaded also advance the watermark,
67
+ // otherwise every tick re-queues the same turn.
68
+ const queuedCheckpoint = getQueuedCheckpoint(existingPayloads);
69
+ const effectiveSourceIndex = Math.max(lastSyncedSourceIndex, queuedCheckpoint.sourceIndex);
70
+ const effectiveHistoryIndex = Math.max(persistedHistoryIndex, queuedCheckpoint.historyIndex);
71
+ const turn = buildIncrementalTurn(events, effectiveSourceIndex, effectiveHistoryIndex);
72
+ if (!turn) {
73
+ logger.debug(`[opencode-conversations] No complete turn past source index ${effectiveSourceIndex} for ${openCodeSessionId}`);
74
+ return { success: true, message: 'No new conversation messages', metadata: { recordsProcessed: 0 } };
75
+ }
76
+ const newTurnEvents = turn.events.filter(event => event.sourceIndex > effectiveSourceIndex);
77
+ const endSourceIndex = Math.max(...newTurnEvents.map(event => event.sourceIndex));
78
+ const sentinel = `${openCodeSessionId}@${endSourceIndex}`;
79
+ if (existingPayloads.some(payload => payload.lastProcessedMessageUuid === sentinel)) {
80
+ logger.debug(`[opencode-conversations] Window ${sentinel} already queued, skipping`);
81
+ return { success: true, message: 'Window already queued', metadata: { recordsProcessed: 0 } };
82
+ }
83
+ const history = turnToHistory(turn, effectiveSourceIndex);
84
+ if (history.length === 0) {
85
+ logger.debug(`[opencode-conversations] Turn resolved but produced no visible history for ${sentinel}`);
86
+ return { success: true, message: 'No visible history generated', metadata: { recordsProcessed: 0 } };
87
+ }
88
+ const { appendFile, mkdir } = await import('fs/promises');
89
+ const { dirname } = await import('path');
90
+ await mkdir(dirname(conversationsPath), { recursive: true });
91
+ const payloadRecord = {
92
+ payloadId: sentinel,
93
+ timestamp: Date.now(),
94
+ isTurnContinuation: turn.isTurnContinuation,
95
+ historyIndices: history.map(entry => entry.history_index),
96
+ messageCount: history.length,
97
+ lastProcessedMessageUuid: sentinel,
98
+ payload: {
99
+ // Always the opencode ses_* id, never context.agentSessionId. That
100
+ // field carries ses_* on the timer and Stop paths but the CodeMie UUID
101
+ // on the in-process SessionEnd path, and conversationId is the PUT
102
+ // path id — so keying off it filed a session's final turn under a
103
+ // second conversation and split the history in two. The checkpoint
104
+ // sentinel already keys on openCodeSessionId, so this is the identity
105
+ // the rest of the pipeline is built around.
106
+ conversationId: openCodeSessionId,
107
+ assistantId: CODEMIE_ASSISTANT_ID,
108
+ folder: OPENCODE_CONVERSATION_FOLDER,
109
+ llmModel: resolveTurnModel(turn.events),
110
+ history,
111
+ },
112
+ status: CONVERSATION_SYNC_STATUS.PENDING,
113
+ };
114
+ await appendFile(conversationsPath, JSON.stringify(payloadRecord) + '\n', 'utf-8');
50
115
  return {
51
116
  success: true,
52
- message: `Normalized ${normalizedMessages.length} messages`,
117
+ message: `Generated 1 conversation payload from ${newTurnEvents.length} new events`,
53
118
  metadata: {
54
- recordsProcessed: normalizedMessages.length,
55
- userMessages: normalizedMessages.filter(m => m.role === 'user').length,
56
- assistantMessages: normalizedMessages.filter(m => m.role === 'assistant').length
119
+ recordsProcessed: newTurnEvents.length,
120
+ userMessages: history.filter(entry => entry.role === 'User').length,
121
+ assistantMessages: history.filter(entry => entry.role === 'Assistant').length,
122
+ syncUpdates: {
123
+ conversations: {
124
+ lastSyncedMessageUuid: sentinel,
125
+ lastSyncedHistoryIndex: turn.historyIndex,
126
+ // Same identity as payload.conversationId above — see the note there.
127
+ conversationId: openCodeSessionId,
128
+ totalMessagesSynced: history.length,
129
+ totalSyncAttempts: 1,
130
+ lastSyncAt: Date.now(),
131
+ },
132
+ },
57
133
  }
58
134
  };
59
135
  }
60
136
  catch (error) {
61
137
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
62
- logger.error(`[opencode-conversations] Processing failed:`, error);
63
- return {
64
- success: false,
65
- message: `Conversations processing failed: ${errorMessage}`
66
- };
138
+ logger.error('[opencode-conversations] Processing failed:', error);
139
+ return { success: false, message: `Conversations processing failed: ${errorMessage}` };
67
140
  }
68
141
  }
69
- /**
70
- * Process parts for a message (helper for full implementation)
71
- * Parts are loaded from part/{messageID}/*.json
72
- *
73
- * UPDATED (GPT-5.9): Use new part schema:
74
- * - Tool parts: callID, tool, state.input, state (not toolName, toolInput, toolOutput)
75
- * - File parts: mime, url, source, filename (not filePath, content)
76
- */
77
- processParts(parts) {
78
- const textParts = [];
79
- const toolUse = [];
80
- const fileReferences = [];
81
- const thinkingParts = [];
142
+ }
143
+ /**
144
+ * Flatten messages and their parts into a single ordered event stream.
145
+ *
146
+ * `sourceIndex` counts across the flattened (message, part) sequence. OpenCode
147
+ * only ever appends — new parts land on the newest message, new messages at the
148
+ * end — so an index already emitted keeps its position on later ticks, which is
149
+ * what makes it usable as a sync watermark.
150
+ */
151
+ async function normalizeEvents(messages, storagePath, openCodeSessionId, partsMap) {
152
+ const events = [];
153
+ let sourceIndex = 0;
154
+ for (const message of messages) {
155
+ const date = toIsoDate(message.time?.created);
156
+ const parts = await loadPartsForMessage(storagePath, message.id, openCodeSessionId, partsMap);
157
+ if (message.role === 'user') {
158
+ // Burn the index unconditionally, exactly as the assistant branch does.
159
+ // A user message whose parts have not flushed yet yields no text on this
160
+ // tick but will on the next one; consuming the index only when text is
161
+ // present would shift every later sourceIndex by one between ticks and
162
+ // silently move the checkpoint onto a different event.
163
+ const index = sourceIndex++;
164
+ const text = parts
165
+ .filter(part => isTextPart(part) && !isIgnoredPart(part))
166
+ .map(part => part.text)
167
+ .filter(value => value?.trim())
168
+ .join('\n');
169
+ if (text) {
170
+ events.push({ kind: 'user_prompt', sourceIndex: index, date, text });
171
+ }
172
+ continue;
173
+ }
174
+ const assistant = message;
175
+ // Bare model id, consistent with the metrics pipeline.
176
+ const model = assistant.modelID?.trim() || undefined;
82
177
  for (const part of parts) {
83
- // Use type guards for safe narrowing
84
- if (isTextPart(part)) {
85
- textParts.push(part.text);
178
+ const index = sourceIndex++;
179
+ if (isReasoningPart(part)) {
180
+ if (part.text?.trim()) {
181
+ events.push({ kind: 'reasoning', sourceIndex: index, date, text: part.text, model });
182
+ }
183
+ continue;
86
184
  }
87
- else if (isToolPart(part)) {
88
- // UPDATED (GPT-5.9): New tool part schema
89
- toolUse.push({
90
- name: part.tool, // Was: part.toolName
91
- input: part.state.input || {}, // Input is inside state
92
- output: part.state?.output // Was: part.toolOutput
185
+ if (isToolPart(part)) {
186
+ events.push({
187
+ kind: 'tool_call',
188
+ sourceIndex: index,
189
+ date,
190
+ callId: part.callID || part.id,
191
+ toolName: part.tool,
192
+ inputText: stringify(part.state.input),
193
+ text: part.state.status === 'error'
194
+ ? (part.state.error ?? '')
195
+ : stringify(part.state.output),
196
+ error: part.state.status === 'error',
197
+ model,
93
198
  });
199
+ continue;
94
200
  }
95
- else if (isFilePart(part)) {
96
- // UPDATED (GPT-5.9): New file part schema
97
- // Use url or construct reference from filename
98
- if (part.url) {
99
- fileReferences.push(part.url);
100
- }
101
- else if (part.filename) {
102
- fileReferences.push(part.filename);
103
- }
201
+ if (isTextPart(part) && !isIgnoredPart(part) && part.text?.trim()) {
202
+ events.push({ kind: 'assistant_reply', sourceIndex: index, date, text: part.text, model });
104
203
  }
105
- else if (isReasoningPart(part)) {
106
- thinkingParts.push(part.text);
204
+ }
205
+ }
206
+ return events;
207
+ }
208
+ /**
209
+ * Resolve the window of events to publish next.
210
+ *
211
+ * A turn runs from a user prompt to the next user prompt. When new events land
212
+ * inside a turn that was already partially published, the turn is re-emitted as
213
+ * a continuation under its original history index so the backend appends rather
214
+ * than duplicating.
215
+ */
216
+ function buildIncrementalTurn(events, effectiveSourceIndex, effectiveHistoryIndex) {
217
+ const firstNewEvent = events.find(event => event.sourceIndex > effectiveSourceIndex);
218
+ if (!firstNewEvent)
219
+ return null;
220
+ const userEvents = events.filter(event => event.kind === 'user_prompt');
221
+ let userEvent;
222
+ let historyIndex = effectiveHistoryIndex;
223
+ let isTurnContinuation = false;
224
+ if (firstNewEvent.kind === 'user_prompt') {
225
+ userEvent = firstNewEvent;
226
+ historyIndex = effectiveHistoryIndex + 1;
227
+ }
228
+ else {
229
+ for (let index = userEvents.length - 1; index >= 0; index -= 1) {
230
+ if (userEvents[index].sourceIndex < firstNewEvent.sourceIndex) {
231
+ userEvent = userEvents[index];
232
+ break;
107
233
  }
108
- // step-finish parts are skipped (metadata only - tokens/cost handled by metrics)
109
234
  }
110
- return {
111
- content: textParts.join('\n'),
112
- toolUse: toolUse.length > 0 ? toolUse : undefined,
113
- fileReferences: fileReferences.length > 0 ? fileReferences : [],
114
- thinking: thinkingParts.join('\n')
115
- };
235
+ if (!userEvent || effectiveHistoryIndex < 0)
236
+ return null;
237
+ historyIndex = effectiveHistoryIndex;
238
+ isTurnContinuation = true;
239
+ }
240
+ const nextUserEvent = userEvents.find(event => event.sourceIndex > userEvent.sourceIndex);
241
+ const turnEndExclusive = nextUserEvent?.sourceIndex ?? Number.MAX_SAFE_INTEGER;
242
+ const turnEvents = events.filter(event => event.sourceIndex >= userEvent.sourceIndex && event.sourceIndex < turnEndExclusive);
243
+ const hasNewReply = turnEvents.some(event => event.kind === 'assistant_reply' && event.sourceIndex > effectiveSourceIndex);
244
+ const shouldEmitUser = userEvent.sourceIndex > effectiveSourceIndex;
245
+ // Hold the turn back until the assistant has actually said something —
246
+ // publishing a prompt with no reply would leave a dangling history entry.
247
+ if (!shouldEmitUser && !hasNewReply)
248
+ return null;
249
+ return { user: userEvent, events: turnEvents, historyIndex, isTurnContinuation };
250
+ }
251
+ function turnToHistory(turn, effectiveSourceIndex) {
252
+ const history = [];
253
+ const finalReply = getFinalReply(turn.events);
254
+ if (turn.user.sourceIndex > effectiveSourceIndex) {
255
+ history.push({
256
+ role: 'User',
257
+ message: turn.user.text,
258
+ message_raw: turn.user.text,
259
+ date: turn.user.date,
260
+ history_index: turn.historyIndex,
261
+ file_names: [],
262
+ });
263
+ }
264
+ if (finalReply && finalReply.sourceIndex > effectiveSourceIndex) {
265
+ const thoughts = buildThoughts(turn.events, turn.historyIndex);
266
+ history.push({
267
+ role: 'Assistant',
268
+ message: finalReply.text,
269
+ message_raw: finalReply.text,
270
+ date: finalReply.date,
271
+ history_index: turn.historyIndex,
272
+ response_time: calculateResponseTime(turn.user.date, finalReply.date),
273
+ assistant_id: CODEMIE_ASSISTANT_ID,
274
+ ...(thoughts.length > 0 && { thoughts }),
275
+ });
276
+ }
277
+ return history;
278
+ }
279
+ /**
280
+ * Build the thought tree hung off the assistant entry: one node per tool call
281
+ * (input and output together, since OpenCode keeps both on the same part) and
282
+ * one per reasoning block.
283
+ */
284
+ function buildThoughts(events, historyIndex) {
285
+ const thoughts = [];
286
+ for (const event of events) {
287
+ if (event.kind === 'user_prompt' || event.kind === 'assistant_reply')
288
+ continue;
289
+ const isTool = event.kind === 'tool_call';
290
+ thoughts.push({
291
+ id: isTool
292
+ ? (event.callId || `opencode-tool-${historyIndex}-${event.sourceIndex}`)
293
+ : `opencode-reasoning-${historyIndex}-${event.sourceIndex}`,
294
+ parent_id: null,
295
+ metadata: {
296
+ timestamp: event.date,
297
+ source_index: event.sourceIndex,
298
+ event_kind: event.kind,
299
+ ...(isTool && { call_id: event.callId }),
300
+ },
301
+ in_progress: false,
302
+ input_text: event.inputText ?? '',
303
+ message: event.text || (isTool ? '' : '[reasoning]'),
304
+ author_type: isTool ? 'Tool' : 'Agent',
305
+ author_name: isTool ? (event.toolName || 'Unknown Tool') : 'OpenCode Reasoning',
306
+ output_format: 'text',
307
+ error: event.error === true,
308
+ interrupted: false,
309
+ aborted: false,
310
+ children: [],
311
+ });
312
+ }
313
+ return thoughts;
314
+ }
315
+ function getFinalReply(events) {
316
+ for (let index = events.length - 1; index >= 0; index -= 1) {
317
+ if (events[index].kind === 'assistant_reply')
318
+ return events[index];
319
+ }
320
+ return undefined;
321
+ }
322
+ function resolveTurnModel(events) {
323
+ for (let index = events.length - 1; index >= 0; index -= 1) {
324
+ if (events[index].model)
325
+ return events[index].model;
326
+ }
327
+ return undefined;
328
+ }
329
+ /** Parts OpenCode marks as ignored or synthetic are not user-authored content. */
330
+ function isIgnoredPart(part) {
331
+ const flags = part;
332
+ return flags.ignored === true || flags.synthetic === true;
333
+ }
334
+ function stringify(value) {
335
+ if (value === undefined || value === null)
336
+ return '';
337
+ if (typeof value === 'string')
338
+ return value;
339
+ try {
340
+ return JSON.stringify(value);
341
+ }
342
+ catch {
343
+ return String(value);
344
+ }
345
+ }
346
+ function toIsoDate(timestamp) {
347
+ return new Date(typeof timestamp === 'number' && timestamp > 0 ? timestamp : Date.now()).toISOString();
348
+ }
349
+ function parseLastSyncedSourceIndex(value, fallback) {
350
+ if (typeof value === 'string') {
351
+ const index = Number.parseInt(value.slice(value.lastIndexOf('@') + 1), 10);
352
+ if (Number.isFinite(index))
353
+ return index;
354
+ }
355
+ return fallback;
356
+ }
357
+ function getQueuedCheckpoint(payloads) {
358
+ let sourceIndex = -1;
359
+ let historyIndex = -1;
360
+ for (const payload of payloads) {
361
+ sourceIndex = Math.max(sourceIndex, parseLastSyncedSourceIndex(payload.lastProcessedMessageUuid, -1));
362
+ if (payload.historyIndices.length > 0) {
363
+ historyIndex = Math.max(historyIndex, Math.max(...payload.historyIndices));
364
+ }
116
365
  }
366
+ return { sourceIndex, historyIndex };
367
+ }
368
+ function calculateResponseTime(start, end) {
369
+ const startMs = new Date(start).getTime();
370
+ const endMs = new Date(end).getTime();
371
+ if (Number.isNaN(startMs) || Number.isNaN(endMs))
372
+ return undefined;
373
+ return Math.max(0, Math.round(((endMs - startMs) / 1000) * 100) / 100);
117
374
  }
118
375
  //# sourceMappingURL=opencode.conversations-processor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"opencode.conversations-processor.js","sourceRoot":"","sources":["../../../../../../src/agents/plugins/opencode/session/processors/opencode.conversations-processor.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,UAAU,EACV,UAAU,EACV,UAAU,EACV,eAAe,EAChB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AAuBxD;;;;;GAKG;AACH,MAAM,OAAO,8BAA8B;IAChC,IAAI,GAAG,wBAAwB,CAAC;IAChC,QAAQ,GAAG,CAAC,CAAC,CAAE,oBAAoB;IAE5C;;OAEG;IACH,aAAa,CAAC,OAAsB;QAClC,IAAI,OAAO,CAAC,GAAG,CAAC,0BAA0B,KAAK,GAAG;YAAE,OAAO,KAAK,CAAC;QACjE,OAAO,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,OAAsB,EAAE,QAA2B;QAC/D,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,OAAO,CAAC,QAA6B,CAAC;YACvD,MAAM,kBAAkB,GAAwB,EAAE,CAAC;YAEnD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,8EAA8E;gBAC9E,8EAA8E;gBAC9E,6DAA6D;gBAC7D,MAAM,UAAU,GAAsB;oBACpC,EAAE,EAAE,OAAO,CAAC,EAAE;oBACd,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,OAAO,EAAE,EAAE,EAAG,gDAAgD;oBAC9D,6DAA6D;oBAC7D,SAAS,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO;wBAC9B,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE;wBAC9C,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBAC5B,2DAA2D;oBAC3D,KAAK,EAAE,OAAO,CAAC,IAAI,KAAK,WAAW;wBACjC,CAAC,CAAE,OAAoC,CAAC,OAAO;wBAC/C,CAAC,CAAC,SAAS;oBACb,KAAK,EAAE,OAAO,CAAC,IAAI,KAAK,WAAW;wBACjC,CAAC,CAAE,OAAoC,CAAC,KAAK;wBAC7C,CAAC,CAAC,SAAS;iBACd,CAAC;gBAEF,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACtC,CAAC;YAED,MAAM,CAAC,KAAK,CACV,uCAAuC,kBAAkB,CAAC,MAAM,WAAW,CAC5E,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,cAAc,kBAAkB,CAAC,MAAM,WAAW;gBAC3D,QAAQ,EAAE;oBACR,gBAAgB,EAAE,kBAAkB,CAAC,MAAM;oBAC3C,YAAY,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,MAAM;oBACtE,iBAAiB,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,MAAM;iBACjF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YAC9E,MAAM,CAAC,KAAK,CAAC,6CAA6C,EAAE,KAAK,CAAC,CAAC;YACnE,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,oCAAoC,YAAY,EAAE;aAC5D,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACK,YAAY,CAAC,KAAqB;QAMxC,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,MAAM,OAAO,GAA8C,EAAE,CAAC;QAC9D,MAAM,cAAc,GAAa,EAAE,CAAC;QACpC,MAAM,aAAa,GAAa,EAAE,CAAC;QAEnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,qCAAqC;YACrC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC;iBAAM,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,0CAA0C;gBAC1C,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,IAAI,CAAC,IAAI,EAAG,qBAAqB;oBACvC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,EAAG,wBAAwB;oBACxD,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,CAAE,uBAAuB;iBACpD,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,0CAA0C;gBAC1C,+CAA+C;gBAC/C,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;oBACb,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAChC,CAAC;qBAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACzB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACrC,CAAC;YACH,CAAC;iBAAM,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChC,CAAC;YACD,iFAAiF;QACnF,CAAC;QAED,OAAO;YACL,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;YAC7B,OAAO,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;YACjD,cAAc,EAAE,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE;YAC/D,QAAQ,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;SACnC,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"opencode.conversations-processor.js","sourceRoot":"","sources":["../../../../../../src/agents/plugins/opencode/session/processors/opencode.conversations-processor.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,17 @@
13
13
  */
14
14
  import type { SessionProcessor, ProcessingContext, ProcessingResult } from '../../../../core/session/BaseProcessor.js';
15
15
  import type { ParsedSession } from '../../../../core/session/BaseSessionAdapter.js';
16
+ /**
17
+ * Count added/removed lines in a unified diff.
18
+ *
19
+ * OpenCode reports edits as patch text (`state.metadata.filediff.patch`,
20
+ * `state.metadata.diff`, `apply_patch` per-file `patch`); unlike Claude it never
21
+ * emits numeric additions/deletions, so the counts have to come from the diff.
22
+ */
23
+ export declare function countDiffLines(patch: unknown): {
24
+ linesAdded: number;
25
+ linesRemoved: number;
26
+ };
16
27
  /**
17
28
  * OpenCode Metrics Processor
18
29
  *
@@ -22,8 +33,6 @@ import type { ParsedSession } from '../../../../core/session/BaseSessionAdapter.
22
33
  export declare class OpenCodeMetricsProcessor implements SessionProcessor {
23
34
  readonly name = "opencode-metrics";
24
35
  readonly priority = 1;
25
- private readonly cacheDir;
26
- constructor();
27
36
  /**
28
37
  * Check if session has data to process
29
38
  */
@@ -33,36 +42,34 @@ export declare class OpenCodeMetricsProcessor implements SessionProcessor {
33
42
  *
34
43
  * Per tech spec ADR-1/G2: Validate metadata at START before any processing
35
44
  */
36
- process(session: ParsedSession, _context: ProcessingContext): Promise<ProcessingResult>;
37
- /**
38
- * Check if session should be processed (cooldown check per ADR-18)
39
- */
40
- private shouldProcessSession;
45
+ process(session: ParsedSession, context: ProcessingContext): Promise<ProcessingResult>;
41
46
  /**
42
- * Mark session as processed (ADR-18)
47
+ * Resolve the git branch every delta in this batch is attributed to.
48
+ *
49
+ * Mirrors codex.metrics-processor's resolveBranch: prefer the branch the CLI
50
+ * already resolved (BaseAgentAdapter sets CODEMIE_GIT_BRANCH before spawning),
51
+ * then the value the adapter overlaid onto session metadata, then detect it.
43
52
  */
44
- private markSessionProcessed;
53
+ private resolveBranch;
45
54
  /**
46
- * Transform messages to MetricDelta records
55
+ * Transform messages to MetricDelta records.
56
+ *
57
+ * One delta per tool call (`{messageId}:{callID}`), per user prompt
58
+ * (`{messageId}:prompt`) and per failed turn (`{messageId}:error`).
47
59
  *
48
- * Per ADR-16: One delta per assistant message with tokens
60
+ * Granularity matters: when the recordId was the bare assistant message id,
61
+ * the first incremental tick claimed the message and every tool that message
62
+ * accumulated afterwards was deduped away and never reported.
49
63
  */
50
64
  private transformMessagesToDeltas;
51
65
  /**
52
- * Resolve timestamp with fallback chain (ADR-13 G4)
66
+ * Build a single-tool delta, or undefined when the tool is still in flight.
53
67
  */
54
- private resolveTimestamp;
68
+ private buildToolDelta;
55
69
  /**
56
- * Load parts for a message (ADR-11 - part-message validation)
57
- *
58
- * When partsMap is provided (SQLite-backed sessions), uses pre-loaded parts
59
- * directly instead of reading from the filesystem.
60
- */
61
- private loadPartsForMessage;
62
- /**
63
- * Extract tool metrics from parts (ADR-8, ADR-14)
70
+ * Resolve timestamp with fallback chain (ADR-13 G4)
64
71
  */
65
- private extractToolMetrics;
72
+ private resolveTimestamp;
66
73
  /**
67
74
  * Map tool status to success/failure/skip (ADR-14)
68
75
  */
@@ -72,25 +79,22 @@ export declare class OpenCodeMetricsProcessor implements SessionProcessor {
72
79
  * Only emits allowed file operation types.
73
80
  */
74
81
  private extractFileOperation;
75
- /**
76
- * Extract user prompts from messages (ADR-10, ADR-20)
77
- */
78
- private extractUserPrompts;
79
82
  /**
80
83
  * Extract user prompt text from message (ADR-10, ADR-20)
81
84
  */
82
85
  private extractUserPromptText;
83
86
  /**
84
- * Get existing record IDs for deduplication (ADR-5)
85
- * Uses tolerant JSONL reading to handle corrupted lines.
87
+ * Get existing record IDs for deduplication (ADR-5).
88
+ * Single tolerant read of the JSONL — corrupted lines are skipped.
86
89
  */
87
90
  private getExistingRecordIds;
88
91
  /**
89
- * Read existing deltas from JSONL file (ADR-5, ADR-21)
90
- */
91
- private readExistingDeltas;
92
- /**
93
- * Get valid model string (ADR-6)
92
+ * Get valid model string (ADR-6).
93
+ *
94
+ * Returns the BARE model id. codemie-claude reports `llm_model` without a
95
+ * provider prefix, so emitting `codemie-proxy/<model>` here would split the
96
+ * same model into two buckets in backend analytics. The provider stays on
97
+ * session metadata for local traceability.
94
98
  */
95
99
  private getValidModelString;
96
100
  }
@@ -1 +1 @@
1
- {"version":3,"file":"opencode.metrics-processor.d.ts","sourceRoot":"","sources":["../../../../../../src/agents/plugins/opencode/session/processors/opencode.metrics-processor.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AACvH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAoBpF;;;;;GAKG;AACH,qBAAa,wBAAyB,YAAW,gBAAgB;IAC/D,QAAQ,CAAC,IAAI,sBAAsB;IACnC,QAAQ,CAAC,QAAQ,KAAK;IAEtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;;IAMlC;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO;IAI9C;;;;OAIG;IACG,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAgH7F;;OAEG;YACW,oBAAoB;IAkBlC;;OAEG;YACW,oBAAoB;IAalC;;;;OAIG;YACW,yBAAyB;IA2FvC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;;;;OAKG;YACW,mBAAmB;IA8DjC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiD1B;;OAEG;IACH,OAAO,CAAC,aAAa;IAerB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IA+F5B;;OAEG;YACW,kBAAkB;IAoBhC;;OAEG;YACW,qBAAqB;IAuCnC;;;OAGG;YACW,oBAAoB;IAUlC;;OAEG;YACW,kBAAkB;IAiBhC;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAQ5B"}
1
+ {"version":3,"file":"opencode.metrics-processor.d.ts","sourceRoot":"","sources":["../../../../../../src/agents/plugins/opencode/session/processors/opencode.metrics-processor.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AACvH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAwCpF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAoB3F;AAED;;;;;GAKG;AACH,qBAAa,wBAAyB,YAAW,gBAAgB;IAC/D,QAAQ,CAAC,IAAI,sBAAsB;IACnC,QAAQ,CAAC,QAAQ,KAAK;IAEtB;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO;IAI9C;;;;OAIG;IACG,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA0G5F;;;;;;OAMG;YACW,aAAa;IAgB3B;;;;;;;;;OASG;YACW,yBAAyB;IA0FvC;;OAEG;IACH,OAAO,CAAC,cAAc;IA8BtB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;OAEG;IACH,OAAO,CAAC,aAAa;IAerB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAkG5B;;OAEG;YACW,qBAAqB;IAuCnC;;;OAGG;YACW,oBAAoB;IAiBlC;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;CAI5B"}