sidekick-shared 0.27.6 → 0.28.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 (269) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +58 -18
  3. package/dist/browser.d.ts +13 -2
  4. package/dist/browser.js +30 -2
  5. package/dist/claudePaths.d.ts +11 -0
  6. package/dist/claudePaths.js +61 -0
  7. package/dist/claudeProfiles.d.ts +2 -9
  8. package/dist/claudeProfiles.js +10 -25
  9. package/dist/codexPaths.d.ts +22 -0
  10. package/dist/codexPaths.js +67 -0
  11. package/dist/codexProfiles.d.ts +1 -4
  12. package/dist/codexProfiles.js +5 -43
  13. package/dist/doctor.js +2 -2
  14. package/dist/esm/accountChangeSignal.js +15 -0
  15. package/dist/esm/accountChanges.js +152 -0
  16. package/dist/esm/accountHealth.js +288 -0
  17. package/dist/esm/accountLaunch.js +145 -0
  18. package/dist/esm/accountLease.js +60 -0
  19. package/dist/esm/accountManager.js +606 -0
  20. package/dist/esm/accountRegistry.js +214 -0
  21. package/dist/esm/accountStatus.js +51 -0
  22. package/dist/esm/accountSwitch.js +74 -0
  23. package/dist/esm/accountSync.js +156 -0
  24. package/dist/esm/accountSyncTypes.js +4 -0
  25. package/dist/esm/accounts.js +1291 -0
  26. package/dist/esm/aggregation/EventAggregator.js +2034 -0
  27. package/dist/esm/aggregation/FrequencyTracker.js +69 -0
  28. package/dist/esm/aggregation/HeatmapTracker.js +89 -0
  29. package/dist/esm/aggregation/PatternExtractor.js +168 -0
  30. package/dist/esm/aggregation/costProvenance.js +31 -0
  31. package/dist/esm/aggregation/snapshot.js +161 -0
  32. package/dist/esm/aggregation/types.js +5 -0
  33. package/dist/esm/analytics/codeImpact.js +18 -0
  34. package/dist/esm/analytics/compactionLedger.js +37 -0
  35. package/dist/esm/analytics/qualityScore.js +112 -0
  36. package/dist/esm/autoSwitch.js +185 -0
  37. package/dist/esm/browser.js +34 -0
  38. package/dist/esm/claudeCredentialDoctor.js +239 -0
  39. package/dist/esm/claudeCredentialLedger.js +91 -0
  40. package/dist/esm/claudeCredentials.js +111 -0
  41. package/dist/esm/claudeLiveGuard.js +43 -0
  42. package/dist/esm/claudePaths.js +22 -0
  43. package/dist/esm/claudeProfiles.js +142 -0
  44. package/dist/esm/claudeRefreshLock.js +106 -0
  45. package/dist/esm/codexAuth.js +101 -0
  46. package/dist/esm/codexCredentialDoctor.js +265 -0
  47. package/dist/esm/codexCredentialStore.js +164 -0
  48. package/dist/esm/codexKeepAlive.js +112 -0
  49. package/dist/esm/codexPaths.js +172 -0
  50. package/dist/esm/codexProfiles.js +1251 -0
  51. package/dist/esm/codexQuota.js +564 -0
  52. package/dist/esm/codexQuotaWatcher.js +363 -0
  53. package/dist/esm/context/composer.js +71 -0
  54. package/dist/esm/context/sessionContext.js +546 -0
  55. package/dist/esm/credentialIO.js +283 -0
  56. package/dist/esm/credentials.js +49 -0
  57. package/dist/esm/doctor.js +305 -0
  58. package/dist/esm/ensureDefaultAccounts.js +62 -0
  59. package/dist/esm/errorHistory.js +56 -0
  60. package/dist/esm/extractors/errorTaxonomy.js +43 -0
  61. package/dist/esm/extractors/gatherAssets.js +32 -0
  62. package/dist/esm/extractors/sessionAssets.js +176 -0
  63. package/dist/esm/extractors/sources/claudeAssets.js +158 -0
  64. package/dist/esm/extractors/sources/codexAssets.js +234 -0
  65. package/dist/esm/extractors/tokenUsage.js +41 -0
  66. package/dist/esm/extractors/toolCall.js +142 -0
  67. package/dist/esm/failingTools.js +65 -0
  68. package/dist/esm/fileHead.js +27 -0
  69. package/dist/esm/formatters/eventHighlighter.js +332 -0
  70. package/dist/esm/formatters/noiseClassifier.js +209 -0
  71. package/dist/esm/formatters/sessionDump.js +328 -0
  72. package/dist/esm/formatters/toolSummary.js +226 -0
  73. package/dist/esm/formatting.js +82 -0
  74. package/dist/esm/handoffUrl.js +23 -0
  75. package/dist/esm/historicalStore.js +305 -0
  76. package/dist/esm/humanPrompt.js +88 -0
  77. package/dist/esm/index.js +213 -0
  78. package/dist/esm/keepAlive.js +189 -0
  79. package/dist/esm/liveCredentialGuard.js +33 -0
  80. package/dist/esm/modelAliases.js +51 -0
  81. package/dist/esm/modelCatalog.js +139 -0
  82. package/dist/esm/modelContext.js +280 -0
  83. package/dist/esm/modelInfo.js +832 -0
  84. package/dist/esm/multiProviderQuotaService.js +450 -0
  85. package/dist/esm/node.js +46 -0
  86. package/dist/esm/observedContextWindows.js +165 -0
  87. package/dist/esm/observedSessionCollector.js +939 -0
  88. package/dist/esm/parsers/changelogParser.js +71 -0
  89. package/dist/esm/parsers/codexHistory.js +89 -0
  90. package/dist/esm/parsers/codexParser.js +906 -0
  91. package/dist/esm/parsers/debugLogParser.js +126 -0
  92. package/dist/esm/parsers/jsonl.js +66 -0
  93. package/dist/esm/parsers/mcpToolName.js +28 -0
  94. package/dist/esm/parsers/openCodeParser.js +625 -0
  95. package/dist/esm/parsers/planExtractor.js +335 -0
  96. package/dist/esm/parsers/sessionActivityDetector.js +246 -0
  97. package/dist/esm/parsers/sessionPathResolver.js +713 -0
  98. package/dist/esm/parsers/subagentScanner.js +360 -0
  99. package/dist/esm/parsers/subagentStatsCache.js +45 -0
  100. package/dist/esm/parsers/subagentTraceParser.js +325 -0
  101. package/dist/esm/paths.js +134 -0
  102. package/dist/esm/peakHours.js +194 -0
  103. package/dist/esm/phrases.js +1330 -0
  104. package/dist/esm/pricingCatalog.js +247 -0
  105. package/dist/esm/processDetection.js +200 -0
  106. package/dist/esm/projectMigration.js +59 -0
  107. package/dist/esm/promptHistory.js +1221 -0
  108. package/dist/esm/providerFailure.js +362 -0
  109. package/dist/esm/providerIds.js +6 -0
  110. package/dist/esm/providerQuota.js +1 -0
  111. package/dist/esm/providerServiceStatus.js +145 -0
  112. package/dist/esm/providerServiceStatusTypes.js +1 -0
  113. package/dist/esm/providerStatus.js +117 -0
  114. package/dist/esm/providers/claudeCode.js +575 -0
  115. package/dist/esm/providers/claudeListing.js +121 -0
  116. package/dist/esm/providers/codex.js +1034 -0
  117. package/dist/esm/providers/codexDatabase.js +297 -0
  118. package/dist/esm/providers/codexRollouts.js +215 -0
  119. package/dist/esm/providers/detect.js +185 -0
  120. package/dist/esm/providers/diagnostics.js +83 -0
  121. package/dist/esm/providers/directoryListingCache.js +206 -0
  122. package/dist/esm/providers/factory.js +54 -0
  123. package/dist/esm/providers/openCode.js +2008 -0
  124. package/dist/esm/providers/openCodeDatabase.js +419 -0
  125. package/dist/esm/providers/rolloutWalker.js +252 -0
  126. package/dist/esm/providers/types.js +12 -0
  127. package/dist/esm/quota.js +182 -0
  128. package/dist/esm/quotaHistory.js +364 -0
  129. package/dist/esm/quotaPoller.js +230 -0
  130. package/dist/esm/quotaPresentation.js +97 -0
  131. package/dist/esm/quotaResolver.js +231 -0
  132. package/dist/esm/quotaSnapshots.js +130 -0
  133. package/dist/esm/quotaThresholds.js +85 -0
  134. package/dist/esm/readers/decisions.js +24 -0
  135. package/dist/esm/readers/handoff.js +20 -0
  136. package/dist/esm/readers/helpers.js +27 -0
  137. package/dist/esm/readers/history.js +9 -0
  138. package/dist/esm/readers/notes.js +48 -0
  139. package/dist/esm/readers/plans.js +225 -0
  140. package/dist/esm/readers/tasks.js +19 -0
  141. package/dist/esm/report/htmlHelpers.js +280 -0
  142. package/dist/esm/report/htmlReportGenerator.js +704 -0
  143. package/dist/esm/report/index.js +7 -0
  144. package/dist/esm/report/logo.js +2 -0
  145. package/dist/esm/report/openBrowser.js +19 -0
  146. package/dist/esm/report/sessionReportInputs.js +33 -0
  147. package/dist/esm/report/transcriptParser.js +83 -0
  148. package/dist/esm/report/types.js +4 -0
  149. package/dist/esm/schemas/accountManager.js +204 -0
  150. package/dist/esm/schemas/accountStatus.js +25 -0
  151. package/dist/esm/schemas/assistantTurn.js +74 -0
  152. package/dist/esm/schemas/index.js +25 -0
  153. package/dist/esm/schemas/observedSessionV1.js +77 -0
  154. package/dist/esm/schemas/providerFailure.js +37 -0
  155. package/dist/esm/schemas/quota.js +132 -0
  156. package/dist/esm/schemas/quotaHistory.js +40 -0
  157. package/dist/esm/schemas/sessionEvent.js +216 -0
  158. package/dist/esm/schemas/stateFile.js +75 -0
  159. package/dist/esm/schemas/tokenEstimation.js +7 -0
  160. package/dist/esm/schemas/transcript.js +86 -0
  161. package/dist/esm/schemas/usageNormalization.js +38 -0
  162. package/dist/esm/search/advancedFilter.js +197 -0
  163. package/dist/esm/search/sessionSearch.js +66 -0
  164. package/dist/esm/sessionFingerprint.js +40 -0
  165. package/dist/esm/sessionMonitor.js +198 -0
  166. package/dist/esm/sessionPreviews.js +522 -0
  167. package/dist/esm/sessionPromptHistory.js +254 -0
  168. package/dist/esm/sessionPromptSignals.js +364 -0
  169. package/dist/esm/sessionStats.js +160 -0
  170. package/dist/esm/sessionTokenTotals.js +98 -0
  171. package/dist/esm/sessionTranscripts.js +49 -0
  172. package/dist/esm/stateFile.js +119 -0
  173. package/dist/esm/statusline/BurnRateCalculator.js +40 -0
  174. package/dist/esm/statusline/claudeStatuslinePayload.js +148 -0
  175. package/dist/esm/statusline/formatter.js +122 -0
  176. package/dist/esm/statusline/index.js +8 -0
  177. package/dist/esm/terminalSync.js +95 -0
  178. package/dist/esm/testing/credentialGuard.js +197 -0
  179. package/dist/esm/testing/index.js +12 -0
  180. package/dist/esm/testing/sessionLogFixtures.js +128 -0
  181. package/dist/esm/tokenEstimation.js +67 -0
  182. package/dist/esm/tokenSummary.js +113 -0
  183. package/dist/esm/toolCategory.js +82 -0
  184. package/dist/esm/transcript.js +257 -0
  185. package/dist/esm/turns/assistantTurn.js +373 -0
  186. package/dist/esm/types/codex.js +23 -0
  187. package/dist/esm/types/decisionLog.js +5 -0
  188. package/dist/esm/types/historicalData.js +47 -0
  189. package/dist/esm/types/knowledgeNote.js +15 -0
  190. package/dist/esm/types/observedSessionV1.js +257 -0
  191. package/dist/esm/types/opencode.js +12 -0
  192. package/dist/esm/types/plan.js +7 -0
  193. package/dist/esm/types/sessionEvent.js +10 -0
  194. package/dist/esm/types/taskPersistence.js +12 -0
  195. package/dist/esm/usage/billingBlocks.js +148 -0
  196. package/dist/esm/usage/claudeUsageDedupe.js +189 -0
  197. package/dist/esm/usage/importSessionHistory.js +84 -0
  198. package/dist/esm/usage/subagentUsage.js +18 -0
  199. package/dist/esm/usage/usageEvents.js +402 -0
  200. package/dist/esm/usage/usageReports.js +202 -0
  201. package/dist/esm/usageNormalization.js +95 -0
  202. package/dist/esm/watchers/eventBridge.js +219 -0
  203. package/dist/esm/watchers/factory.js +63 -0
  204. package/dist/esm/watchers/jsonlTail.js +289 -0
  205. package/dist/esm/watchers/jsonlWatcher.js +435 -0
  206. package/dist/esm/watchers/providerReaderWatcher.js +118 -0
  207. package/dist/esm/watchers/sqliteWatcher.js +285 -0
  208. package/dist/esm/watchers/types.js +4 -0
  209. package/dist/esm/workspaceRoots.js +56 -0
  210. package/dist/esm/writers/atomic.js +375 -0
  211. package/dist/esm/writers/decisions.js +51 -0
  212. package/dist/esm/writers/notes.js +46 -0
  213. package/dist/esm/writers/tasks.js +63 -0
  214. package/dist/esm/zaiQuota.js +323 -0
  215. package/dist/esm/zaiQuotaApi.js +271 -0
  216. package/dist/esm/zaiQuotaWatcher.js +265 -0
  217. package/dist/fileHead.d.ts +22 -0
  218. package/dist/fileHead.js +33 -0
  219. package/dist/index.d.ts +16 -7
  220. package/dist/index.js +49 -15
  221. package/dist/node.d.ts +13 -1
  222. package/dist/node.js +43 -2
  223. package/dist/parsers/codexHistory.js +2 -2
  224. package/dist/parsers/codexParser.d.ts +12 -0
  225. package/dist/parsers/codexParser.js +34 -12
  226. package/dist/parsers/debugLogParser.js +2 -2
  227. package/dist/parsers/sessionPathResolver.js +5 -4
  228. package/dist/promptHistory.d.ts +32 -0
  229. package/dist/promptHistory.js +115 -59
  230. package/dist/providerFailure.d.ts +12 -6
  231. package/dist/providerFailure.js +45 -0
  232. package/dist/providers/claudeCode.js +7 -99
  233. package/dist/providers/claudeListing.d.ts +22 -0
  234. package/dist/providers/claudeListing.js +158 -0
  235. package/dist/providers/codex.d.ts +3 -1
  236. package/dist/providers/codex.js +26 -227
  237. package/dist/providers/codexRollouts.d.ts +44 -0
  238. package/dist/providers/codexRollouts.js +261 -0
  239. package/dist/providers/detect.js +4 -4
  240. package/dist/readers/plans.js +3 -3
  241. package/dist/schemas/index.d.ts +2 -0
  242. package/dist/schemas/index.js +7 -2
  243. package/dist/schemas/providerFailure.d.ts +154 -0
  244. package/dist/schemas/providerFailure.js +40 -0
  245. package/dist/sessionPromptHistory.d.ts +12 -7
  246. package/dist/sessionPromptHistory.js +15 -3
  247. package/dist/sessionPromptSignals.d.ts +9 -0
  248. package/dist/sessionPromptSignals.js +13 -0
  249. package/dist/testing/credentialGuard.d.ts +23 -0
  250. package/dist/testing/credentialGuard.js +233 -0
  251. package/dist/testing/index.d.ts +14 -0
  252. package/dist/testing/index.js +22 -0
  253. package/dist/testing/sessionLogFixtures.d.ts +28 -0
  254. package/dist/testing/sessionLogFixtures.js +169 -0
  255. package/dist/tokenEstimation.d.ts +2 -0
  256. package/dist/tokenEstimation.js +21 -11
  257. package/dist/toolCategory.d.ts +18 -0
  258. package/dist/toolCategory.js +86 -0
  259. package/dist/types/codex.d.ts +4 -0
  260. package/dist/usage/usageEvents.d.ts +16 -0
  261. package/dist/usage/usageEvents.js +53 -9
  262. package/dist/watchers/jsonlTail.d.ts +26 -1
  263. package/dist/watchers/jsonlTail.js +136 -28
  264. package/dist/watchers/jsonlWatcher.js +7 -0
  265. package/dist/watchers/providerReaderWatcher.js +1 -0
  266. package/dist/watchers/types.d.ts +6 -0
  267. package/dist/workspaceRoots.d.ts +23 -0
  268. package/dist/workspaceRoots.js +93 -0
  269. package/package.json +22 -2
