sidekick-shared 0.29.0 → 0.30.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 (142) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +198 -56
  3. package/dist/aggregation/EventAggregator.d.ts +96 -2
  4. package/dist/aggregation/EventAggregator.js +535 -42
  5. package/dist/aggregation/snapshot.d.ts +37 -8
  6. package/dist/aggregation/snapshot.js +31 -9
  7. package/dist/aggregation/types.d.ts +38 -1
  8. package/dist/browser.d.ts +9 -1
  9. package/dist/browser.js +29 -3
  10. package/dist/context/sessionContext.js +8 -0
  11. package/dist/esm/aggregation/EventAggregator.js +535 -42
  12. package/dist/esm/aggregation/snapshot.js +31 -9
  13. package/dist/esm/browser.js +3 -0
  14. package/dist/esm/context/sessionContext.js +8 -0
  15. package/dist/esm/fileContinuity.js +149 -0
  16. package/dist/esm/formatters/toolSummary.js +4 -1
  17. package/dist/esm/index.js +7 -2
  18. package/dist/esm/modelCatalog.js +5 -4
  19. package/dist/esm/modelContext.js +4 -3
  20. package/dist/esm/modelInfo.js +4 -3
  21. package/dist/esm/node.js +3 -1
  22. package/dist/esm/observedContextWindows.js +2 -1
  23. package/dist/esm/ownKey.js +26 -0
  24. package/dist/esm/parsers/codexParser.js +372 -7
  25. package/dist/esm/parsers/openCodeParser.js +2 -1
  26. package/dist/esm/parsers/subagentEndState.js +61 -0
  27. package/dist/esm/parsers/subagentScanner.js +37 -12
  28. package/dist/esm/parsers/subagentTraceParser.js +103 -37
  29. package/dist/esm/pricingCatalog.js +3 -2
  30. package/dist/esm/promptHistory.js +22 -11
  31. package/dist/esm/providers/claudeCode.js +60 -29
  32. package/dist/esm/providers/codex.js +235 -201
  33. package/dist/esm/providers/codexCompressedReader.js +184 -0
  34. package/dist/esm/providers/codexDatabase.js +47 -2
  35. package/dist/esm/providers/codexRollouts.js +20 -2
  36. package/dist/esm/providers/codexSubagents.js +456 -0
  37. package/dist/esm/providers/compressedRollouts.js +330 -0
  38. package/dist/esm/providers/factory.js +4 -1
  39. package/dist/esm/providers/rolloutWalker.js +32 -4
  40. package/dist/esm/schemas/sessionEvent.js +63 -14
  41. package/dist/esm/sessionMonitor.js +7 -1
  42. package/dist/esm/sessionPreviews.js +9 -0
  43. package/dist/esm/sessionPromptHistory.js +5 -3
  44. package/dist/esm/subagentActivity.js +125 -0
  45. package/dist/esm/subagentDisplayState.js +81 -0
  46. package/dist/esm/subagentSpawn.js +363 -0
  47. package/dist/esm/testing/codexSubagentFixtures.js +336 -0
  48. package/dist/esm/toolCallOrigins.js +17 -10
  49. package/dist/esm/toolCategory.js +6 -2
  50. package/dist/esm/transcript.js +8 -0
  51. package/dist/esm/turns/assistantTurn.js +6 -2
  52. package/dist/esm/usage/claudeUsageDedupe.js +68 -0
  53. package/dist/esm/usage/usageEvents.js +4 -1
  54. package/dist/esm/watchers/eventBridge.js +45 -0
  55. package/dist/esm/watchers/factory.js +5 -3
  56. package/dist/esm/watchers/jsonlTail.js +82 -48
  57. package/dist/esm/watchers/jsonlWatcher.js +61 -4
  58. package/dist/esm/watchers/providerReaderWatcher.js +18 -4
  59. package/dist/esm/zaiQuota.js +2 -1
  60. package/dist/fileContinuity.d.ts +95 -0
  61. package/dist/fileContinuity.js +187 -0
  62. package/dist/formatters/toolSummary.js +4 -1
  63. package/dist/index.d.ts +19 -7
  64. package/dist/index.js +48 -10
  65. package/dist/modelCatalog.js +5 -4
  66. package/dist/modelContext.js +4 -3
  67. package/dist/modelInfo.js +4 -3
  68. package/dist/node.d.ts +5 -1
  69. package/dist/node.js +18 -2
  70. package/dist/observedContextWindows.js +2 -1
  71. package/dist/ownKey.d.ts +16 -0
  72. package/dist/ownKey.js +30 -0
  73. package/dist/parsers/codexParser.d.ts +107 -0
  74. package/dist/parsers/codexParser.js +373 -7
  75. package/dist/parsers/openCodeParser.js +2 -1
  76. package/dist/parsers/subagentEndState.d.ts +20 -0
  77. package/dist/parsers/subagentEndState.js +65 -0
  78. package/dist/parsers/subagentScanner.d.ts +19 -6
  79. package/dist/parsers/subagentScanner.js +37 -12
  80. package/dist/parsers/subagentTraceParser.d.ts +33 -5
  81. package/dist/parsers/subagentTraceParser.js +103 -37
  82. package/dist/pricingCatalog.js +3 -2
  83. package/dist/promptHistory.d.ts +13 -3
  84. package/dist/promptHistory.js +22 -11
  85. package/dist/providers/claudeCode.js +59 -28
  86. package/dist/providers/codex.d.ts +35 -5
  87. package/dist/providers/codex.js +232 -198
  88. package/dist/providers/codexCompressedReader.d.ts +58 -0
  89. package/dist/providers/codexCompressedReader.js +221 -0
  90. package/dist/providers/codexDatabase.d.ts +25 -0
  91. package/dist/providers/codexDatabase.js +48 -2
  92. package/dist/providers/codexRollouts.d.ts +16 -2
  93. package/dist/providers/codexRollouts.js +20 -2
  94. package/dist/providers/codexSubagents.d.ts +66 -0
  95. package/dist/providers/codexSubagents.js +495 -0
  96. package/dist/providers/compressedRollouts.d.ts +114 -0
  97. package/dist/providers/compressedRollouts.js +380 -0
  98. package/dist/providers/factory.d.ts +5 -0
  99. package/dist/providers/factory.js +4 -1
  100. package/dist/providers/rolloutWalker.d.ts +15 -2
  101. package/dist/providers/rolloutWalker.js +33 -4
  102. package/dist/providers/types.d.ts +36 -1
  103. package/dist/schemas/index.d.ts +1 -0
  104. package/dist/schemas/sessionEvent.d.ts +51 -10
  105. package/dist/schemas/sessionEvent.js +63 -14
  106. package/dist/sessionMonitor.d.ts +6 -0
  107. package/dist/sessionMonitor.js +7 -1
  108. package/dist/sessionPreviews.js +9 -0
  109. package/dist/sessionPromptHistory.d.ts +5 -0
  110. package/dist/sessionPromptHistory.js +5 -36
  111. package/dist/subagentActivity.d.ts +91 -0
  112. package/dist/subagentActivity.js +132 -0
  113. package/dist/subagentDisplayState.d.ts +81 -0
  114. package/dist/subagentDisplayState.js +86 -0
  115. package/dist/subagentSpawn.d.ts +175 -0
  116. package/dist/subagentSpawn.js +385 -0
  117. package/dist/testing/codexSubagentFixtures.d.ts +48 -0
  118. package/dist/testing/codexSubagentFixtures.js +344 -0
  119. package/dist/toolCallOrigins.d.ts +5 -0
  120. package/dist/toolCallOrigins.js +17 -10
  121. package/dist/toolCategory.js +6 -2
  122. package/dist/transcript.js +8 -0
  123. package/dist/turns/assistantTurn.d.ts +4 -0
  124. package/dist/turns/assistantTurn.js +6 -2
  125. package/dist/types/codex.d.ts +71 -2
  126. package/dist/types/sessionEvent.d.ts +38 -3
  127. package/dist/usage/claudeUsageDedupe.d.ts +31 -0
  128. package/dist/usage/claudeUsageDedupe.js +68 -0
  129. package/dist/usage/usageEvents.d.ts +4 -1
  130. package/dist/usage/usageEvents.js +4 -1
  131. package/dist/watchers/eventBridge.js +45 -0
  132. package/dist/watchers/factory.d.ts +6 -0
  133. package/dist/watchers/factory.js +5 -3
  134. package/dist/watchers/jsonlTail.d.ts +27 -4
  135. package/dist/watchers/jsonlTail.js +84 -48
  136. package/dist/watchers/jsonlWatcher.d.ts +22 -1
  137. package/dist/watchers/jsonlWatcher.js +60 -3
  138. package/dist/watchers/providerReaderWatcher.d.ts +7 -0
  139. package/dist/watchers/providerReaderWatcher.js +18 -4
  140. package/dist/watchers/types.d.ts +12 -0
  141. package/dist/zaiQuota.js +2 -1
  142. package/package.json +1 -1
