sidekick-shared 0.18.4 → 0.19.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.
- package/README.md +23 -2
- package/dist/accounts.d.ts +1 -0
- package/dist/aggregation/EventAggregator.js +26 -11
- package/dist/browser.d.ts +2 -0
- package/dist/browser.js +5 -1
- package/dist/codexProfiles.d.ts +3 -2
- package/dist/codexProfiles.js +382 -52
- package/dist/context/sessionContext.d.ts +99 -0
- package/dist/context/sessionContext.js +523 -0
- package/dist/ensureDefaultAccounts.js +6 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +9 -3
- package/dist/modelContext.js +3 -1
- package/dist/modelInfo.js +69 -9
- package/dist/parsers/codexParser.d.ts +2 -0
- package/dist/parsers/codexParser.js +129 -63
- package/dist/providers/claudeCode.d.ts +2 -0
- package/dist/providers/claudeCode.js +4 -0
- package/dist/providers/codex.d.ts +2 -0
- package/dist/providers/codex.js +125 -91
- package/dist/providers/openCode.d.ts +2 -0
- package/dist/providers/openCode.js +4 -0
- package/dist/providers/types.d.ts +4 -0
- package/dist/report/htmlReportGenerator.js +3 -0
- package/dist/report/index.d.ts +1 -1
- package/dist/report/index.js +2 -1
- package/dist/report/transcriptParser.d.ts +3 -0
- package/dist/report/transcriptParser.js +25 -3
- package/dist/report/types.d.ts +2 -0
- package/dist/schemas/sessionEvent.d.ts +15 -0
- package/dist/schemas/sessionEvent.js +14 -1
- package/dist/types/sessionEvent.d.ts +16 -1
- package/dist/watchers/eventBridge.js +24 -0
- package/dist/watchers/factory.d.ts +2 -2
- package/dist/watchers/factory.js +7 -5
- package/dist/watchers/providerReaderWatcher.d.ts +27 -0
- package/dist/watchers/providerReaderWatcher.js +148 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,17 +26,18 @@ npm install sidekick-shared
|
|
|
26
26
|
| **Formatters** | Display helpers (`formatTokenCount()`, `formatDurationMs()`), tool summary, noise classification, session dump (text/markdown/JSON), event highlighting |
|
|
27
27
|
| **Search** | Cross-session full-text search, advanced filtering (substring, fuzzy, regex, date) |
|
|
28
28
|
| **Aggregation** | Event aggregation, frequency tracking, activity heatmaps, pattern extraction |
|
|
29
|
+
| **Session Context** | Provider-neutral context evidence snapshots (`buildSessionContextSnapshot()`, `calculateSessionContextPressure()`, `createSessionContextProjector()`, `readSessionContextSnapshot()`): layered evidence sources, low/medium/high context pressure, and observed capabilities (tools, MCP servers, permission mode, rate limits) |
|
|
29
30
|
| **Report** | Self-contained HTML session report generation |
|
|
30
31
|
| **Credentials** | Claude Max OAuth credential reading from `~/.claude/.credentials.json` |
|
|
31
32
|
| **Quota** | Claude Max subscription quota fetching (5-hour and 7-day windows) and Codex rate-limit extraction from event streams |
|
|
32
33
|
| **Provider Status** | API health checking via status.claude.com and status.openai.com (indicator, components, incidents) |
|
|
33
34
|
| **Schemas** | Zod schemas for runtime JSONL event validation (`sessionEventSchema`, `messageUsageSchema`, `sessionMessageSchema`) |
|
|
34
35
|
| **Extractors** | Pure functions for single-event processing: `extractTokenUsage()`, `extractToolCall()` (top-level `tool_use`), `extractToolCalls()` (assistant content blocks) |
|
|
35
|
-
| **Model Info & Pricing** | Model family parsing (Anthropic / OpenAI / Google, including legacy `claude-3-opus-…` and `claude-3-5-sonnet-…` IDs), context-window lookup (including Opus 4.7 / Sonnet 4.7 1M and GPT-5.x variants), pricing tables with optional LiteLLM hydration, null-aware cost (`calculateCost()`), provenance-preserving cost (`calculateCostWithProvenance()`, `mergeCostSources()`), and display helpers (`shortModelName()`, `getModelDisplayInfo()`, `compareModelIds()`, `sortModelIds()`, `formatCost()`) |
|
|
36
|
+
| **Model Info & Pricing** | Model family parsing (Anthropic / OpenAI / Google, including legacy `claude-3-opus-…` and `claude-3-5-sonnet-…` IDs), context-window lookup (including Fable 5 / Opus 4.8 / Opus 4.7 / Sonnet 4.7 1M and GPT-5.x variants), pricing tables with optional LiteLLM hydration, null-aware cost (`calculateCost()`), provenance-preserving cost (`calculateCostWithProvenance()`, `mergeCostSources()`), and display helpers (`shortModelName()`, `getModelDisplayInfo()`, `compareModelIds()`, `sortModelIds()`, `formatCost()`) |
|
|
36
37
|
| **Quota Polling** | `QuotaPoller` class with exponential backoff, active/idle intervals, and cached fallback |
|
|
37
38
|
| **Multi-Provider Quota** | `MultiProviderQuotaService` orchestrates Claude polling + peak-hours + account labels + Codex quota updates behind one typed `{ claude?, codex? }` event stream. `CodexQuotaWatcher` watches the active Codex rollout for live rate limits with snapshot fallback |
|
|
38
39
|
| **Accounts** | Multi-provider account registry (v2) with per-provider active account, save/switch/remove, v1 migration, `ensureDefaultAccounts()` for first-run bootstrap of the active system Claude/Codex credentials as a "Default" saved account, and `getActiveAccountStatus()` for a single-pass active-account read across providers |
|
|
39
|
-
| **Codex Profiles** | Codex account lifecycle — prepare, finalize, switch, remove — with
|
|
40
|
+
| **Codex Profiles** | Codex account lifecycle — prepare, finalize, switch, remove — switching atomically swaps the profile's backed-up credentials into the system `~/.codex/auth.json`, with rotated-token staleness protection, one-time dual-home migration, and legacy multi-home session monitoring |
|
|
40
41
|
| **Quota Snapshots** | Persistent quota caching per provider/account for offline fallback |
|
|
41
42
|
| **Phrases** | Curated humorous phrases for loading/idle states, available as a flat `ALL_PHRASES` array or grouped via `PHRASE_CATEGORIES` for category-aware UI |
|
|
42
43
|
|
|
@@ -180,6 +181,26 @@ const tools = extractToolCalls(event); // ToolCall[] — assistant
|
|
|
180
181
|
const toolFromEvent = extractToolCall(event); // ToolCall | null — top-level `tool_use` events
|
|
181
182
|
```
|
|
182
183
|
|
|
184
|
+
### Project session context evidence
|
|
185
|
+
|
|
186
|
+
Build a provider-neutral snapshot of what an assistant has "seen" in a session — layered evidence sources, context pressure, and observed capabilities. Read it through any session provider, or build it directly from a canonical `SessionEvent[]`.
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { detectProvider, readSessionContextSnapshot } from 'sidekick-shared';
|
|
190
|
+
|
|
191
|
+
const provider = await detectProvider('/path/to/project');
|
|
192
|
+
if (provider) {
|
|
193
|
+
const snapshot = readSessionContextSnapshot(provider, '/path/to/session.jsonl');
|
|
194
|
+
|
|
195
|
+
console.log(snapshot.pressure); // 'low' | 'medium' | 'high'
|
|
196
|
+
console.log(snapshot.contextTokens, '/', snapshot.contextWindow);
|
|
197
|
+
console.log(snapshot.capabilities.tools, snapshot.capabilities.mcpServers);
|
|
198
|
+
console.log(snapshot.sources.length, 'evidence sources');
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Use `createSessionContextProjector()` for incremental updates as new events stream in, or `calculateSessionContextPressure(contextTokens, contextWindow)` for the pressure band alone.
|
|
203
|
+
|
|
183
204
|
### Format shared dashboard values
|
|
184
205
|
|
|
185
206
|
```typescript
|
package/dist/accounts.d.ts
CHANGED
|
@@ -157,25 +157,29 @@ class EventAggregator {
|
|
|
157
157
|
if (event.message.model) {
|
|
158
158
|
this.currentModel = event.message.model;
|
|
159
159
|
}
|
|
160
|
-
// 3. Skip synthetic token-count events for messageCount
|
|
160
|
+
// 3. Skip system/audit events and synthetic token-count events for messageCount
|
|
161
161
|
const msgId = event.message.id ?? '';
|
|
162
|
-
if (!msgId.startsWith('token-count-')) {
|
|
162
|
+
if (event.type !== 'system' && !msgId.startsWith('token-count-')) {
|
|
163
163
|
this.messageCount++;
|
|
164
164
|
}
|
|
165
165
|
// 4. Latency tracking
|
|
166
|
-
|
|
166
|
+
if (event.type !== 'system') {
|
|
167
|
+
this.processLatency(event);
|
|
168
|
+
}
|
|
167
169
|
// 5. Token accumulation
|
|
168
170
|
if (event.message.usage) {
|
|
169
171
|
this.accumulateUsage(event.message.usage, event.timestamp, event.message.model);
|
|
170
172
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
173
|
+
if (event.type !== 'system') {
|
|
174
|
+
// 6. Tool extraction from content blocks
|
|
175
|
+
this.extractToolsFromContent(event);
|
|
176
|
+
// 7. Task state
|
|
177
|
+
this.extractTaskStateFromEvent(event);
|
|
178
|
+
// 8. Subagent tracking
|
|
179
|
+
this.extractSubagentFromEvent(event);
|
|
180
|
+
// 9. Plan extraction — convert SessionEvent to a FollowEvent shape for PlanExtractor
|
|
181
|
+
this.extractPlanFromSessionEvent(event);
|
|
182
|
+
}
|
|
179
183
|
// 10. Context attribution
|
|
180
184
|
this.attributeContextFromEvent(event);
|
|
181
185
|
// 11. Permission mode tracking
|
|
@@ -1447,6 +1451,12 @@ class EventAggregator {
|
|
|
1447
1451
|
this.contextAttribution.other += this.estimateTokens(text);
|
|
1448
1452
|
}
|
|
1449
1453
|
}
|
|
1454
|
+
else if (event.type === 'system') {
|
|
1455
|
+
const text = this.extractTextContent(event) || '';
|
|
1456
|
+
if (text) {
|
|
1457
|
+
this.contextAttribution.systemPrompt += this.estimateTokens(text);
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1450
1460
|
}
|
|
1451
1461
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1452
1462
|
// Private: Context Attribution from FollowEvent
|
|
@@ -1591,6 +1601,11 @@ class EventAggregator {
|
|
|
1591
1601
|
description = 'Context compacted';
|
|
1592
1602
|
noiseLevel = 'system';
|
|
1593
1603
|
break;
|
|
1604
|
+
case 'system':
|
|
1605
|
+
tlType = 'session_start';
|
|
1606
|
+
description = this.extractTextContent(event) ?? event.message.sourceLabel ?? 'System event';
|
|
1607
|
+
noiseLevel = 'system';
|
|
1608
|
+
break;
|
|
1594
1609
|
default:
|
|
1595
1610
|
tlType = 'session_start';
|
|
1596
1611
|
description = 'Event';
|
package/dist/browser.d.ts
CHANGED
|
@@ -10,5 +10,7 @@
|
|
|
10
10
|
export { getModelContextWindowSize, DEFAULT_CONTEXT_WINDOW } from './modelContext';
|
|
11
11
|
export { formatDurationMs, formatTokenCount } from './formatting';
|
|
12
12
|
export type { FormatDurationMsOptions, FormatTokenCountOptions } from './formatting';
|
|
13
|
+
export { buildSessionContextSnapshot, calculateSessionContextPressure, createSessionContextProjector, } from './context/sessionContext';
|
|
14
|
+
export type { BuildSessionContextSnapshotOptions, SessionContextCapabilities, SessionContextLayerBreakdown, SessionContextPressure, SessionContextProjector, SessionContextSnapshot, SessionContextSource, SessionContextSourceType, } from './context/sessionContext';
|
|
13
15
|
export { parseModelId, getModelPricing, getModelInfo, calculateCost, calculateCostWithPricing, calculateCostWithProvenance, mergeCostSources, shortModelName, getModelDisplayInfo, compareModelIds, sortModelIds, formatCost, } from './modelInfo';
|
|
14
16
|
export type { ModelPricing, CostTokenUsage, CostSource, CostProvenanceInput, CostWithProvenance, ModelProvider, ParsedModelId, ModelInfo, ModelDisplayInfo, } from './modelInfo';
|
package/dist/browser.js
CHANGED
|
@@ -9,13 +9,17 @@
|
|
|
9
9
|
* For pricing hydration (LiteLLM catalog refresh), use `sidekick-shared/node`.
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.getModelPricing = exports.parseModelId = exports.formatTokenCount = exports.formatDurationMs = exports.DEFAULT_CONTEXT_WINDOW = exports.getModelContextWindowSize = void 0;
|
|
12
|
+
exports.formatCost = exports.sortModelIds = exports.compareModelIds = exports.getModelDisplayInfo = exports.shortModelName = exports.mergeCostSources = exports.calculateCostWithProvenance = exports.calculateCostWithPricing = exports.calculateCost = exports.getModelInfo = exports.getModelPricing = exports.parseModelId = exports.createSessionContextProjector = exports.calculateSessionContextPressure = exports.buildSessionContextSnapshot = exports.formatTokenCount = exports.formatDurationMs = exports.DEFAULT_CONTEXT_WINDOW = exports.getModelContextWindowSize = void 0;
|
|
13
13
|
var modelContext_1 = require("./modelContext");
|
|
14
14
|
Object.defineProperty(exports, "getModelContextWindowSize", { enumerable: true, get: function () { return modelContext_1.getModelContextWindowSize; } });
|
|
15
15
|
Object.defineProperty(exports, "DEFAULT_CONTEXT_WINDOW", { enumerable: true, get: function () { return modelContext_1.DEFAULT_CONTEXT_WINDOW; } });
|
|
16
16
|
var formatting_1 = require("./formatting");
|
|
17
17
|
Object.defineProperty(exports, "formatDurationMs", { enumerable: true, get: function () { return formatting_1.formatDurationMs; } });
|
|
18
18
|
Object.defineProperty(exports, "formatTokenCount", { enumerable: true, get: function () { return formatting_1.formatTokenCount; } });
|
|
19
|
+
var sessionContext_1 = require("./context/sessionContext");
|
|
20
|
+
Object.defineProperty(exports, "buildSessionContextSnapshot", { enumerable: true, get: function () { return sessionContext_1.buildSessionContextSnapshot; } });
|
|
21
|
+
Object.defineProperty(exports, "calculateSessionContextPressure", { enumerable: true, get: function () { return sessionContext_1.calculateSessionContextPressure; } });
|
|
22
|
+
Object.defineProperty(exports, "createSessionContextProjector", { enumerable: true, get: function () { return sessionContext_1.createSessionContextProjector; } });
|
|
19
23
|
var modelInfo_1 = require("./modelInfo");
|
|
20
24
|
Object.defineProperty(exports, "parseModelId", { enumerable: true, get: function () { return modelInfo_1.parseModelId; } });
|
|
21
25
|
Object.defineProperty(exports, "getModelPricing", { enumerable: true, get: function () { return modelInfo_1.getModelPricing; } });
|
package/dist/codexProfiles.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare function getActiveCodexAccount(): SavedAccountProfile | null;
|
|
|
14
14
|
export declare function resolveSidekickCodexHome(): string;
|
|
15
15
|
export declare function getCodexExecutionEnv(baseEnv?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
16
16
|
export declare function prepareCodexAccount(label: string): CodexAccountManagerResult;
|
|
17
|
-
export declare function finalizeCodexAccount(profileId: string):
|
|
18
|
-
export declare function switchToCodexAccount(profileId: string):
|
|
17
|
+
export declare function finalizeCodexAccount(profileId: string): CodexAccountManagerResult;
|
|
18
|
+
export declare function switchToCodexAccount(profileId: string): CodexAccountManagerResult;
|
|
19
|
+
export declare function reconcileCodexAuthState(): void;
|
|
19
20
|
export declare function removeCodexAccount(profileId: string): AccountManagerResult;
|