@@ -0,0 +1,373 @@
1
+ import { formatToolSummary, truncate } from '../formatters/toolSummary';
2
+ const DEFAULT_NARRATION_CHARS = 4000;
3
+ const DEFAULT_REASONING_CHARS = 8000;
4
+ const DEFAULT_PROCESS_STEPS = 60;
5
+ const DEFAULT_REASONING_BLOCKS = 24;
6
+ const DEFAULT_TOOL_INPUT_CHARS = 200;
7
+ const SUBAGENT_TOOL_NAMES = new Set(['Task']);
8
+ const LABEL_MAX = 80;
9
+ const TITLE_RE = /^\s*\*\*([^*\n]+)\*\*[ \t]*(?:\n+([\s\S]*))?$/;
10
+ const TITLE_MAX = 100;
11
+ export function reasoningSummary(text) {
12
+ const normalized = text.replace(/\r\n/g, '\n');
13
+ const trimmed = normalized.trim();
14
+ if (trimmed === '')
15
+ return { title: null, body: '' };
16
+ const match = TITLE_RE.exec(normalized);
17
+ if (match) {
18
+ const title = match[1].trim();
19
+ if (title !== '' && title.length <= TITLE_MAX) {
20
+ return { title, body: (match[2] ?? '').trim() };
21
+ }
22
+ }
23
+ return { title: null, body: trimmed };
24
+ }
25
+ export function isAssistantTurnSubagentTool(toolName) {
26
+ return toolName != null && SUBAGENT_TOOL_NAMES.has(toolName);
27
+ }
28
+ export function segmentAssistantTurn(events, options = {}) {
29
+ const maxNarrationChars = options.maxNarrationChars ?? DEFAULT_NARRATION_CHARS;
30
+ const maxReasoningChars = options.maxReasoningChars ?? DEFAULT_REASONING_CHARS;
31
+ const maxProcessSteps = options.maxProcessSteps ?? DEFAULT_PROCESS_STEPS;
32
+ const maxReasoningBlocks = options.maxReasoningBlocks ?? DEFAULT_REASONING_BLOCKS;
33
+ const subagentStatus = options.subagentStatus ?? 'completed';
34
+ const reasoningParts = [];
35
+ const steps = [];
36
+ const timelineItems = [];
37
+ let textBuffer = [];
38
+ let toolGroup = null;
39
+ function closeToolGroup() {
40
+ if (toolGroup != null && toolGroup.tools.length > 0) {
41
+ const processStepIndex = steps.length;
42
+ steps.push(toolGroup);
43
+ timelineItems.push({ kind: 'toolGroup', tools: toolGroup.tools, processStepIndex });
44
+ }
45
+ toolGroup = null;
46
+ }
47
+ function sealTextAsNarration() {
48
+ const text = joinText(textBuffer);
49
+ if (text !== '') {
50
+ const processStepIndex = steps.length;
51
+ const step = { kind: 'narration', text: capText(text, maxNarrationChars) };
52
+ steps.push(step);
53
+ timelineItems.push({ kind: 'narration', text: step.text, processStepIndex });
54
+ }
55
+ textBuffer = [];
56
+ }
57
+ for (const event of events) {
58
+ switch (event.eventType) {
59
+ case 'text': {
60
+ if (event.content.trim() === '')
61
+ break;
62
+ closeToolGroup();
63
+ textBuffer.push(event.content);
64
+ break;
65
+ }
66
+ case 'thinking': {
67
+ if (event.content.trim() === '')
68
+ break;
69
+ sealTextAsNarration();
70
+ closeToolGroup();
71
+ const reasoningIndex = reasoningParts.length;
72
+ reasoningParts.push(event.content);
73
+ timelineItems.push({
74
+ kind: 'reasoning',
75
+ text: capText(event.content, maxReasoningChars),
76
+ reasoningIndex,
77
+ });
78
+ break;
79
+ }
80
+ case 'tool_use': {
81
+ sealTextAsNarration();
82
+ if (toolGroup == null)
83
+ toolGroup = { kind: 'toolGroup', tools: [] };
84
+ const toolName = event.toolName ?? 'tool';
85
+ const tool = { toolName };
86
+ const toolInput = formatTurnToolInput(toolName, event.toolInput, event.toolUseId, options);
87
+ if (toolInput != null && toolInput !== '')
88
+ tool.toolInput = toolInput;
89
+ if (event.toolUseId != null && event.toolUseId !== '')
90
+ tool.toolUseId = event.toolUseId;
91
+ toolGroup.tools.push(tool);
92
+ break;
93
+ }
94
+ default:
95
+ break;
96
+ }
97
+ }
98
+ const answer = joinText(textBuffer);
99
+ closeToolGroup();
100
+ const cappedReasoning = capReasoningBlocks(reasoningParts.map((part) => capText(part, maxReasoningChars)), maxReasoningBlocks);
101
+ const cappedProcess = capProcessSteps(steps, maxProcessSteps);
102
+ const process = { steps: cappedProcess.steps };
103
+ return {
104
+ schemaVersion: 2,
105
+ answer,
106
+ reasoning: capText(joinText(reasoningParts), maxReasoningChars),
107
+ reasoningBlocks: cappedReasoning.blocks,
108
+ process,
109
+ timeline: capTimelineItems(timelineItems, cappedReasoning, cappedProcess),
110
+ subagents: extractTurnSubagents(flattenProcessTools(process), { status: subagentStatus }),
111
+ };
112
+ }
113
+ export function assistantTurnEventsFromSessionEvents(events) {
114
+ const result = [];
115
+ for (const event of events) {
116
+ if (event.type === 'assistant') {
117
+ appendMessageContentEvents(result, event.message.content);
118
+ continue;
119
+ }
120
+ if (event.type === 'tool_use' && event.tool != null) {
121
+ result.push({
122
+ eventType: 'tool_use',
123
+ content: '',
124
+ toolName: event.tool.name,
125
+ toolInput: event.tool.input,
126
+ });
127
+ continue;
128
+ }
129
+ if (event.type === 'tool_result') {
130
+ result.push({
131
+ eventType: 'tool_result',
132
+ content: stringifyValue(event.result?.output),
133
+ toolUseId: event.result?.tool_use_id,
134
+ });
135
+ }
136
+ }
137
+ return result;
138
+ }
139
+ export function extractTurnSubagents(tools, options) {
140
+ const result = [];
141
+ for (const tool of tools) {
142
+ if (!isAssistantTurnSubagentTool(tool.toolName))
143
+ continue;
144
+ const input = parseSubagentInput(tool.toolInput);
145
+ const index = result.length;
146
+ const label = capLabel(input.description ?? input.agentType ?? `Agent ${index + 1}`);
147
+ const ref = {
148
+ id: tool.toolUseId && tool.toolUseId !== '' ? tool.toolUseId : `subagent-${index}`,
149
+ label,
150
+ status: options.status,
151
+ };
152
+ if (input.agentType != null)
153
+ ref.agentType = input.agentType;
154
+ result.push(ref);
155
+ }
156
+ return result;
157
+ }
158
+ function appendMessageContentEvents(result, content) {
159
+ if (typeof content === 'string') {
160
+ if (content !== '')
161
+ result.push({ eventType: 'text', content });
162
+ return;
163
+ }
164
+ if (!Array.isArray(content))
165
+ return;
166
+ for (const block of content) {
167
+ if (!isRecord(block))
168
+ continue;
169
+ const type = stringValue(block.type);
170
+ if (type === 'text') {
171
+ const text = stringValue(block.text) ?? stringValue(block.content);
172
+ if (text != null)
173
+ result.push({ eventType: 'text', content: text });
174
+ continue;
175
+ }
176
+ if (type === 'thinking' || type === 'reasoning') {
177
+ const text = stringValue(block.thinking) ?? stringValue(block.text) ?? stringValue(block.content);
178
+ if (text != null)
179
+ result.push({ eventType: 'thinking', content: text });
180
+ continue;
181
+ }
182
+ if (type === 'tool_use') {
183
+ const toolName = stringValue(block.name) ?? 'tool';
184
+ const event = {
185
+ eventType: 'tool_use',
186
+ content: '',
187
+ toolName,
188
+ toolInput: block.input,
189
+ };
190
+ const toolUseId = stringValue(block.id);
191
+ if (toolUseId != null)
192
+ event.toolUseId = toolUseId;
193
+ result.push(event);
194
+ continue;
195
+ }
196
+ if (type === 'tool_result') {
197
+ const event = {
198
+ eventType: 'tool_result',
199
+ content: stringifyValue(block.content),
200
+ };
201
+ const toolUseId = stringValue(block.tool_use_id);
202
+ if (toolUseId != null)
203
+ event.toolUseId = toolUseId;
204
+ result.push(event);
205
+ }
206
+ }
207
+ }
208
+ function formatTurnToolInput(toolName, toolInput, toolUseId, options) {
209
+ if (options.sanitizeToolInput != null) {
210
+ return options.sanitizeToolInput({ toolName, toolInput, toolUseId });
211
+ }
212
+ if (toolInput == null)
213
+ return undefined;
214
+ const maxChars = options.toolInputMaxChars ?? DEFAULT_TOOL_INPUT_CHARS;
215
+ if (isAssistantTurnSubagentTool(toolName)) {
216
+ const input = parseSubagentInput(toolInput);
217
+ const projection = {};
218
+ if (input.agentType != null)
219
+ projection.subagent_type = truncate(input.agentType, LABEL_MAX);
220
+ if (input.description != null)
221
+ projection.description = truncate(input.description, maxChars);
222
+ return JSON.stringify(projection);
223
+ }
224
+ const record = coerceRecord(toolInput);
225
+ if (record != null) {
226
+ const summary = formatToolSummary(toolName, record);
227
+ return summary === '' ? undefined : truncate(summary, maxChars);
228
+ }
229
+ if (typeof toolInput === 'string') {
230
+ return truncate(toolInput, maxChars);
231
+ }
232
+ return truncate(stringifyValue(toolInput), maxChars);
233
+ }
234
+ function flattenProcessTools(process) {
235
+ const result = [];
236
+ for (const step of process.steps) {
237
+ if (step.kind === 'toolGroup')
238
+ result.push(...step.tools);
239
+ }
240
+ return result;
241
+ }
242
+ function capProcessSteps(steps, maxRetainedSteps) {
243
+ const retainedIndexes = new Set();
244
+ if (!Number.isFinite(maxRetainedSteps) || maxRetainedSteps < 0)
245
+ return { steps: [], retainedIndexes };
246
+ const retainedCount = Math.floor(maxRetainedSteps);
247
+ if (steps.length <= retainedCount) {
248
+ steps.forEach((_step, index) => retainedIndexes.add(index));
249
+ return { steps, retainedIndexes };
250
+ }
251
+ const firstKeptIndex = Math.max(steps.length - retainedCount, 0);
252
+ const kept = retainedCount > 0 ? steps.slice(firstKeptIndex) : [];
253
+ for (let index = firstKeptIndex; index < steps.length; index += 1) {
254
+ retainedIndexes.add(index);
255
+ }
256
+ const omitted = steps.length - kept.length;
257
+ const omittedMarker = `... ${omitted} earlier process step${omitted === 1 ? '' : 's'} omitted`;
258
+ return {
259
+ steps: [{ kind: 'narration', text: omittedMarker }, ...kept],
260
+ retainedIndexes,
261
+ omittedMarker,
262
+ };
263
+ }
264
+ function capReasoningBlocks(blocks, maxRetainedBlocks) {
265
+ const retainedIndexes = new Set();
266
+ if (!Number.isFinite(maxRetainedBlocks) || maxRetainedBlocks < 0)
267
+ return { blocks: [], retainedIndexes };
268
+ const retainedCount = Math.floor(maxRetainedBlocks);
269
+ if (blocks.length <= retainedCount) {
270
+ blocks.forEach((_block, index) => retainedIndexes.add(index));
271
+ return { blocks, retainedIndexes };
272
+ }
273
+ const kept = retainedCount > 0 ? blocks.slice(0, retainedCount) : [];
274
+ for (let index = 0; index < kept.length; index += 1) {
275
+ retainedIndexes.add(index);
276
+ }
277
+ const omitted = blocks.length - kept.length;
278
+ const omittedMarker = `... ${omitted} more reasoning block${omitted === 1 ? '' : 's'} omitted`;
279
+ return { blocks: [...kept, omittedMarker], retainedIndexes, omittedMarker };
280
+ }
281
+ function capTimelineItems(items, reasoning, process) {
282
+ const result = [];
283
+ let insertedReasoningOmission = false;
284
+ let insertedProcessOmission = false;
285
+ for (const item of items) {
286
+ if (item.kind === 'reasoning') {
287
+ if (reasoning.retainedIndexes.has(item.reasoningIndex)) {
288
+ result.push({ kind: 'reasoning', text: item.text });
289
+ }
290
+ else if (reasoning.omittedMarker != null && !insertedReasoningOmission) {
291
+ result.push({ kind: 'reasoning', text: reasoning.omittedMarker });
292
+ insertedReasoningOmission = true;
293
+ }
294
+ continue;
295
+ }
296
+ if (!process.retainedIndexes.has(item.processStepIndex)) {
297
+ if (process.omittedMarker != null && !insertedProcessOmission) {
298
+ result.push({ kind: 'narration', text: process.omittedMarker });
299
+ insertedProcessOmission = true;
300
+ }
301
+ continue;
302
+ }
303
+ if (process.omittedMarker != null && !insertedProcessOmission) {
304
+ result.push({ kind: 'narration', text: process.omittedMarker });
305
+ insertedProcessOmission = true;
306
+ }
307
+ if (item.kind === 'narration') {
308
+ result.push({ kind: 'narration', text: item.text });
309
+ }
310
+ else {
311
+ result.push({ kind: 'toolGroup', tools: item.tools });
312
+ }
313
+ }
314
+ return result;
315
+ }
316
+ function parseSubagentInput(input) {
317
+ const record = coerceRecord(input);
318
+ if (record == null)
319
+ return {};
320
+ const description = stringValue(record.description)?.trim();
321
+ const agentType = (stringValue(record.subagent_type) ?? stringValue(record.subagentType))?.trim();
322
+ return {
323
+ ...(description != null && description !== '' ? { description } : {}),
324
+ ...(agentType != null && agentType !== '' ? { agentType } : {}),
325
+ };
326
+ }
327
+ function coerceRecord(value) {
328
+ if (isRecord(value))
329
+ return value;
330
+ if (typeof value !== 'string' || value.trim() === '')
331
+ return null;
332
+ try {
333
+ const parsed = JSON.parse(value);
334
+ return isRecord(parsed) ? parsed : null;
335
+ }
336
+ catch {
337
+ return null;
338
+ }
339
+ }
340
+ function capLabel(label) {
341
+ return label.length <= LABEL_MAX ? label : `${label.slice(0, LABEL_MAX - 3).trimEnd()}...`;
342
+ }
343
+ function capText(text, maxChars) {
344
+ if (!Number.isFinite(maxChars) || maxChars < 0)
345
+ return '';
346
+ const limit = Math.floor(maxChars);
347
+ if (text.length <= limit)
348
+ return text;
349
+ if (limit <= 3)
350
+ return '.'.repeat(limit);
351
+ return `${text.slice(0, limit - 3).trimEnd()}...`;
352
+ }
353
+ function joinText(parts) {
354
+ return parts.filter((part) => part.trim() !== '').join('\n\n');
355
+ }
356
+ function stringifyValue(value) {
357
+ if (value == null)
358
+ return '';
359
+ if (typeof value === 'string')
360
+ return value;
361
+ try {
362
+ return JSON.stringify(value, null, 2);
363
+ }
364
+ catch {
365
+ return String(value);
366
+ }
367
+ }
368
+ function stringValue(value) {
369
+ return typeof value === 'string' ? value : undefined;
370
+ }
371
+ function isRecord(value) {
372
+ return value != null && typeof value === 'object' && !Array.isArray(value);
373
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @fileoverview Type definitions for Codex CLI (OpenAI) session rollout format.
3
+ *
4
+ * Codex stores sessions as JSONL rollout files in:
5
+ * ~/.codex/sessions/YYYY/MM/DD/rollout-<timestamp>-<uuid>.jsonl
6
+ * with an optional SQLite index at ~/.codex/state.sqlite.
7
+ *
8
+ * Each line is a JSON object: { timestamp, type, payload }
9
+ * with 5 top-level types: session_meta, response_item, compacted, turn_context, event_msg.
10
+ *
11
+ * @module types/codex
12
+ */
13
+ /**
14
+ * Codex reports several rate-limit families per session, keyed by `limit_id`.
15
+ * The aggregate plan quota — what the usage API surfaces — is `limit_id: "codex"`
16
+ * (or absent on older payloads). Model/feature-specific families (e.g.
17
+ * `codex_bengalfox`, `premium`) report their own windows and can read 0% while the
18
+ * plan is heavily used, so they must never mask the aggregate in the standard
19
+ * quota view. Returns true only for the aggregate family.
20
+ */
21
+ export function isAggregateCodexLimit(limitId) {
22
+ return !limitId || limitId === 'codex';
23
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * On-disk schema types for cross-session decision log.
3
+ * Canonical source: sidekick-vscode/src/types/decisionLog.ts
4
+ */
5
+ export const DECISION_LOG_SCHEMA_VERSION = 1;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * On-disk schema types for historical session data.
3
+ * Canonical source: sidekick-vscode/src/types/historicalData.ts
4
+ *
5
+ * Schema version 2 (2026-04-17) adds optional pricing-honesty fields:
6
+ * - ModelUsageRecord.priced: false when the model had no known pricing
7
+ * at the time the record was written. When false, `cost` is 0 and UIs
8
+ * render "—".
9
+ * - SessionSummary.unpricedModelIds: list of model IDs that fell back to
10
+ * $0 because pricing was unknown — surfaced in the dashboard footer.
11
+ * Legacy records (schemaVersion 1 or missing) have neither field and should
12
+ * be treated as fully priced.
13
+ *
14
+ * Schema version 3 (2026-07-18) adds a capped per-session record list with
15
+ * provider/project dimensions, beta quality factors, churn, and impact cost.
16
+ */
17
+ export const HISTORICAL_DATA_SCHEMA_VERSION = 3;
18
+ export const HISTORICAL_SESSION_RETENTION_LIMIT = 500;
19
+ export function createEmptyTokenTotals() {
20
+ return {
21
+ inputTokens: 0,
22
+ outputTokens: 0,
23
+ cacheWriteTokens: 0,
24
+ cacheReadTokens: 0,
25
+ };
26
+ }
27
+ export function createEmptyDataStore() {
28
+ const now = new Date().toISOString();
29
+ return {
30
+ schemaVersion: HISTORICAL_DATA_SCHEMA_VERSION,
31
+ daily: {},
32
+ monthly: {},
33
+ sessions: [],
34
+ allTime: {
35
+ tokens: createEmptyTokenTotals(),
36
+ totalCost: 0,
37
+ messageCount: 0,
38
+ sessionCount: 0,
39
+ firstDate: '',
40
+ lastDate: '',
41
+ modelUsage: [],
42
+ toolUsage: [],
43
+ updatedAt: now,
44
+ },
45
+ lastSaved: now,
46
+ };
47
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * On-disk schema types for knowledge notes.
3
+ * Canonical source: sidekick-vscode/src/types/knowledgeNote.ts
4
+ */
5
+ export const KNOWLEDGE_NOTE_SCHEMA_VERSION = 1;
6
+ export const IMPORTANCE_DECAY_FACTORS = {
7
+ critical: 2.0,
8
+ high: 1.5,
9
+ medium: 1.0,
10
+ low: 0.5,
11
+ };
12
+ export const STALENESS_THRESHOLDS = {
13
+ needsReview: 30,
14
+ stale: 90,
15
+ };