@@ -2,11 +2,15 @@
2
2
  * Session snapshot sidecar — persists aggregator state + reader position
3
3
  * so that re-attaching to a session skips full replay.
4
4
  *
5
- * Snapshots are stored in ~/.config/sidekick/snapshots/{sessionId}.json.
6
- * They are invalidated when the source file changes beyond the snapshot position.
5
+ * Snapshots are stored in `<config dir>/snapshots/{sessionId}.json` (see
6
+ * `getConfigDir()`). They are invalidated when the source file shrank below
7
+ * the snapshot position or, for file-backed sessions that recorded a
8
+ * {@link SessionSnapshot.sourceCheckpoint}, when the file is no longer the
9
+ * same append-only file.
7
10
  *
8
11
  * @module aggregation/snapshot
9
12
  */
13
+ import { type JsonlTailCheckpoint } from '../watchers/jsonlTail';
10
14
  import { type SerializedAggregatorState } from './EventAggregator';
11
15
  /** Newest snapshots kept on disk; older ones are pruned opportunistically. */
12
16
  export declare const MAX_SNAPSHOT_FILES = 200;
@@ -22,6 +26,23 @@ export interface SessionSnapshot {
22
26
  readerPosition: number;
23
27
  /** Source file size at snapshot time (for staleness check; 0 for DB-backed). */
24
28
  sourceSize: number;
29
+ /**
30
+ * Identity of the source file at `readerPosition`, from
31
+ * `captureJsonlCheckpoint(sourcePath, readerPosition)`: its device and
32
+ * inode plus a digest of its first bytes. Present for file-backed sessions
33
+ * written by 0.29.1 and later; absent for DB-backed sessions and older
34
+ * snapshots. {@link isSnapshotValid} checks it when given the source path.
35
+ */
36
+ sourceCheckpoint?: JsonlTailCheckpoint;
37
+ /**
38
+ * The reader's parse state at `readerPosition`, from
39
+ * `SessionReader.getResumeState()` or `SessionWatcher.getResumeState()`
40
+ * (for Claude Code, which split-line responses were already counted).
41
+ * After seeking to `readerPosition`, pass it to `restoreResumeState()` and
42
+ * replay from the start when that returns false. Absent when the reader
43
+ * keeps none, and in snapshots written before 0.29.1.
44
+ */
45
+ readerState?: unknown;
25
46
  /** ISO timestamp when snapshot was written. */
26
47
  createdAt: string;
27
48
  /** Serialized EventAggregator state. */
@@ -55,8 +76,8 @@ export declare function pruneSnapshots(keep?: number): number;
55
76
  * - Schema version doesn't match
56
77
  * - JSON parse fails
57
78
  *
58
- * The caller is responsible for staleness checks (comparing sourceSize
59
- * and readerPosition against the actual file).
79
+ * The caller is responsible for staleness checks against the actual file:
80
+ * `isSnapshotValid(snapshot, currentSize, sourcePath)`.
60
81
  */
61
82
  export declare function loadSnapshot(sessionId: string): SessionSnapshot | null;
62
83
  /**
@@ -66,10 +87,18 @@ export declare function deleteSnapshot(sessionId: string): void;
66
87
  /**
67
88
  * Validates whether a snapshot is still usable for a given source file.
68
89
  *
69
- * For JSONL providers: checks that the file hasn't been truncated
70
- * (current size >= snapshot position) and that the size matches or has grown.
71
- *
72
90
  * For DB-backed providers: sourceSize is 0, so we always consider valid
73
91
  * (the DB reader's timestamp-based cursor handles staleness naturally).
92
+ *
93
+ * For JSONL providers: the file must not have shrunk below the snapshot
94
+ * position. With `sourcePath` the check is also content-aware: the snapshot
95
+ * must carry a {@link SessionSnapshot.sourceCheckpoint} for exactly
96
+ * `readerPosition`, and that checkpoint must still match the file at
97
+ * `sourcePath` (same device and inode, same first bytes, position just after
98
+ * a newline), so a file replaced by another one or rewritten to the same or
99
+ * a larger size is not resumed mid-content. A snapshot without a checkpoint
100
+ * (written before 0.29.1) is invalid when `sourcePath` is given, which costs
101
+ * one full replay. Without `sourcePath` only the size check applies, as it
102
+ * did before.
74
103
  */
75
- export declare function isSnapshotValid(snapshot: SessionSnapshot, currentSourceSize: number): boolean;
104
+ export declare function isSnapshotValid(snapshot: SessionSnapshot, currentSourceSize: number, sourcePath?: string): boolean;
@@ -3,8 +3,11 @@
3
3
  * Session snapshot sidecar — persists aggregator state + reader position
4
4
  * so that re-attaching to a session skips full replay.
5
5
  *
6
- * Snapshots are stored in ~/.config/sidekick/snapshots/{sessionId}.json.
7
- * They are invalidated when the source file changes beyond the snapshot position.
6
+ * Snapshots are stored in `<config dir>/snapshots/{sessionId}.json` (see
7
+ * `getConfigDir()`). They are invalidated when the source file shrank below
8
+ * the snapshot position or, for file-backed sessions that recorded a
9
+ * {@link SessionSnapshot.sourceCheckpoint}, when the file is no longer the
10
+ * same append-only file.
8
11
  *
9
12
  * @module aggregation/snapshot
10
13
  */
@@ -52,6 +55,7 @@ exports.isSnapshotValid = isSnapshotValid;
52
55
  const fs = __importStar(require("fs"));
53
56
  const path = __importStar(require("path"));
54
57
  const paths_1 = require("../paths");
58
+ const jsonlTail_1 = require("../watchers/jsonlTail");
55
59
  const atomic_1 = require("../writers/atomic");
56
60
  const EventAggregator_1 = require("./EventAggregator");
57
61
  /** Current schema version — bump when format changes. */
@@ -143,8 +147,8 @@ function pruneSnapshots(keep = exports.MAX_SNAPSHOT_FILES) {
143
147
  * - Schema version doesn't match
144
148
  * - JSON parse fails
145
149
  *
146
- * The caller is responsible for staleness checks (comparing sourceSize
147
- * and readerPosition against the actual file).
150
+ * The caller is responsible for staleness checks against the actual file:
151
+ * `isSnapshotValid(snapshot, currentSize, sourcePath)`.
148
152
  */
149
153
  function loadSnapshot(sessionId) {
150
154
  try {
@@ -184,13 +188,21 @@ function deleteSnapshot(sessionId) {
184
188
  /**
185
189
  * Validates whether a snapshot is still usable for a given source file.
186
190
  *
187
- * For JSONL providers: checks that the file hasn't been truncated
188
- * (current size >= snapshot position) and that the size matches or has grown.
189
- *
190
191
  * For DB-backed providers: sourceSize is 0, so we always consider valid
191
192
  * (the DB reader's timestamp-based cursor handles staleness naturally).
193
+ *
194
+ * For JSONL providers: the file must not have shrunk below the snapshot
195
+ * position. With `sourcePath` the check is also content-aware: the snapshot
196
+ * must carry a {@link SessionSnapshot.sourceCheckpoint} for exactly
197
+ * `readerPosition`, and that checkpoint must still match the file at
198
+ * `sourcePath` (same device and inode, same first bytes, position just after
199
+ * a newline), so a file replaced by another one or rewritten to the same or
200
+ * a larger size is not resumed mid-content. A snapshot without a checkpoint
201
+ * (written before 0.29.1) is invalid when `sourcePath` is given, which costs
202
+ * one full replay. Without `sourcePath` only the size check applies, as it
203
+ * did before.
192
204
  */
193
- function isSnapshotValid(snapshot, currentSourceSize) {
205
+ function isSnapshotValid(snapshot, currentSourceSize, sourcePath) {
194
206
  // DB-backed providers store sourceSize=0 — always valid (cursor is a timestamp)
195
207
  if (snapshot.sourceSize === 0) {
196
208
  return true;
@@ -199,5 +211,15 @@ function isSnapshotValid(snapshot, currentSourceSize) {
199
211
  if (currentSourceSize < snapshot.readerPosition) {
200
212
  return false;
201
213
  }
202
- return true;
214
+ if (typeof sourcePath !== 'string') {
215
+ return true;
216
+ }
217
+ // Snapshot content comes from disk: guard the shape before trusting it.
218
+ const checkpoint = snapshot.sourceCheckpoint;
219
+ if (!checkpoint ||
220
+ typeof checkpoint !== 'object' ||
221
+ checkpoint.offset !== snapshot.readerPosition) {
222
+ return false;
223
+ }
224
+ return (0, jsonlTail_1.verifyJsonlCheckpoint)(sourcePath, checkpoint);
203
225
  }
@@ -117,15 +117,52 @@ export interface BurnRateInfo {
117
117
  /** Number of samples in the window. */
118
118
  sampleCount: number;
119
119
  }
120
+ /** How a subagent ended: a failed spawn, or a background agent's notification status. */
121
+ export type SubagentOutcome = 'completed' | 'failed' | 'killed' | 'stopped';
122
+ /**
123
+ * What settled a background subagent, when something other than its spawn's
124
+ * own tool result did:
125
+ *
126
+ * - `notification`: its final task notification (Claude Code), or a Codex
127
+ * `SubAgentActivity` `completed` record or `FINAL_ANSWER` report.
128
+ * - `meta`: the host's evidence from Claude Code's `agent-<id>.meta.json`
129
+ * (`finished`, `stoppedByUser`), via `EventAggregator.applySubagentEvidence()`.
130
+ * - `stop-marker`: an in-stream stop: Claude Code's `agents_killed` system
131
+ * line or its "background agents were stopped by the user" notice, or a
132
+ * Codex `interrupt_agent` record.
133
+ * - `task-status`: a Claude Code `task_status` attachment with a final status.
134
+ */
135
+ export type SubagentSettledBy = 'notification' | 'meta' | 'stop-marker' | 'task-status';
120
136
  /** Subagent lifecycle info (for tracking spawn/completion from tool events). */
121
137
  export interface SubagentLifecycle {
138
+ /** The spawning tool_use id (`Agent` / `Task`, or Codex `spawn_agent`). */
122
139
  id: string;
123
140
  description: string;
124
141
  subagentType: string;
125
142
  spawnTime: string;
126
143
  completionTime?: string;
144
+ /**
145
+ * A background agent stays `running` after its spawn's immediate result
146
+ * until its task notification arrives.
147
+ */
127
148
  status: 'running' | 'completed';
128
149
  durationMs?: number;
150
+ /**
151
+ * The agent's id, once known: Claude Code's agent id (the `agent-<id>.jsonl`
152
+ * transcript name), or the Codex child thread id (its rollout's session id).
153
+ */
154
+ agentId?: string;
155
+ /** Codex: the child's agent path (e.g. `/root/review_builder`), once known. */
156
+ agentPath?: string;
157
+ /** The agent was launched in the background (its spawn returned at once). */
158
+ background?: boolean;
159
+ /** How the agent ended, once `status` is `completed`. */
160
+ outcome?: SubagentOutcome;
161
+ /**
162
+ * What settled a background agent (see {@link SubagentSettledBy}); absent
163
+ * while it runs and when its spawn's own result settled it.
164
+ */
165
+ settledBy?: SubagentSettledBy;
129
166
  }
130
167
  /** Frequency entry for tool/word frequency tracking. */
131
168
  export interface FrequencyMetric {
@@ -165,7 +202,7 @@ export interface AggregatedMetrics {
165
202
  taskState: TaskState;
166
203
  subagents: SubagentLifecycle[];
167
204
  plan: PlanState | null;
168
- /** Current permission mode (default | acceptEdits | bypassPermissions | plan) */
205
+ /** Current permission mode (default | acceptEdits | bypassPermissions | plan | auto | dontAsk) */
169
206
  permissionMode: PermissionMode | null;
170
207
  /** History of permission mode changes */
171
208
  permissionModeHistory: PermissionModeChange[];
package/dist/browser.d.ts CHANGED
@@ -14,6 +14,7 @@ export type { UsageProvider, UsageSemantics, UsageNormalizationProvenance, Provi
14
14
  export { formatTokenBreakdown, summarizeTokens, sumTokenTotals, TOKEN_CONTEXT_LABEL, TOKEN_MAIN_THREAD_LABEL, TOKEN_SESSION_TOTAL_LABEL, TOKEN_SUBAGENTS_LABEL, TOKEN_TOTAL_LABEL, } from './tokenSummary';
15
15
  export type { TokenSummary, TokenTotalsLike } from './tokenSummary';
16
16
  export { ClaudeUsageDeduper, SYNTHETIC_MODEL } from './usage/claudeUsageDedupe';
17
+ export type { ClaudeUsageDedupeBuckets, ClaudeUsageDedupeState } from './usage/claudeUsageDedupe';
17
18
  export { ASCII_CHARS_PER_TOKEN, estimateTextTokens, estimateSerializedTokens, } from './tokenEstimation';
18
19
  export type { ExactTokenCounterContext, ExactTokenCounter, TokenEstimationMethod, TokenEstimationConfidence, TokenEstimationOptions, TokenEstimate, } from './tokenEstimation';
19
20
  export { projectSessionTranscript } from './transcript';
@@ -28,6 +29,11 @@ export type { AccountProviderId, ModelProviderId, QuotaProviderId, RuntimeQuotaP
28
29
  /** Same type as `ProviderId` from the package root and `sidekick-shared/node`. */
29
30
  SessionProviderId as ProviderId, } from './providerIds';
30
31
  export type { BuildSessionContextSnapshotOptions, SessionContextCapabilities, SessionContextLayerBreakdown, SessionContextPressure, SessionContextProjector, SessionContextSnapshot, SessionContextSource, SessionContextSourceType, } from './context/sessionContext';
32
+ export { SUBAGENT_SPAWN_TOOL_NAMES, agentsStoppedNoticeFromEvent, isAgentsKilledSystemEvent, isCodexSubagentSpawnTool, isSubagentSpawnTool, isTaskNotificationSystemEvent, isTaskStatusSystemEvent, parseAgentsStoppedNotice, parseCodexSpawnLaunch, parseTaskNotification, taskNotificationFromEvent, taskStatusFromAttachment, taskStatusFromEvent, } from './subagentSpawn';
33
+ export type { AgentsStoppedNotice, CodexSpawnLaunch, SubagentTaskStatus, TaskNotification, } from './subagentSpawn';
34
+ export { SUBAGENT_PARENT_IDLE_ENDED_MS, SUBAGENT_UNREPORTED_QUIET_MS, resolveSubagentDisplayState, subagentDisplayLabel, } from './subagentDisplayState';
35
+ export type { SubagentDisplayLifecycle, SubagentDisplayOptions, SubagentDisplayReason, SubagentDisplayState, SubagentDisplayStateName, SubagentDisplayTrace, } from './subagentDisplayState';
36
+ export type { SubagentOutcome, SubagentSettledBy } from './aggregation/types';
31
37
  export { assistantTurnEventsFromSessionEvents, extractTurnSubagents, isAssistantTurnSubagentTool, reasoningSummary, segmentAssistantTurn, } from './turns/assistantTurn';
32
38
  export type { AssistantTurnEvent, AssistantTurnEventType, AssistantTurnProcess, AssistantTurnProcessStep, AssistantTurnProjection, AssistantTurnSubagent, AssistantTurnSubagentStatus, AssistantTurnTimelineItem, AssistantTurnToolRef, ExtractTurnSubagentsOptions, ReasoningSummary, SegmentAssistantTurnOptions, } from './turns/assistantTurn';
33
39
  export { parseModelId, getModelPricing, resolveModelPricing, getModelInfo, calculateCost, calculateCostWithPricing, calculateCostWithProvenance, mergeCostSources, shortModelName, getModelDisplayInfo, compareModelIds, sortModelIds, formatCost, canonicalModelId, isMovingModelAlias, registerModelPricing, clearRegisteredModelPricing, getPricingCatalogInfo, costSourceFromPricingProvenance, mergeCostComponents, } from './modelInfo';
@@ -51,9 +57,11 @@ export type { SessionEvent, ClaudeSessionEvent, MessageUsage, SessionMessage, Se
51
57
  export type { CodexRolloutLine, CodexSessionMeta, CodexResponseItem, CodexMessageItem, CodexContentPart, CodexReasoningItem, CodexFunctionCallItem, CodexFunctionCallOutputItem, CodexLocalShellCallItem, CodexWebSearchCallItem, CodexCustomToolCallItem, CodexCustomToolCallOutputItem, CodexCompacted, CodexTurnContext, CodexEventMsg, CodexEvent, CodexTurnStartedEvent, CodexTurnCompleteEvent, CodexTaskStartedEvent, CodexTaskCompleteEvent, CodexTurnAbortedEvent, CodexTokenCountEvent, CodexTokenUsage, CodexRateLimits, CodexAgentMessageEvent, CodexAgentReasoningEvent, CodexUserMessageEvent, CodexExecCommandBeginEvent, CodexExecCommandEndEvent, CodexMcpToolCallBeginEvent, CodexMcpToolCallEndEvent, CodexErrorEvent, CodexContextCompactedEvent, CodexPatchAppliedEvent, CodexBackgroundEvent, CodexGenericEvent, CodexDbThread, CodexReasoningSummary, } from './types/codex';
52
58
  export { isAggregateCodexLimit } from './types/codex';
53
59
  export { CodexRolloutParser, DEFAULT_MAX_TRACKED_TOOL_CALLS, extractPatchFilePaths, normalizeCodexToolName, normalizeCodexToolInput, resolveCodexCallUsage, } from './parsers/codexParser';
54
- export type { CodexPendingStats, CodexRolloutParserOptions } from './parsers/codexParser';
60
+ export type { CodexPendingStats, CodexRolloutParserOptions, CodexRolloutResumeState, } from './parsers/codexParser';
55
61
  export { codexRolloutOrigin, codexSpawnParentFromSource } from './parsers/codexRolloutOrigin';
56
62
  export type { CodexRolloutOrigin } from './parsers/codexRolloutOrigin';
63
+ export { SUBAGENT_ACTIVITY_BLOCK_TYPE, SUBAGENT_ACTIVITY_ORIGIN_KIND, describeSubagentActivity, isSubagentActivitySystemEvent, parseCodexAgentMessageText, subagentActivityFromEvent, } from './subagentActivity';
64
+ export type { CodexAgentMessageText, SubagentActivity, SubagentActivityKind, } from './subagentActivity';
57
65
  export { HUMAN_CLAUDE_ENTRYPOINTS, HUMAN_CODEX_SOURCES, humanPromptText, isHumanPrompt, } from './humanPrompt';
58
66
  export type { HumanPromptProvider } from './humanPrompt';
59
67
  export { renderHandoffUrlTemplate } from './handoffUrl';
package/dist/browser.js CHANGED
@@ -9,9 +9,9 @@
9
9
  * For pricing hydration (LiteLLM catalog refresh), use `sidekick-shared/node`.
10
10
  */
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.resolveModelPricing = exports.getModelPricing = exports.parseModelId = exports.segmentAssistantTurn = exports.reasoningSummary = exports.isAssistantTurnSubagentTool = exports.extractTurnSubagents = exports.assistantTurnEventsFromSessionEvents = exports.SESSION_PROVIDER_IDS = exports.RUNTIME_QUOTA_PROVIDER_IDS = exports.QUOTA_PROVIDER_IDS = exports.MODEL_PROVIDER_IDS = exports.ACCOUNT_PROVIDER_IDS = exports.createSessionContextProjector = exports.calculateSessionContextPressure = exports.buildSessionContextSnapshot = exports.parseMcpToolName = exports.parseLocalDateKey = exports.formatTokenCount = exports.formatLocalDateKey = exports.formatDurationMs = exports.addLocalDays = exports.projectSessionTranscript = exports.estimateSerializedTokens = exports.estimateTextTokens = exports.ASCII_CHARS_PER_TOKEN = exports.SYNTHETIC_MODEL = exports.ClaudeUsageDeduper = exports.TOKEN_TOTAL_LABEL = exports.TOKEN_SUBAGENTS_LABEL = exports.TOKEN_SESSION_TOTAL_LABEL = exports.TOKEN_MAIN_THREAD_LABEL = exports.TOKEN_CONTEXT_LABEL = exports.sumTokenTotals = exports.summarizeTokens = exports.formatTokenBreakdown = exports.calculateNormalizedUsageCost = exports.extractNormalizedUsage = exports.normalizeProviderUsage = exports.DEFAULT_CONTEXT_WINDOW = exports.resolveModelContextWindow = exports.getModelContextWindowSize = void 0;
13
- exports.HUMAN_CLAUDE_ENTRYPOINTS = exports.codexSpawnParentFromSource = exports.codexRolloutOrigin = exports.resolveCodexCallUsage = exports.normalizeCodexToolInput = exports.normalizeCodexToolName = exports.extractPatchFilePaths = exports.DEFAULT_MAX_TRACKED_TOOL_CALLS = exports.CodexRolloutParser = exports.isAggregateCodexLimit = exports.parseCodexLoginStatus = exports.parseClaudeAuthStatus = exports.decodeCodexErrorInfo = exports.CODEX_ERROR_INFO_KINDS = exports.PROVIDER_RECOVERY_ACTIONS = exports.PROVIDER_FAILURE_EVIDENCE_SOURCES = exports.PROVIDER_FAILURE_CODES = exports.PROVIDER_CREDENTIAL_KINDS = exports.PROVIDER_AUTHENTICATION_STATES = exports.PROVIDER_AUTHENTICATION_SOURCES = exports.diagnoseProviderFailure = exports.mergeFailingToolWindows = exports.failingToolTrend = exports.FAILING_TOOL_TREND_ARROWS = exports.sessionSummaryFromStats = exports.removeSessionSummary = exports.markFileImported = exports.isFileImported = exports.applySessionSummary = exports.weekKey = exports.usageBucketKey = exports.summarizeUsageRows = exports.bucketUsage = exports.findActiveBillingBlock = exports.computeBillingBlocks = exports.BILLING_BLOCK_DURATION_MS = exports.RESOLVED_MODEL_CATALOG_SCHEMA_VERSION = exports.resolveModelAlias = exports.registerModelAlias = exports.importResolvedModelCatalog = exports.exportResolvedModelCatalog = exports.mergeCostComponents = exports.costSourceFromPricingProvenance = exports.getPricingCatalogInfo = exports.clearRegisteredModelPricing = exports.registerModelPricing = exports.isMovingModelAlias = exports.canonicalModelId = exports.formatCost = exports.sortModelIds = void 0;
14
- exports.quotaWindowShortLabel = exports.quotaWindowLabel = exports.quotaWindowHasData = exports.quotaWindowApplies = exports.formatExtraUsage = exports.extraQuotaRows = exports.claudePlanLabel = exports.TOOL_CATEGORIES = exports.classifyTool = exports.renderHandoffUrlTemplate = exports.isHumanPrompt = exports.humanPromptText = exports.HUMAN_CODEX_SOURCES = void 0;
12
+ exports.resolveSubagentDisplayState = exports.SUBAGENT_UNREPORTED_QUIET_MS = exports.SUBAGENT_PARENT_IDLE_ENDED_MS = exports.taskStatusFromEvent = exports.taskStatusFromAttachment = exports.taskNotificationFromEvent = exports.parseTaskNotification = exports.parseCodexSpawnLaunch = exports.parseAgentsStoppedNotice = exports.isTaskStatusSystemEvent = exports.isTaskNotificationSystemEvent = exports.isSubagentSpawnTool = exports.isCodexSubagentSpawnTool = exports.isAgentsKilledSystemEvent = exports.agentsStoppedNoticeFromEvent = exports.SUBAGENT_SPAWN_TOOL_NAMES = exports.SESSION_PROVIDER_IDS = exports.RUNTIME_QUOTA_PROVIDER_IDS = exports.QUOTA_PROVIDER_IDS = exports.MODEL_PROVIDER_IDS = exports.ACCOUNT_PROVIDER_IDS = exports.createSessionContextProjector = exports.calculateSessionContextPressure = exports.buildSessionContextSnapshot = exports.parseMcpToolName = exports.parseLocalDateKey = exports.formatTokenCount = exports.formatLocalDateKey = exports.formatDurationMs = exports.addLocalDays = exports.projectSessionTranscript = exports.estimateSerializedTokens = exports.estimateTextTokens = exports.ASCII_CHARS_PER_TOKEN = exports.SYNTHETIC_MODEL = exports.ClaudeUsageDeduper = exports.TOKEN_TOTAL_LABEL = exports.TOKEN_SUBAGENTS_LABEL = exports.TOKEN_SESSION_TOTAL_LABEL = exports.TOKEN_MAIN_THREAD_LABEL = exports.TOKEN_CONTEXT_LABEL = exports.sumTokenTotals = exports.summarizeTokens = exports.formatTokenBreakdown = exports.calculateNormalizedUsageCost = exports.extractNormalizedUsage = exports.normalizeProviderUsage = exports.DEFAULT_CONTEXT_WINDOW = exports.resolveModelContextWindow = exports.getModelContextWindowSize = void 0;
13
+ exports.PROVIDER_CREDENTIAL_KINDS = exports.PROVIDER_AUTHENTICATION_STATES = exports.PROVIDER_AUTHENTICATION_SOURCES = exports.diagnoseProviderFailure = exports.mergeFailingToolWindows = exports.failingToolTrend = exports.FAILING_TOOL_TREND_ARROWS = exports.sessionSummaryFromStats = exports.removeSessionSummary = exports.markFileImported = exports.isFileImported = exports.applySessionSummary = exports.weekKey = exports.usageBucketKey = exports.summarizeUsageRows = exports.bucketUsage = exports.findActiveBillingBlock = exports.computeBillingBlocks = exports.BILLING_BLOCK_DURATION_MS = exports.RESOLVED_MODEL_CATALOG_SCHEMA_VERSION = exports.resolveModelAlias = exports.registerModelAlias = exports.importResolvedModelCatalog = exports.exportResolvedModelCatalog = exports.mergeCostComponents = exports.costSourceFromPricingProvenance = exports.getPricingCatalogInfo = exports.clearRegisteredModelPricing = exports.registerModelPricing = exports.isMovingModelAlias = exports.canonicalModelId = exports.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.resolveModelPricing = exports.getModelPricing = exports.parseModelId = exports.segmentAssistantTurn = exports.reasoningSummary = exports.isAssistantTurnSubagentTool = exports.extractTurnSubagents = exports.assistantTurnEventsFromSessionEvents = exports.subagentDisplayLabel = void 0;
14
+ exports.quotaWindowShortLabel = exports.quotaWindowLabel = exports.quotaWindowHasData = exports.quotaWindowApplies = exports.formatExtraUsage = exports.extraQuotaRows = exports.claudePlanLabel = exports.TOOL_CATEGORIES = exports.classifyTool = exports.renderHandoffUrlTemplate = exports.isHumanPrompt = exports.humanPromptText = exports.HUMAN_CODEX_SOURCES = exports.HUMAN_CLAUDE_ENTRYPOINTS = exports.subagentActivityFromEvent = exports.parseCodexAgentMessageText = exports.isSubagentActivitySystemEvent = exports.describeSubagentActivity = exports.SUBAGENT_ACTIVITY_ORIGIN_KIND = exports.SUBAGENT_ACTIVITY_BLOCK_TYPE = exports.codexSpawnParentFromSource = exports.codexRolloutOrigin = exports.resolveCodexCallUsage = exports.normalizeCodexToolInput = exports.normalizeCodexToolName = exports.extractPatchFilePaths = exports.DEFAULT_MAX_TRACKED_TOOL_CALLS = exports.CodexRolloutParser = exports.isAggregateCodexLimit = exports.parseCodexLoginStatus = exports.parseClaudeAuthStatus = exports.decodeCodexErrorInfo = exports.CODEX_ERROR_INFO_KINDS = exports.PROVIDER_RECOVERY_ACTIONS = exports.PROVIDER_FAILURE_EVIDENCE_SOURCES = exports.PROVIDER_FAILURE_CODES = void 0;
15
15
  var modelContext_1 = require("./modelContext");
16
16
  Object.defineProperty(exports, "getModelContextWindowSize", { enumerable: true, get: function () { return modelContext_1.getModelContextWindowSize; } });
17
17
  Object.defineProperty(exports, "resolveModelContextWindow", { enumerable: true, get: function () { return modelContext_1.resolveModelContextWindow; } });
@@ -56,6 +56,25 @@ Object.defineProperty(exports, "MODEL_PROVIDER_IDS", { enumerable: true, get: fu
56
56
  Object.defineProperty(exports, "QUOTA_PROVIDER_IDS", { enumerable: true, get: function () { return providerIds_1.QUOTA_PROVIDER_IDS; } });
57
57
  Object.defineProperty(exports, "RUNTIME_QUOTA_PROVIDER_IDS", { enumerable: true, get: function () { return providerIds_1.RUNTIME_QUOTA_PROVIDER_IDS; } });
58
58
  Object.defineProperty(exports, "SESSION_PROVIDER_IDS", { enumerable: true, get: function () { return providerIds_1.SESSION_PROVIDER_IDS; } });
59
+ var subagentSpawn_1 = require("./subagentSpawn");
60
+ Object.defineProperty(exports, "SUBAGENT_SPAWN_TOOL_NAMES", { enumerable: true, get: function () { return subagentSpawn_1.SUBAGENT_SPAWN_TOOL_NAMES; } });
61
+ Object.defineProperty(exports, "agentsStoppedNoticeFromEvent", { enumerable: true, get: function () { return subagentSpawn_1.agentsStoppedNoticeFromEvent; } });
62
+ Object.defineProperty(exports, "isAgentsKilledSystemEvent", { enumerable: true, get: function () { return subagentSpawn_1.isAgentsKilledSystemEvent; } });
63
+ Object.defineProperty(exports, "isCodexSubagentSpawnTool", { enumerable: true, get: function () { return subagentSpawn_1.isCodexSubagentSpawnTool; } });
64
+ Object.defineProperty(exports, "isSubagentSpawnTool", { enumerable: true, get: function () { return subagentSpawn_1.isSubagentSpawnTool; } });
65
+ Object.defineProperty(exports, "isTaskNotificationSystemEvent", { enumerable: true, get: function () { return subagentSpawn_1.isTaskNotificationSystemEvent; } });
66
+ Object.defineProperty(exports, "isTaskStatusSystemEvent", { enumerable: true, get: function () { return subagentSpawn_1.isTaskStatusSystemEvent; } });
67
+ Object.defineProperty(exports, "parseAgentsStoppedNotice", { enumerable: true, get: function () { return subagentSpawn_1.parseAgentsStoppedNotice; } });
68
+ Object.defineProperty(exports, "parseCodexSpawnLaunch", { enumerable: true, get: function () { return subagentSpawn_1.parseCodexSpawnLaunch; } });
69
+ Object.defineProperty(exports, "parseTaskNotification", { enumerable: true, get: function () { return subagentSpawn_1.parseTaskNotification; } });
70
+ Object.defineProperty(exports, "taskNotificationFromEvent", { enumerable: true, get: function () { return subagentSpawn_1.taskNotificationFromEvent; } });
71
+ Object.defineProperty(exports, "taskStatusFromAttachment", { enumerable: true, get: function () { return subagentSpawn_1.taskStatusFromAttachment; } });
72
+ Object.defineProperty(exports, "taskStatusFromEvent", { enumerable: true, get: function () { return subagentSpawn_1.taskStatusFromEvent; } });
73
+ var subagentDisplayState_1 = require("./subagentDisplayState");
74
+ Object.defineProperty(exports, "SUBAGENT_PARENT_IDLE_ENDED_MS", { enumerable: true, get: function () { return subagentDisplayState_1.SUBAGENT_PARENT_IDLE_ENDED_MS; } });
75
+ Object.defineProperty(exports, "SUBAGENT_UNREPORTED_QUIET_MS", { enumerable: true, get: function () { return subagentDisplayState_1.SUBAGENT_UNREPORTED_QUIET_MS; } });
76
+ Object.defineProperty(exports, "resolveSubagentDisplayState", { enumerable: true, get: function () { return subagentDisplayState_1.resolveSubagentDisplayState; } });
77
+ Object.defineProperty(exports, "subagentDisplayLabel", { enumerable: true, get: function () { return subagentDisplayState_1.subagentDisplayLabel; } });
59
78
  var assistantTurn_1 = require("./turns/assistantTurn");
60
79
  Object.defineProperty(exports, "assistantTurnEventsFromSessionEvents", { enumerable: true, get: function () { return assistantTurn_1.assistantTurnEventsFromSessionEvents; } });
61
80
  Object.defineProperty(exports, "extractTurnSubagents", { enumerable: true, get: function () { return assistantTurn_1.extractTurnSubagents; } });
@@ -134,6 +153,13 @@ Object.defineProperty(exports, "resolveCodexCallUsage", { enumerable: true, get:
134
153
  var codexRolloutOrigin_1 = require("./parsers/codexRolloutOrigin");
135
154
  Object.defineProperty(exports, "codexRolloutOrigin", { enumerable: true, get: function () { return codexRolloutOrigin_1.codexRolloutOrigin; } });
136
155
  Object.defineProperty(exports, "codexSpawnParentFromSource", { enumerable: true, get: function () { return codexRolloutOrigin_1.codexSpawnParentFromSource; } });
156
+ var subagentActivity_1 = require("./subagentActivity");
157
+ Object.defineProperty(exports, "SUBAGENT_ACTIVITY_BLOCK_TYPE", { enumerable: true, get: function () { return subagentActivity_1.SUBAGENT_ACTIVITY_BLOCK_TYPE; } });
158
+ Object.defineProperty(exports, "SUBAGENT_ACTIVITY_ORIGIN_KIND", { enumerable: true, get: function () { return subagentActivity_1.SUBAGENT_ACTIVITY_ORIGIN_KIND; } });
159
+ Object.defineProperty(exports, "describeSubagentActivity", { enumerable: true, get: function () { return subagentActivity_1.describeSubagentActivity; } });
160
+ Object.defineProperty(exports, "isSubagentActivitySystemEvent", { enumerable: true, get: function () { return subagentActivity_1.isSubagentActivitySystemEvent; } });
161
+ Object.defineProperty(exports, "parseCodexAgentMessageText", { enumerable: true, get: function () { return subagentActivity_1.parseCodexAgentMessageText; } });
162
+ Object.defineProperty(exports, "subagentActivityFromEvent", { enumerable: true, get: function () { return subagentActivity_1.subagentActivityFromEvent; } });
137
163
  var humanPrompt_1 = require("./humanPrompt");
138
164
  Object.defineProperty(exports, "HUMAN_CLAUDE_ENTRYPOINTS", { enumerable: true, get: function () { return humanPrompt_1.HUMAN_CLAUDE_ENTRYPOINTS; } });
139
165
  Object.defineProperty(exports, "HUMAN_CODEX_SOURCES", { enumerable: true, get: function () { return humanPrompt_1.HUMAN_CODEX_SOURCES; } });
@@ -14,6 +14,8 @@ const EventAggregator_1 = require("../aggregation/EventAggregator");
14
14
  const modelContext_1 = require("../modelContext");
15
15
  const mcpToolName_1 = require("../parsers/mcpToolName");
16
16
  const tokenEstimation_1 = require("../tokenEstimation");
17
+ const subagentSpawn_1 = require("../subagentSpawn");
18
+ const subagentActivity_1 = require("../subagentActivity");
17
19
  const DEFAULT_CONTEXT_SOURCE_LIMIT = 200;
18
20
  const DEFAULT_SNIPPET_MAX_CHARS = 240;
19
21
  const DEFAULT_BODY_MAX_CHARS = 5000;
@@ -211,6 +213,12 @@ function extractSourcesFromEvent(event, state) {
211
213
  }
212
214
  }
213
215
  function extractSystemSource(event, state) {
216
+ // Background-task notices only update subagent lifecycles (like the aggregator).
217
+ if ((0, subagentSpawn_1.isTaskNotificationSystemEvent)(event) || (0, subagentSpawn_1.isTaskStatusSystemEvent)(event))
218
+ return;
219
+ // So are subagent lifecycle records (opt-in Codex parser events).
220
+ if ((0, subagentActivity_1.isSubagentActivitySystemEvent)(event))
221
+ return;
214
222
  const message = event.message;
215
223
  const text = extractText(message?.content);
216
224
  const label = message?.sourceLabel ?? message?.role ?? 'system';