@workerdeck/protocol 2.10.0 → 2.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.
package/build/index.d.mts CHANGED
@@ -1,10 +1,12 @@
1
1
  //#region src/pricing.d.ts
2
+ type CostBasis = 'list' | 'managed' | 'unknown';
2
3
  type TokenUsage = {
3
4
  input: number;
4
5
  output: number;
5
6
  cacheWrite5m: number;
6
7
  cacheWrite1h: number;
7
8
  cacheRead: number;
9
+ costBasis?: CostBasis;
8
10
  };
9
11
  type ByModel = Record<string, TokenUsage>;
10
12
  type ModelRate = {
@@ -28,18 +30,33 @@ declare const PRICING_AS_OF = "2026-09-19";
28
30
  declare const PRICING_SOURCES = "platform.claude.com and developers.openai.com list prices, bundled";
29
31
  declare const PRICING_NOTE = "List rates as of 2026-09-19. A subscription is a flat fee, so this is what the same tokens would have cost on the pay-as-you-go API, not a bill.";
30
32
  declare const UNPRICED_WARN_SHARE = 0.005;
33
+ declare const PRICING_STALE_DAYS = 90;
31
34
  declare const DEFAULT_PRICING: Record<string, ModelRate>;
35
+ type PricingTable = Record<string, ModelRate>;
36
+ type PricingOverrides = Record<string, ModelRate>;
37
+ type PricingMerge = {
38
+ pricing: PricingTable;
39
+ overrides: PricingOverrides;
40
+ dropped: string[];
41
+ };
42
+ declare function mergePricing(overrides: unknown, base?: PricingTable): PricingMerge;
43
+ declare function activePricing(): PricingTable;
44
+ declare function setPricingOverrides(overrides: unknown): PricingMerge;
45
+ declare function pricingAgeDays(now: number, asOf?: string): number;
46
+ declare function pricingAgeNote(now: number, asOf?: string): string | undefined;
32
47
  declare function canonicalModel(model: string): string;
33
- declare function rateFor(model: string | undefined, pricing?: Record<string, ModelRate>): ModelRate | undefined;
48
+ declare function rateFor(model: string | undefined, pricing?: PricingTable): ModelRate | undefined;
34
49
  declare function emptyTokenUsage(): TokenUsage;
35
50
  declare function totalTokens(usage: TokenUsage): number;
36
51
  declare function addTokenUsage(into: TokenUsage, add: TokenUsage): TokenUsage;
52
+ declare function worseBasis(a: CostBasis | undefined, b: CostBasis | undefined): CostBasis | undefined;
53
+ declare function unknownBasisModels(byModel: ByModel): string[];
37
54
  declare function mergeByModel(into: ByModel, add: ByModel): ByModel;
38
55
  declare function byModelTotalTokens(byModel: ByModel): number;
39
56
  declare function tokenUsageFromWire(usage: unknown): TokenUsage;
40
- declare function costOf(usage: TokenUsage, model: string | undefined, pricing?: Record<string, ModelRate>): CostBreakdown;
41
- declare function costOfByModel(byModel: ByModel, pricing?: Record<string, ModelRate>): CostBreakdown;
42
- declare function unpricedModels(byModel: ByModel, pricing?: Record<string, ModelRate>): string[];
57
+ declare function costOf(usage: TokenUsage, model: string | undefined, pricing?: PricingTable): CostBreakdown;
58
+ declare function costOfByModel(byModel: ByModel, pricing?: PricingTable): CostBreakdown;
59
+ declare function unpricedModels(byModel: ByModel, pricing?: PricingTable): string[];
43
60
  declare function meteredCost(cost: CostBreakdown): number;
44
61
  type SubscriptionComparison = {
45
62
  weeklyUsd: number;
@@ -132,6 +149,7 @@ declare function projectsOf(rows: readonly SessionRow[]): {
132
149
  declare function sessionLabel(info: SessionInfo): string;
133
150
  declare function projectKey(row: SessionRow): string;
134
151
  declare function projectLabel(row: Pick<SessionRow, 'info'>): string;
152
+ declare function projectName(row: Pick<SessionRow, 'info'>): string;
135
153
  declare function projectSubpath(row: Pick<SessionRow, 'info'>): string | undefined;
136
154
  declare function isJobRun(info: SessionInfo): boolean;
137
155
  declare function inScope(row: SessionRow, scope: WorkspaceScope): boolean;
@@ -152,6 +170,8 @@ declare const TOOL_TITLE_MAX_CHARS = 64;
152
170
  declare const BUILTIN_TOOL_TITLES: Record<string, string>;
153
171
  declare function toolTitle(name: string, titles?: Record<string, string>): string | undefined;
154
172
  declare function sanitizeToolTitle(title: string | undefined, name?: string): string | undefined;
173
+ declare const PEER_SEND_TOOLS: readonly ["peers_send", "mcp__workerdeck__peers_send"];
174
+ declare function isPeerSendTool(name: string): boolean;
155
175
  //#endregion
156
176
  //#region src/usage.d.ts
157
177
  type SessionUsage = {
@@ -443,6 +463,7 @@ type SessionEventBody = {
443
463
  attachments?: MessageAttachment[];
444
464
  patch?: FilePatch;
445
465
  uuid?: string;
466
+ origin?: MessageOrigin;
446
467
  } | {
447
468
  type: 'stream_delta';
448
469
  event: {
@@ -559,6 +580,7 @@ type AttachedFrame = {
559
580
  session: SessionInfo;
560
581
  replayingFrom: number;
561
582
  shell?: boolean;
583
+ pricingOverrides?: PricingOverrides;
562
584
  };
563
585
  type ToolCallRequestFrame = {
564
586
  type: 'tool_call_request';
@@ -767,7 +789,21 @@ type ProjectInfo = {
767
789
  name: string;
768
790
  root: string;
769
791
  icon?: ProjectIcon;
792
+ shortcode?: string;
770
793
  };
794
+ type MessageOrigin = {
795
+ kind: 'peer';
796
+ sessionId: string;
797
+ name?: string;
798
+ engine?: ProfileEngine;
799
+ hostId?: string;
800
+ hops?: string[];
801
+ };
802
+ declare function peerDeliveredPrefix(sessionId: string, name?: string): string;
803
+ declare function peerDeliveredTo(text: string): {
804
+ sessionId: string;
805
+ name?: string;
806
+ } | undefined;
771
807
  type SessionInfo = {
772
808
  id: string;
773
809
  sdkSessionId?: string;
@@ -974,6 +1010,7 @@ type JobUsage = {
974
1010
  tokens: number;
975
1011
  totalCostUsd: number;
976
1012
  numTurns: number;
1013
+ costUsd?: number;
977
1014
  };
978
1015
  type JobResult = {
979
1016
  subtype: string;
@@ -1075,5 +1112,5 @@ type QueueStatsResponse = {
1075
1112
  stats: QueueStats;
1076
1113
  };
1077
1114
  //#endregion
1078
- export { ApiMessage, AttachedFrame, BUILTIN_TOOL_TITLES, ByModel, CHECKLIST_TEXT_MAX, ChecklistItem, ChecklistStatus, ClientFrame, ContentBlock, ContextReading, ContextUsage, ContextUsageCategory, CostBreakdown, CreateJobRequest, CreateJobResponse, CreateProfileRequest, CreateSessionRequest, CreateSessionResponse, DEFAULT_PRICING, DEFAULT_VIEW_CONFIG, ENGINE_CAPABILITIES, EngineCapabilities, ErrorResponse, Facet, FilePatch, FindHostFilesResponse, GetJobResponse, GetProfileResponse, GetSessionResponse, GroupBy, HostDirEntry, HostFileMatch, HostFileRoot, ImageRefPart, JobEvent, JobInfo, JobProgress, JobResult, JobStatus, JobUsage, ListHostDirResponse, ListHostRootsResponse, ListJobsResponse, ListProfilesResponse, ListSdkSessionsResponse, ListSessionFilesResponse, ListSessionsResponse, McpServerActionRequest, McpServerConfigWire, McpServerStatusInfo, McpServerToolInfo, McpServersResponse, MessageAttachment, ModelOption, ModelRate, PRICING_AS_OF, PRICING_NOTE, PRICING_SOURCES, PROTOCOL_VERSION, PatchHunk, PermissionDecisionSource, PermissionMode, PermissionRequest, ProfileConfigSnapshot, ProfileDefaults, ProfileEngine, ProfileInfo, ProfileSessionDefaults, ProfileSpend, ProfileUsage, ProfileUsageWindow, ProjectIcon, ProjectInfo, ProviderConfig, QuestionBehavior, QueueServerFrame, QueueStats, QueueStatsResponse, RateLimitInfo, ReadHostFileResponse, ResolvePermissionRequest, ResolvePermissionResponse, SHELL_COMMAND_MAX, STATE_LABELS, STATE_ORDER, SUBAGENT_HISTORY, SaveProfileResponse, ScopeRoot, SdkSessionSummary, ServerFrame, SessionCapability, SessionCommand, SessionEvent, SessionEventBody, SessionFileInfo, SessionGroup, SessionInfo, SessionNotification, SessionNotificationType, SessionRow, SessionState, SessionStatus, SessionTask, SessionTaskSource, SessionTaskState, SessionUsage, SessionWebhookConfig, SkillInfo, SlashCommandInfo, SortBy, SubagentInfo, SubmitExecutionResultRequest, SubmitExecutionResultResponse, SubscriptionComparison, SubsetSummary, TOOL_RESULT_HEAD_CHARS, TOOL_TITLE_MAX_CHARS, TaskSummary, TextBlock, ThinkingBlock, TokenUsage, ToolCallRequestFrame, ToolExecutionBackend, ToolExecutionOutput, ToolExecutionStatus, ToolResultBlock, ToolUseBlock, UNPRICED_WARN_SHARE, USAGE_STALE_AFTER_MS, UnknownBlock, UpdateProfileRequest, UpdateSessionRequest, UpdateSessionResponse, UploadAttachmentResponse, UsageWindowRow, UserQuestion, UserQuestionOption, ViewConfig, Watermark, WatermarkStore, Watermarks, WebhookConfig, WorkspaceScope, WriteHostFileRequest, WriteHostFileResponse, adaptersOf, addTokenUsage, byModelTotalTokens, canonicalModel, clearFilters, contextReading, costOf, costOfByModel, emptyTokenUsage, filterRows, groupRows, hasFacetFilter, imagePartRef, inScope, isAgentRecord, isJobRun, mergeByModel, mergeUsage, meteredCost, orderUsageWindows, parseTodoWriteInput, parseUserQuestions, projectKey, projectLabel, projectSubpath, projectsOf, rateFor, replayCoalesceKey, replayRetains, runningSubagents, sanitizeToolTitle, scopeActive, sessionLabel, sessionState, sessionTasks, snapshotRetains, subagentLabel, subscriptionComparison, subsetSummary, supportsPermissionMode, taskCountLabel, taskSummary, tokenUsageFromWire, toolTitle, totalTokens, transcriptActivity, transcriptContent, transcriptProse, unpricedModels, unseenCount, usageInfos, usageIsStale, visibleTasks, watermarkKey };
1115
+ export { ApiMessage, AttachedFrame, BUILTIN_TOOL_TITLES, ByModel, CHECKLIST_TEXT_MAX, ChecklistItem, ChecklistStatus, ClientFrame, ContentBlock, ContextReading, ContextUsage, ContextUsageCategory, CostBasis, CostBreakdown, CreateJobRequest, CreateJobResponse, CreateProfileRequest, CreateSessionRequest, CreateSessionResponse, DEFAULT_PRICING, DEFAULT_VIEW_CONFIG, ENGINE_CAPABILITIES, EngineCapabilities, ErrorResponse, Facet, FilePatch, FindHostFilesResponse, GetJobResponse, GetProfileResponse, GetSessionResponse, GroupBy, HostDirEntry, HostFileMatch, HostFileRoot, ImageRefPart, JobEvent, JobInfo, JobProgress, JobResult, JobStatus, JobUsage, ListHostDirResponse, ListHostRootsResponse, ListJobsResponse, ListProfilesResponse, ListSdkSessionsResponse, ListSessionFilesResponse, ListSessionsResponse, McpServerActionRequest, McpServerConfigWire, McpServerStatusInfo, McpServerToolInfo, McpServersResponse, MessageAttachment, MessageOrigin, ModelOption, ModelRate, PEER_SEND_TOOLS, PRICING_AS_OF, PRICING_NOTE, PRICING_SOURCES, PRICING_STALE_DAYS, PROTOCOL_VERSION, PatchHunk, PermissionDecisionSource, PermissionMode, PermissionRequest, PricingMerge, PricingOverrides, PricingTable, ProfileConfigSnapshot, ProfileDefaults, ProfileEngine, ProfileInfo, ProfileSessionDefaults, ProfileSpend, ProfileUsage, ProfileUsageWindow, ProjectIcon, ProjectInfo, ProviderConfig, QuestionBehavior, QueueServerFrame, QueueStats, QueueStatsResponse, RateLimitInfo, ReadHostFileResponse, ResolvePermissionRequest, ResolvePermissionResponse, SHELL_COMMAND_MAX, STATE_LABELS, STATE_ORDER, SUBAGENT_HISTORY, SaveProfileResponse, ScopeRoot, SdkSessionSummary, ServerFrame, SessionCapability, SessionCommand, SessionEvent, SessionEventBody, SessionFileInfo, SessionGroup, SessionInfo, SessionNotification, SessionNotificationType, SessionRow, SessionState, SessionStatus, SessionTask, SessionTaskSource, SessionTaskState, SessionUsage, SessionWebhookConfig, SkillInfo, SlashCommandInfo, SortBy, SubagentInfo, SubmitExecutionResultRequest, SubmitExecutionResultResponse, SubscriptionComparison, SubsetSummary, TOOL_RESULT_HEAD_CHARS, TOOL_TITLE_MAX_CHARS, TaskSummary, TextBlock, ThinkingBlock, TokenUsage, ToolCallRequestFrame, ToolExecutionBackend, ToolExecutionOutput, ToolExecutionStatus, ToolResultBlock, ToolUseBlock, UNPRICED_WARN_SHARE, USAGE_STALE_AFTER_MS, UnknownBlock, UpdateProfileRequest, UpdateSessionRequest, UpdateSessionResponse, UploadAttachmentResponse, UsageWindowRow, UserQuestion, UserQuestionOption, ViewConfig, Watermark, WatermarkStore, Watermarks, WebhookConfig, WorkspaceScope, WriteHostFileRequest, WriteHostFileResponse, activePricing, adaptersOf, addTokenUsage, byModelTotalTokens, canonicalModel, clearFilters, contextReading, costOf, costOfByModel, emptyTokenUsage, filterRows, groupRows, hasFacetFilter, imagePartRef, inScope, isAgentRecord, isJobRun, isPeerSendTool, mergeByModel, mergePricing, mergeUsage, meteredCost, orderUsageWindows, parseTodoWriteInput, parseUserQuestions, peerDeliveredPrefix, peerDeliveredTo, pricingAgeDays, pricingAgeNote, projectKey, projectLabel, projectName, projectSubpath, projectsOf, rateFor, replayCoalesceKey, replayRetains, runningSubagents, sanitizeToolTitle, scopeActive, sessionLabel, sessionState, sessionTasks, setPricingOverrides, snapshotRetains, subagentLabel, subscriptionComparison, subsetSummary, supportsPermissionMode, taskCountLabel, taskSummary, tokenUsageFromWire, toolTitle, totalTokens, transcriptActivity, transcriptContent, transcriptProse, unknownBasisModels, unpricedModels, unseenCount, usageInfos, usageIsStale, visibleTasks, watermarkKey, worseBasis };
1079
1116
  //# sourceMappingURL=index.d.mts.map
package/build/index.mjs CHANGED
@@ -58,6 +58,9 @@ function projectKey(row) {
58
58
  return `${row.hostId}:${normalizePath(row.info.project?.root ?? row.info.cwd)}`;
59
59
  }
60
60
  function projectLabel(row) {
61
+ return row.info.project?.shortcode || projectName(row);
62
+ }
63
+ function projectName(row) {
61
64
  const name = row.info.project?.name;
62
65
  if (name) return name;
63
66
  const dir = normalizePath(row.info.cwd);
@@ -77,7 +80,7 @@ function isJobRun(info) {
77
80
  }
78
81
  function matchesSearch(row, needle) {
79
82
  if (!needle) return true;
80
- return sessionLabel(row.info).toLowerCase().includes(needle) || row.info.cwd.toLowerCase().includes(needle) || (row.info.project?.name.toLowerCase().includes(needle) ?? false) || row.hostName.toLowerCase().includes(needle) || row.adapter.toLowerCase().includes(needle) || row.info.id.startsWith(needle);
83
+ return sessionLabel(row.info).toLowerCase().includes(needle) || row.info.cwd.toLowerCase().includes(needle) || (row.info.project?.name.toLowerCase().includes(needle) ?? false) || (row.info.project?.shortcode?.toLowerCase().includes(needle) ?? false) || row.hostName.toLowerCase().includes(needle) || row.adapter.toLowerCase().includes(needle) || row.info.id.startsWith(needle);
81
84
  }
82
85
  function normalizePath(path) {
83
86
  return path.replace(/\\/g, "/").replace(/\/+$/, "");
@@ -237,7 +240,21 @@ const PRICING_AS_OF = "2026-09-19";
237
240
  const PRICING_SOURCES = "platform.claude.com and developers.openai.com list prices, bundled";
238
241
  const PRICING_NOTE = `List rates as of ${PRICING_AS_OF}. A subscription is a flat fee, so this is what the same tokens would have cost on the pay-as-you-go API, not a bill.`;
239
242
  const UNPRICED_WARN_SHARE = .005;
243
+ const PRICING_STALE_DAYS = 90;
240
244
  const MTOK = 1e6;
245
+ const DAY_MS = 864e5;
246
+ const BASIS_ORDER = {
247
+ list: 0,
248
+ managed: 1,
249
+ unknown: 2
250
+ };
251
+ const RATE_FIELDS = [
252
+ "input",
253
+ "output",
254
+ "cacheWrite5m",
255
+ "cacheWrite1h",
256
+ "cacheRead"
257
+ ];
241
258
  const WEEKS_PER_MONTH = 52 / 12;
242
259
  function anthropicRate(input, output, cacheRead) {
243
260
  return {
@@ -281,11 +298,67 @@ const DEFAULT_PRICING = {
281
298
  "gpt-5.1": openaiRate(1.25, 10, .125),
282
299
  "gpt-5": openaiRate(1.25, 10, .125)
283
300
  };
301
+ let activeTable = DEFAULT_PRICING;
302
+ function rateFromInput(value) {
303
+ if (value === null || typeof value !== "object") return;
304
+ const raw = value;
305
+ const rate = {
306
+ input: 0,
307
+ output: 0,
308
+ cacheWrite5m: 0,
309
+ cacheWrite1h: 0,
310
+ cacheRead: 0
311
+ };
312
+ for (const field of RATE_FIELDS) {
313
+ const rest = raw[field];
314
+ if (typeof rest !== "number" || !Number.isFinite(rest) || rest < 0) return;
315
+ rate[field] = rest;
316
+ }
317
+ return rate;
318
+ }
319
+ function mergePricing(overrides, base = DEFAULT_PRICING) {
320
+ const accepted = {};
321
+ const dropped = [];
322
+ if (overrides !== null && typeof overrides === "object") for (const [model, value] of Object.entries(overrides)) {
323
+ const rate = rateFromInput(value);
324
+ const key = canonicalModel(model);
325
+ if (!rate || key === "") {
326
+ dropped.push(model);
327
+ continue;
328
+ }
329
+ accepted[key] = rate;
330
+ }
331
+ return {
332
+ pricing: {
333
+ ...base,
334
+ ...accepted
335
+ },
336
+ overrides: accepted,
337
+ dropped
338
+ };
339
+ }
340
+ function activePricing() {
341
+ return activeTable;
342
+ }
343
+ function setPricingOverrides(overrides) {
344
+ const merged = mergePricing(overrides);
345
+ activeTable = merged.pricing;
346
+ return merged;
347
+ }
348
+ function pricingAgeDays(now, asOf = PRICING_AS_OF) {
349
+ const dated = Date.parse(asOf);
350
+ return Number.isFinite(dated) ? Math.floor((now - dated) / DAY_MS) : 0;
351
+ }
352
+ function pricingAgeNote(now, asOf = PRICING_AS_OF) {
353
+ const days = pricingAgeDays(now, asOf);
354
+ if (days <= 90) return;
355
+ return `This rate table is ${days} days old, so check the vendor's current list prices before you trust the total.`;
356
+ }
284
357
  function canonicalModel(model) {
285
358
  const slash = model.lastIndexOf("/");
286
359
  return (slash === -1 ? model : model.slice(slash + 1)).toLowerCase().replace(/\[[^\]]*\]$/, "").replace(/^(?:[a-z]+\.)*anthropic\./, "").replace(/[@-]\d{8}$/, "").replace(/-v\d+:\d+$/, "");
287
360
  }
288
- function rateFor(model, pricing = DEFAULT_PRICING) {
361
+ function rateFor(model, pricing = activePricing()) {
289
362
  return model ? pricing[canonicalModel(model)] : void 0;
290
363
  }
291
364
  function emptyTokenUsage() {
@@ -306,9 +379,18 @@ function addTokenUsage(into, add) {
306
379
  output: into.output + add.output,
307
380
  cacheWrite5m: into.cacheWrite5m + add.cacheWrite5m,
308
381
  cacheWrite1h: into.cacheWrite1h + add.cacheWrite1h,
309
- cacheRead: into.cacheRead + add.cacheRead
382
+ cacheRead: into.cacheRead + add.cacheRead,
383
+ costBasis: worseBasis(into.costBasis, add.costBasis)
310
384
  };
311
385
  }
386
+ function worseBasis(a, b) {
387
+ if (a === void 0) return b;
388
+ if (b === void 0) return a;
389
+ return BASIS_ORDER[a] >= BASIS_ORDER[b] ? a : b;
390
+ }
391
+ function unknownBasisModels(byModel) {
392
+ return Object.entries(byModel).filter(([, usage]) => usage.costBasis === "unknown").map(([model]) => canonicalModel(model));
393
+ }
312
394
  function mergeByModel(into, add) {
313
395
  const out = { ...into };
314
396
  for (const [model, usage] of Object.entries(add)) out[model] = addTokenUsage(out[model] ?? emptyTokenUsage(), usage);
@@ -348,7 +430,7 @@ function unpricedBreakdown(tokens) {
348
430
  unpricedShare: tokens > 0 ? 1 : 0
349
431
  };
350
432
  }
351
- function costOf(usage, model, pricing = DEFAULT_PRICING) {
433
+ function costOf(usage, model, pricing = activePricing()) {
352
434
  const rate = rateFor(model, pricing);
353
435
  if (!rate) return unpricedBreakdown(totalTokens(usage));
354
436
  const input = usage.input / MTOK * rate.input;
@@ -366,7 +448,7 @@ function costOf(usage, model, pricing = DEFAULT_PRICING) {
366
448
  unpricedShare: 0
367
449
  };
368
450
  }
369
- function costOfByModel(byModel, pricing = DEFAULT_PRICING) {
451
+ function costOfByModel(byModel, pricing = activePricing()) {
370
452
  const acc = {
371
453
  input: 0,
372
454
  output: 0,
@@ -398,7 +480,7 @@ function costOfByModel(byModel, pricing = DEFAULT_PRICING) {
398
480
  acc.unpricedShare = tokens > 0 ? acc.unpricedTokens / tokens : 0;
399
481
  return acc;
400
482
  }
401
- function unpricedModels(byModel, pricing = DEFAULT_PRICING) {
483
+ function unpricedModels(byModel, pricing = activePricing()) {
402
484
  return Object.keys(byModel).filter((model) => rateFor(model, pricing) === void 0);
403
485
  }
404
486
  function meteredCost(cost) {
@@ -430,7 +512,13 @@ const BUILTIN_TOOL_TITLES = {
430
512
  CodexFileChange: "Editing a file",
431
513
  CodexWebSearch: "Searching the web",
432
514
  CodexImageGeneration: "Generating an image",
433
- CodexImageView: "Viewing an image"
515
+ CodexImageView: "Viewing an image",
516
+ peers_list: "Listing peer sessions",
517
+ peers_peek: "Peeking at a peer session",
518
+ peers_send: "Messaging a peer session",
519
+ mcp__workerdeck__peers_list: "Listing peer sessions",
520
+ mcp__workerdeck__peers_peek: "Peeking at a peer session",
521
+ mcp__workerdeck__peers_send: "Messaging a peer session"
434
522
  };
435
523
  function toolTitle(name, titles) {
436
524
  return sanitizeToolTitle(titles?.[name] ?? BUILTIN_TOOL_TITLES[name], name);
@@ -442,6 +530,10 @@ function sanitizeToolTitle(title, name) {
442
530
  const points = [...flat];
443
531
  return points.length > 64 ? points.slice(0, 63).join("") + "…" : flat;
444
532
  }
533
+ const PEER_SEND_TOOLS = ["peers_send", "mcp__workerdeck__peers_send"];
534
+ function isPeerSendTool(name) {
535
+ return PEER_SEND_TOOLS.includes(name);
536
+ }
445
537
  //#endregion
446
538
  //#region src/usage.ts
447
539
  function mergeUsage(session, profile) {
@@ -673,6 +765,18 @@ function supportsPermissionMode(engine, mode) {
673
765
  }
674
766
  const SUBAGENT_HISTORY = 8;
675
767
  const CHECKLIST_TEXT_MAX = 200;
768
+ function peerDeliveredPrefix(sessionId, name) {
769
+ return `Delivered to ${name ? `${name} (${sessionId})` : sessionId}`;
770
+ }
771
+ function peerDeliveredTo(text) {
772
+ const named = /^Delivered to (.+) \(([^()]+)\);/.exec(text);
773
+ if (named) return {
774
+ sessionId: named[2],
775
+ name: named[1]
776
+ };
777
+ const bare = /^Delivered to ([^()\s]+);/.exec(text);
778
+ return bare ? { sessionId: bare[1] } : void 0;
779
+ }
676
780
  function contextReading(body) {
677
781
  if (body.type !== "context_usage") return;
678
782
  const { totalTokens, maxTokens, percentage } = body.usage;
@@ -700,6 +804,7 @@ function transcriptActivity(body) {
700
804
  function transcriptProse(body) {
701
805
  if ("parentToolUseId" in body && body.parentToolUseId != null) return 0;
702
806
  switch (body.type) {
807
+ case "user_message": return body.origin && !body.synthetic ? 1 : 0;
703
808
  case "assistant_message": {
704
809
  const content = body.message.content;
705
810
  if (typeof content === "string") return content.trim() === "" ? 0 : 1;
@@ -749,6 +854,6 @@ function snapshotRetains(body) {
749
854
  return body.type !== "stream_delta";
750
855
  }
751
856
  //#endregion
752
- export { BUILTIN_TOOL_TITLES, CHECKLIST_TEXT_MAX, DEFAULT_PRICING, DEFAULT_VIEW_CONFIG, ENGINE_CAPABILITIES, PRICING_AS_OF, PRICING_NOTE, PRICING_SOURCES, PROTOCOL_VERSION, SHELL_COMMAND_MAX, STATE_LABELS, STATE_ORDER, SUBAGENT_HISTORY, TOOL_RESULT_HEAD_CHARS, TOOL_TITLE_MAX_CHARS, UNPRICED_WARN_SHARE, USAGE_STALE_AFTER_MS, Watermarks, adaptersOf, addTokenUsage, byModelTotalTokens, canonicalModel, clearFilters, contextReading, costOf, costOfByModel, emptyTokenUsage, filterRows, groupRows, hasFacetFilter, imagePartRef, inScope, isAgentRecord, isJobRun, mergeByModel, mergeUsage, meteredCost, orderUsageWindows, parseTodoWriteInput, parseUserQuestions, projectKey, projectLabel, projectSubpath, projectsOf, rateFor, replayCoalesceKey, replayRetains, runningSubagents, sanitizeToolTitle, scopeActive, sessionLabel, sessionState, sessionTasks, snapshotRetains, subagentLabel, subscriptionComparison, subsetSummary, supportsPermissionMode, taskCountLabel, taskSummary, tokenUsageFromWire, toolTitle, totalTokens, transcriptActivity, transcriptContent, transcriptProse, unpricedModels, unseenCount, usageInfos, usageIsStale, visibleTasks, watermarkKey };
857
+ export { BUILTIN_TOOL_TITLES, CHECKLIST_TEXT_MAX, DEFAULT_PRICING, DEFAULT_VIEW_CONFIG, ENGINE_CAPABILITIES, PEER_SEND_TOOLS, PRICING_AS_OF, PRICING_NOTE, PRICING_SOURCES, PRICING_STALE_DAYS, PROTOCOL_VERSION, SHELL_COMMAND_MAX, STATE_LABELS, STATE_ORDER, SUBAGENT_HISTORY, TOOL_RESULT_HEAD_CHARS, TOOL_TITLE_MAX_CHARS, UNPRICED_WARN_SHARE, USAGE_STALE_AFTER_MS, Watermarks, activePricing, adaptersOf, addTokenUsage, byModelTotalTokens, canonicalModel, clearFilters, contextReading, costOf, costOfByModel, emptyTokenUsage, filterRows, groupRows, hasFacetFilter, imagePartRef, inScope, isAgentRecord, isJobRun, isPeerSendTool, mergeByModel, mergePricing, mergeUsage, meteredCost, orderUsageWindows, parseTodoWriteInput, parseUserQuestions, peerDeliveredPrefix, peerDeliveredTo, pricingAgeDays, pricingAgeNote, projectKey, projectLabel, projectName, projectSubpath, projectsOf, rateFor, replayCoalesceKey, replayRetains, runningSubagents, sanitizeToolTitle, scopeActive, sessionLabel, sessionState, sessionTasks, setPricingOverrides, snapshotRetains, subagentLabel, subscriptionComparison, subsetSummary, supportsPermissionMode, taskCountLabel, taskSummary, tokenUsageFromWire, toolTitle, totalTokens, transcriptActivity, transcriptContent, transcriptProse, unknownBasisModels, unpricedModels, unseenCount, usageInfos, usageIsStale, visibleTasks, watermarkKey, worseBasis };
753
858
 
754
859
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/session-list.ts","../src/checklist.ts","../src/pricing.ts","../src/tool-titles.ts","../src/usage.ts","../src/watermarks.ts","../src/index.ts"],"sourcesContent":["import type { SessionInfo, SubagentInfo } from './index.ts'\n\nexport type SessionState = 'attention' | 'working' | 'idle' | 'ended'\n\nexport const STATE_ORDER: readonly SessionState[] = ['attention', 'working', 'idle', 'ended']\n\nexport const STATE_LABELS: Record<SessionState, string> = {\n attention: 'Needs attention',\n working: 'Working',\n idle: 'Idle',\n ended: 'Ended',\n}\n\nexport function sessionState(info: SessionInfo): SessionState {\n if (info.pendingPermissionCount > 0 || info.status === 'awaiting_approval') {\n return 'attention'\n }\n if (info.status === 'failed' || info.status === 'closed') {\n return 'ended'\n }\n if (info.status === 'running' || info.status === 'starting') {\n return 'working'\n }\n if (runningSubagents(info).length > 0) {\n return 'working'\n }\n return 'idle'\n}\n\nexport function runningSubagents(info: SessionInfo): SubagentInfo[] {\n return (info.subagents ?? []).filter((sub) => sub.status === 'running')\n}\n\nexport function isAgentRecord(sub: SubagentInfo): boolean {\n return (sub.agentType?.trim() ?? '') !== ''\n}\n\nexport function subagentLabel(sub: SubagentInfo): string {\n const agent = sub.agentType?.trim()\n const description = sub.description?.trim()\n if (agent && description) {\n return `${agent} · ${description}`\n }\n return agent || description || 'Sub-agent'\n}\n\nexport type Facet = 'gateway' | 'adapter' | 'state' | 'project'\nexport type GroupBy = 'none' | Facet\nexport type SortBy = 'recent' | 'name' | Facet\n\nexport type ViewConfig = {\n search: string\n gateways: string[]\n adapters: string[]\n states: SessionState[]\n projects?: string[]\n scoped: boolean\n groupBy: GroupBy\n sortBy: SortBy\n}\n\nexport const DEFAULT_VIEW_CONFIG: ViewConfig = {\n search: '',\n gateways: [],\n adapters: [],\n states: [],\n projects: [],\n scoped: true,\n groupBy: 'state',\n sortBy: 'recent',\n}\n\nexport type ScopeRoot = { hostId?: string; path: string }\n\nexport type WorkspaceScope = { label: string; roots: ScopeRoot[] }\n\nexport type SessionRow = {\n hostId: string\n hostName: string\n local: boolean\n adapter: string\n state: SessionState\n info: SessionInfo\n // Messages this client has not read - `unseenCount` against its watermark, so the\n // unit is prose (`SessionInfo.proseCount`) wherever the gateway reports it. A session\n // that is only running tools contributes 0: the badge answers \"is there something to\n // read\", not \"is anything happening\", which is what `state` is for.\n unseen: number\n}\n\nexport type SessionGroup = { key: string; label?: string; rows: SessionRow[] }\n\nexport function adaptersOf(rows: readonly SessionRow[]): string[] {\n return [...new Set(rows.map((r) => r.adapter))].sort()\n}\n\nexport function projectsOf(rows: readonly SessionRow[]): { key: string; label: string }[] {\n const byKey = new Map<string, string>()\n for (const row of rows) {\n byKey.set(projectKey(row), projectLabel(row))\n }\n return [...byKey].map(([key, label]) => ({ key, label })).sort((a, b) => a.label.toLowerCase().localeCompare(b.label.toLowerCase()))\n}\n\nexport function sessionLabel(info: SessionInfo): string {\n return info.title ?? info.id.slice(0, 8)\n}\n\nexport function projectKey(row: SessionRow): string {\n return `${row.hostId}:${normalizePath(row.info.project?.root ?? row.info.cwd)}`\n}\n\nexport function projectLabel(row: Pick<SessionRow, 'info'>): string {\n const name = row.info.project?.name\n if (name) {\n return name\n }\n const dir = normalizePath(row.info.cwd)\n return dir.slice(dir.lastIndexOf('/') + 1) || 'No project'\n}\n\nexport function projectSubpath(row: Pick<SessionRow, 'info'>): string | undefined {\n const root = row.info.project?.root\n if (root === undefined || !row.info.cwd) {\n return undefined\n }\n const base = normalizePath(root)\n const dir = normalizePath(row.info.cwd)\n if (dir === base) {\n return undefined\n }\n if (!dir.startsWith(`${base}/`)) {\n return undefined\n }\n return dir.slice(base.length + 1) || undefined\n}\n\nexport function isJobRun(info: SessionInfo): boolean {\n return typeof info.meta?.jobId === 'string'\n}\n\nfunction matchesSearch(row: SessionRow, needle: string): boolean {\n if (!needle) {\n return true\n }\n return (\n sessionLabel(row.info).toLowerCase().includes(needle) ||\n row.info.cwd.toLowerCase().includes(needle) ||\n (row.info.project?.name.toLowerCase().includes(needle) ?? false) ||\n row.hostName.toLowerCase().includes(needle) ||\n row.adapter.toLowerCase().includes(needle) ||\n row.info.id.startsWith(needle)\n )\n}\n\nfunction normalizePath(path: string): string {\n return path.replace(/\\\\/g, '/').replace(/\\/+$/, '')\n}\n\nfunction isWithin(root: string, path: string): boolean {\n const base = normalizePath(root)\n const dir = normalizePath(path)\n // The separator matters: /a/project must not swallow /a/project-2.\n return dir === base || dir.startsWith(`${base}/`)\n}\n\nexport function inScope(row: SessionRow, scope: WorkspaceScope): boolean {\n return scope.roots.some(\n (root) => (root.hostId ? root.hostId.toLowerCase() === row.hostId.toLowerCase() : row.local) && isWithin(root.path, row.info.cwd),\n )\n}\n\nexport function scopeActive(config: ViewConfig, scope: WorkspaceScope | undefined): boolean {\n return config.scoped && scope !== undefined\n}\n\nexport function filterRows(rows: readonly SessionRow[], config: ViewConfig, scope?: WorkspaceScope): SessionRow[] {\n const needle = config.search.trim().toLowerCase()\n const scoping = scopeActive(config, scope) ? scope : undefined\n return rows.filter(\n (row) =>\n (config.gateways.length === 0 || config.gateways.includes(row.hostId)) &&\n (config.adapters.length === 0 || config.adapters.includes(row.adapter)) &&\n (config.states.length === 0 || config.states.includes(row.state)) &&\n (!config.projects?.length || config.projects.includes(projectKey(row))) &&\n (!scoping || inScope(row, scoping)) &&\n matchesSearch(row, needle),\n )\n}\n\nfunction facetKey(row: SessionRow, facet: Facet): string {\n return facet === 'gateway' ? row.hostId : facet === 'adapter' ? row.adapter : facet === 'project' ? projectKey(row) : row.state\n}\n\nfunction facetLabel(row: SessionRow, facet: Facet): string {\n return facet === 'gateway'\n ? row.hostName\n : facet === 'adapter'\n ? row.adapter\n : facet === 'project'\n ? projectLabel(row)\n : STATE_LABELS[row.state]\n}\n\nfunction facetRank(row: SessionRow, facet: Facet): string {\n if (facet === 'state') {\n return String(STATE_ORDER.indexOf(row.state))\n }\n return facetLabel(row, facet).toLowerCase()\n}\n\nfunction byRecency(a: SessionRow, b: SessionRow) {\n return (b.info.lastActivityAt ?? b.info.createdAt) - (a.info.lastActivityAt ?? a.info.createdAt)\n}\n\nfunction compare(a: SessionRow, b: SessionRow, sortBy: SortBy): number {\n if (sortBy === 'recent') {\n return byRecency(a, b)\n }\n if (sortBy === 'name') {\n return (\n sessionLabel(a.info).localeCompare(sessionLabel(b.info), undefined, {\n sensitivity: 'base',\n }) || byRecency(a, b)\n )\n }\n return facetRank(a, sortBy).localeCompare(facetRank(b, sortBy)) || byRecency(a, b)\n}\n\nexport function groupRows(rows: readonly SessionRow[], config: ViewConfig): SessionGroup[] {\n const sorted = [...rows].sort((a, b) => compare(a, b, config.sortBy))\n if (config.groupBy === 'none') {\n return sorted.length ? [{ key: 'all', rows: sorted }] : []\n }\n const facet = config.groupBy\n const groups = new Map<string, SessionGroup & { rank: string }>()\n for (const row of sorted) {\n const key = facetKey(row, facet)\n const group = groups.get(key)\n if (group) {\n group.rows.push(row)\n } else {\n groups.set(key, {\n key,\n label: facetLabel(row, facet),\n rank: facetRank(row, facet),\n rows: [row],\n })\n }\n }\n return [...groups.values()].sort((a, b) => a.rank.localeCompare(b.rank))\n}\n\nexport type SubsetSummary = { shown: number; total: number; causes: string[] }\n\nexport function subsetSummary(\n config: ViewConfig,\n scope: WorkspaceScope | undefined,\n shown: number,\n total: number,\n): SubsetSummary | undefined {\n if (shown >= total) {\n return undefined\n }\n const causes: string[] = []\n if (scope && scopeActive(config, scope)) {\n causes.push(scope.label)\n }\n const facets =\n (config.gateways.length ? 1 : 0) + (config.adapters.length ? 1 : 0) + (config.states.length ? 1 : 0) + (config.projects?.length ? 1 : 0)\n if (facets > 0) {\n causes.push(`${facets} filter${facets === 1 ? '' : 's'}`)\n }\n if (config.search.trim()) {\n causes.push('search')\n }\n return { shown, total, causes }\n}\n\nexport function hasFacetFilter(config: ViewConfig): boolean {\n return (\n config.search.trim().length > 0 ||\n config.gateways.length > 0 ||\n config.adapters.length > 0 ||\n config.states.length > 0 ||\n (config.projects?.length ?? 0) > 0\n )\n}\n\nexport function clearFilters(config: ViewConfig): ViewConfig {\n return {\n ...DEFAULT_VIEW_CONFIG,\n scoped: false,\n groupBy: config.groupBy,\n sortBy: config.sortBy,\n }\n}\n","import type { ChecklistItem, ChecklistStatus, SessionInfo } from './index.ts'\nimport { isAgentRecord } from './session-list.ts'\n\nexport type SessionTaskState = 'pending' | 'running' | 'done' | 'failed'\n\nexport type SessionTaskSource = 'checklist' | 'spawn'\n\nexport type SessionTask = {\n key: string\n label: string\n source: SessionTaskSource\n state: SessionTaskState\n detail?: string\n toolUseId?: string\n}\n\nexport type TaskSummary = { total: number; done: number; running: number; failed: number }\n\nfunction checklistEntry(value: unknown): ChecklistItem | undefined {\n if (typeof value !== 'object' || value === null) {\n return undefined\n }\n const raw = value as { content?: unknown; status?: unknown; activeForm?: unknown }\n const status = raw.status\n if (status !== 'pending' && status !== 'in_progress' && status !== 'completed') {\n return undefined\n }\n const content = typeof raw.content === 'string' ? raw.content.trim() : ''\n if (content === '') {\n return undefined\n }\n const active = typeof raw.activeForm === 'string' ? raw.activeForm.trim() : ''\n return { status, text: status === 'in_progress' && active !== '' ? active : content }\n}\n\n// Whole-or-nothing: a malformed entry (streaming, partial input) yields undefined rather than a half-read list.\n// A well-formed empty list is a clear, and answers `[]`.\nexport function parseTodoWriteInput(input: unknown): ChecklistItem[] | undefined {\n const todos = (input as { todos?: unknown } | null)?.todos\n if (!Array.isArray(todos)) {\n return undefined\n }\n const out: ChecklistItem[] = []\n for (const value of todos) {\n const entry = checklistEntry(value)\n if (entry === undefined) {\n return undefined\n }\n out.push(entry)\n }\n return out\n}\n\nfunction checklistState(status: ChecklistStatus): SessionTaskState {\n switch (status) {\n case 'in_progress': {\n return 'running'\n }\n case 'completed': {\n return 'done'\n }\n default: {\n return 'pending'\n }\n }\n}\n\nexport function sessionTasks(info: Pick<SessionInfo, 'checklist' | 'subagents'>): SessionTask[] {\n const checklist = (info.checklist ?? []).map((item, index) => ({\n key: `checklist:${index}`,\n label: item.text,\n source: 'checklist' as const,\n state: checklistState(item.status),\n }))\n const spawns = (info.subagents ?? [])\n .filter((sub) => !isAgentRecord(sub))\n .map((sub) => ({\n key: `spawn:${sub.toolUseId}`,\n label: sub.description?.trim() || 'Task',\n source: 'spawn' as const,\n state: sub.status,\n detail: sub.toolCount > 0 ? String(sub.toolCount) : undefined,\n toolUseId: sub.toolUseId,\n }))\n return [...checklist, ...spawns]\n}\n\nexport function taskSummary(tasks: readonly SessionTask[]): TaskSummary {\n let done = 0\n let running = 0\n let failed = 0\n for (const task of tasks) {\n if (task.state === 'done') {\n done += 1\n } else if (task.state === 'running') {\n running += 1\n } else if (task.state === 'failed') {\n failed += 1\n }\n }\n return { total: tasks.length, done, running, failed }\n}\n\nexport function taskCountLabel(summary: TaskSummary): string | undefined {\n return summary.total === 0 ? undefined : `${summary.done}/${summary.total}`\n}\n\nexport function visibleTasks(tasks: readonly SessionTask[], showCompleted: boolean): SessionTask[] {\n return showCompleted ? [...tasks] : tasks.filter((task) => task.state !== 'done')\n}\n","export type TokenUsage = {\n input: number\n output: number\n cacheWrite5m: number\n cacheWrite1h: number\n cacheRead: number\n}\n\nexport type ByModel = Record<string, TokenUsage>\n\nexport type ModelRate = {\n input: number\n output: number\n cacheWrite5m: number\n cacheWrite1h: number\n cacheRead: number\n}\n\nexport type CostBreakdown = {\n input: number\n output: number\n cacheWrite: number\n cacheRead: number\n total: number\n unpriced: boolean\n unpricedTokens: number\n unpricedShare: number\n}\n\nexport const PRICING_AS_OF = '2026-09-19'\n\nexport const PRICING_SOURCES = 'platform.claude.com and developers.openai.com list prices, bundled'\n\nexport const PRICING_NOTE = `List rates as of ${PRICING_AS_OF}. A subscription is a flat fee, so this is what the same tokens would have cost on the pay-as-you-go API, not a bill.`\n\nexport const UNPRICED_WARN_SHARE = 0.005\n\nconst MTOK = 1_000_000\n\nconst WEEKS_PER_MONTH = 52 / 12\n\nfunction anthropicRate(input: number, output: number, cacheRead?: number): ModelRate {\n return { input, output, cacheWrite5m: input * 1.25, cacheWrite1h: input * 2, cacheRead: cacheRead ?? input * 0.1 }\n}\n\nfunction openaiRate(input: number, output: number, cacheRead: number): ModelRate {\n return { input, output, cacheWrite5m: input, cacheWrite1h: input, cacheRead }\n}\n\nexport const DEFAULT_PRICING: Record<string, ModelRate> = {\n 'claude-fable-5-1': anthropicRate(10, 50, 0.25),\n 'claude-fable-5': anthropicRate(10, 50),\n 'claude-mythos-5-1': anthropicRate(10, 50, 0.25),\n 'claude-mythos-5': anthropicRate(10, 50),\n 'claude-opus-5': anthropicRate(5, 25),\n 'claude-opus-4-8': anthropicRate(5, 25),\n 'claude-opus-4-7': anthropicRate(5, 25),\n 'claude-opus-4-6': anthropicRate(5, 25),\n 'claude-opus-4-5': anthropicRate(5, 25),\n 'claude-sonnet-5': anthropicRate(2, 10),\n 'claude-sonnet-4-6': anthropicRate(3, 15),\n 'claude-sonnet-4-5': anthropicRate(3, 15),\n 'claude-haiku-4-5': anthropicRate(1, 5),\n 'gpt-6-astra': openaiRate(10, 50, 1),\n 'gpt-5.6-sol': openaiRate(4, 20, 0.4),\n 'gpt-5.6-terra': openaiRate(2, 12, 0.2),\n 'gpt-5.6-luna': openaiRate(0.2, 1.2, 0.02),\n 'gpt-5.5': openaiRate(5, 30, 0.5),\n 'gpt-5.4': openaiRate(2.5, 15, 0.25),\n 'gpt-5.2': openaiRate(1.75, 14, 0.175),\n 'gpt-5.1': openaiRate(1.25, 10, 0.125),\n 'gpt-5': openaiRate(1.25, 10, 0.125),\n}\n\nexport function canonicalModel(model: string): string {\n const slash = model.lastIndexOf('/')\n const withoutProvider = slash === -1 ? model : model.slice(slash + 1)\n return withoutProvider\n .toLowerCase()\n .replace(/\\[[^\\]]*\\]$/, '')\n .replace(/^(?:[a-z]+\\.)*anthropic\\./, '')\n .replace(/[@-]\\d{8}$/, '')\n .replace(/-v\\d+:\\d+$/, '')\n}\n\nexport function rateFor(model: string | undefined, pricing: Record<string, ModelRate> = DEFAULT_PRICING): ModelRate | undefined {\n return model ? pricing[canonicalModel(model)] : undefined\n}\n\nexport function emptyTokenUsage(): TokenUsage {\n return { input: 0, output: 0, cacheWrite5m: 0, cacheWrite1h: 0, cacheRead: 0 }\n}\n\nexport function totalTokens(usage: TokenUsage): number {\n return usage.input + usage.output + usage.cacheWrite5m + usage.cacheWrite1h + usage.cacheRead\n}\n\nexport function addTokenUsage(into: TokenUsage, add: TokenUsage): TokenUsage {\n return {\n input: into.input + add.input,\n output: into.output + add.output,\n cacheWrite5m: into.cacheWrite5m + add.cacheWrite5m,\n cacheWrite1h: into.cacheWrite1h + add.cacheWrite1h,\n cacheRead: into.cacheRead + add.cacheRead,\n }\n}\n\nexport function mergeByModel(into: ByModel, add: ByModel): ByModel {\n const out: ByModel = { ...into }\n for (const [model, usage] of Object.entries(add)) {\n out[model] = addTokenUsage(out[model] ?? emptyTokenUsage(), usage)\n }\n return out\n}\n\nexport function byModelTotalTokens(byModel: ByModel): number {\n let total = 0\n for (const usage of Object.values(byModel)) {\n total += totalTokens(usage)\n }\n return total\n}\n\nfunction num(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : 0\n}\n\nexport function tokenUsageFromWire(usage: unknown): TokenUsage {\n if (usage === null || typeof usage !== 'object') {\n return emptyTokenUsage()\n }\n const wire = usage as {\n input_tokens?: unknown\n output_tokens?: unknown\n cache_creation_input_tokens?: unknown\n cache_read_input_tokens?: unknown\n cache_creation?: { ephemeral_5m_input_tokens?: unknown; ephemeral_1h_input_tokens?: unknown } | null\n }\n const split = wire.cache_creation\n const write1h = num(split?.ephemeral_1h_input_tokens)\n const write5m = split ? num(split.ephemeral_5m_input_tokens) : num(wire.cache_creation_input_tokens)\n return {\n input: num(wire.input_tokens),\n output: num(wire.output_tokens),\n cacheWrite5m: write5m,\n cacheWrite1h: write1h,\n cacheRead: num(wire.cache_read_input_tokens),\n }\n}\n\nfunction unpricedBreakdown(tokens: number): CostBreakdown {\n return {\n input: 0,\n output: 0,\n cacheWrite: 0,\n cacheRead: 0,\n total: 0,\n unpriced: true,\n unpricedTokens: tokens,\n unpricedShare: tokens > 0 ? 1 : 0,\n }\n}\n\nexport function costOf(usage: TokenUsage, model: string | undefined, pricing: Record<string, ModelRate> = DEFAULT_PRICING): CostBreakdown {\n const rate = rateFor(model, pricing)\n if (!rate) {\n return unpricedBreakdown(totalTokens(usage))\n }\n const input = (usage.input / MTOK) * rate.input\n const output = (usage.output / MTOK) * rate.output\n const cacheWrite = (usage.cacheWrite5m / MTOK) * rate.cacheWrite5m + (usage.cacheWrite1h / MTOK) * rate.cacheWrite1h\n const cacheRead = (usage.cacheRead / MTOK) * rate.cacheRead\n return {\n input,\n output,\n cacheWrite,\n cacheRead,\n total: input + output + cacheWrite + cacheRead,\n unpriced: false,\n unpricedTokens: 0,\n unpricedShare: 0,\n }\n}\n\nexport function costOfByModel(byModel: ByModel, pricing: Record<string, ModelRate> = DEFAULT_PRICING): CostBreakdown {\n const acc: CostBreakdown = {\n input: 0,\n output: 0,\n cacheWrite: 0,\n cacheRead: 0,\n total: 0,\n unpriced: false,\n unpricedTokens: 0,\n unpricedShare: 0,\n }\n const models = Object.entries(byModel)\n let anyPriced = false\n let tokens = 0\n for (const [model, usage] of models) {\n tokens += totalTokens(usage)\n const cost = costOf(usage, model, pricing)\n if (cost.unpriced) {\n acc.unpricedTokens += cost.unpricedTokens\n continue\n }\n anyPriced = true\n acc.input += cost.input\n acc.output += cost.output\n acc.cacheWrite += cost.cacheWrite\n acc.cacheRead += cost.cacheRead\n acc.total += cost.total\n }\n acc.unpriced = !anyPriced && models.length > 0\n acc.unpricedShare = tokens > 0 ? acc.unpricedTokens / tokens : 0\n return acc\n}\n\nexport function unpricedModels(byModel: ByModel, pricing: Record<string, ModelRate> = DEFAULT_PRICING): string[] {\n return Object.keys(byModel).filter((model) => rateFor(model, pricing) === undefined)\n}\n\n// Rate limits meter fresh input, output and cache writes; a cache read is nearly free to serve and does not\n// count against a plan window, which is why quota burn and API-equivalent cost diverge on an agentic workload.\nexport function meteredCost(cost: CostBreakdown): number {\n return cost.input + cost.output + cost.cacheWrite\n}\n\nexport type SubscriptionComparison = {\n weeklyUsd: number\n monthlyUsd: number\n weeklyShareUsd: number\n ratio: number\n}\n\nexport function subscriptionComparison(weeklyUsd: number, monthlyUsd: number): SubscriptionComparison | undefined {\n if (!(monthlyUsd > 0) || !Number.isFinite(weeklyUsd) || weeklyUsd < 0) {\n return undefined\n }\n const weeklyShareUsd = monthlyUsd / WEEKS_PER_MONTH\n return { weeklyUsd, monthlyUsd, weeklyShareUsd, ratio: weeklyUsd / weeklyShareUsd }\n}\n\nexport type ProfileSpend = {\n weekUsd: number\n monthUsd: number\n weekByModel: ByModel\n unpricedShare: number\n monthlySubscriptionUsd?: number\n subscription?: SubscriptionComparison\n}\n","export const TOOL_TITLE_MAX_CHARS = 64\n\n// Capability tools the sandbox grants and the synthetic names the codex adapter invents: wire\n// names with no public vocabulary behind them. An engine's own tool names (`Bash`, `Read`,\n// `Task`) are deliberately absent - those are the CLI's published names and users read them.\nexport const BUILTIN_TOOL_TITLES: Record<string, string> = {\n fs_read: 'Reading a file',\n fs_write: 'Writing a file',\n fs_list: 'Listing files',\n eval_script: 'Running a script',\n web_fetch: 'Fetching a web page',\n web_search: 'Searching the web',\n deliver_file: 'Delivering a file',\n download: 'Downloading a file',\n CodexCommand: 'Running a command',\n CodexFileChange: 'Editing a file',\n CodexWebSearch: 'Searching the web',\n CodexImageGeneration: 'Generating an image',\n CodexImageView: 'Viewing an image',\n}\n\nexport function toolTitle(name: string, titles?: Record<string, string>): string | undefined {\n return sanitizeToolTitle(titles?.[name] ?? BUILTIN_TOOL_TITLES[name], name)\n}\n\n// Titles reach here from remote MCP servers, so they are untrusted display text: one line,\n// clamped, and never a restatement of the wire name the caller already has.\nexport function sanitizeToolTitle(title: string | undefined, name?: string): string | undefined {\n if (typeof title !== 'string') {\n return undefined\n }\n const flat = [...title]\n .map((char) => (char < ' ' || char === '\\u007f' ? ' ' : char))\n .join('')\n .replace(/\\s+/g, ' ')\n .trim()\n if (flat === '' || flat === name) {\n return undefined\n }\n // By code point, not code unit: a clamp that splits a surrogate pair renders a replacement\n // character, and the clients that mirror this rule do not count in UTF-16.\n const points = [...flat]\n return points.length > TOOL_TITLE_MAX_CHARS ? points.slice(0, TOOL_TITLE_MAX_CHARS - 1).join('') + '…' : flat\n}\n","import type { ProfileUsage, RateLimitInfo } from './index.ts'\n\nexport type SessionUsage = {\n rateLimits?: Record<string, RateLimitInfo>\n updatedAt?: number\n}\n\nexport function mergeUsage(session: SessionUsage, profile: ProfileUsage | undefined): ProfileUsage {\n const out: ProfileUsage = {}\n for (const [key, info] of Object.entries(session.rateLimits ?? {})) {\n out[key] = { info, updatedAt: session.updatedAt ?? 0 }\n }\n for (const [key, window] of Object.entries(profile ?? {})) {\n out[key] = window\n }\n return out\n}\n\n// A rate-limit reading is a poll, not a stream: the engine reports one at a turn boundary, on an attach and on a\n// profiles read, and nothing in between. A window older than this is still the best answer anyone has, and it is\n// no longer a claim about right now, so every surface marks it rather than drawing it as current. Minutes, not\n// hours: the windows move over hours, so a reading from this morning can be wrong by a lot.\nexport const USAGE_STALE_AFTER_MS = 15 * 60_000\n\nexport function usageIsStale(row: Pick<UsageWindowRow, 'updatedAt' | 'inferredReset'>, now: number): boolean {\n // An inferred reset is not stale, it is derived at serve time from the wall clock, and it says so in its own words.\n if (row.inferredReset || row.updatedAt === undefined) {\n return false\n }\n return now - row.updatedAt > USAGE_STALE_AFTER_MS\n}\n\nexport type UsageWindowRow = {\n key: string\n info: RateLimitInfo\n updatedAt?: number\n inferredReset?: boolean\n}\n\nexport function orderUsageWindows(usage: ProfileUsage | undefined): UsageWindowRow[] {\n const all = Object.entries(usage ?? {})\n .filter(([, w]) => w.info.utilization !== undefined)\n .map(([key, w]) => ({ key, info: w.info, updatedAt: w.updatedAt, inferredReset: w.inferredReset }))\n const named = ['five_hour', 'seven_day'].flatMap((key) => all.filter((w) => w.key === key))\n const perModel = all.filter((w) => w.key.startsWith('seven_day_')).sort((a, b) => a.key.localeCompare(b.key))\n return [...named, ...perModel]\n}\n\nexport function usageInfos(usage: ProfileUsage | undefined): Record<string, RateLimitInfo> | undefined {\n if (!usage) {\n return undefined\n }\n const out: Record<string, RateLimitInfo> = {}\n for (const [key, window] of Object.entries(usage)) {\n out[key] = window.info\n }\n return out\n}\n","export type Watermark = {\n itemCount: number\n activity: number\n // Prose rows read (`SessionInfo.proseCount`). Optional because a mark stored before\n // prose counting existed cannot say - see `unseenCount`, which reads that absence as\n // \"caught up\" rather than badging a whole history the operator has already seen.\n prose?: number\n turns: number\n seenAt: number\n}\n\nexport type WatermarkStore = {\n read(): Record<string, Watermark> | undefined\n write(marks: Record<string, Watermark>): void\n}\n\nconst MAX_AGE_MS = 30 * 24 * 60 * 60 * 1000\n\nconst TOUCH_MS = 60_000\n\nexport function watermarkKey(hostId: string, sessionId: string) {\n return `${hostId}:${sessionId}`\n}\n\nexport class Watermarks {\n readonly #store: WatermarkStore\n #cache: Record<string, Watermark>\n\n constructor(store: WatermarkStore) {\n this.#store = store\n this.#cache = { ...store.read() }\n }\n\n get(hostId: string, sessionId: string): Watermark | undefined {\n return this.#cache[watermarkKey(hostId, sessionId)]\n }\n\n all(): Readonly<Record<string, Watermark>> {\n return this.#cache\n }\n\n mark(\n hostId: string,\n sessionId: string,\n seen: { itemCount?: number; activity?: number; prose?: number; turns?: number },\n now = Date.now(),\n ): boolean {\n const id = watermarkKey(hostId, sessionId)\n const previous = this.#cache[id]\n const next: Watermark = {\n itemCount: Math.max(previous?.itemCount ?? 0, seen.itemCount ?? 0),\n activity: Math.max(previous?.activity ?? 0, seen.activity ?? 0),\n // A caller with nothing to say about prose (an older gateway reports no `proseCount`)\n // must not overwrite a real mark with 0, which would re-badge everything already read.\n prose: seen.prose === undefined ? previous?.prose : Math.max(previous?.prose ?? 0, seen.prose),\n turns: Math.max(previous?.turns ?? 0, seen.turns ?? 0),\n seenAt: now,\n }\n if (\n previous &&\n previous.itemCount === next.itemCount &&\n previous.activity === next.activity &&\n previous.prose === next.prose &&\n previous.turns === next.turns &&\n next.seenAt - previous.seenAt < TOUCH_MS\n ) {\n return false\n }\n this.#cache[id] = next\n this.#store.write(this.#prune(now))\n return true\n }\n\n forget(hostId: string, sessionId: string): void {\n const id = watermarkKey(hostId, sessionId)\n if (!(id in this.#cache)) {\n return\n }\n delete this.#cache[id]\n this.#store.write(this.#cache)\n }\n\n #prune(now: number): Record<string, Watermark> {\n const cutoff = now - MAX_AGE_MS\n for (const [id, mark] of Object.entries(this.#cache)) {\n if (mark.seenAt < cutoff) {\n delete this.#cache[id]\n }\n }\n return this.#cache\n }\n}\n\n// The badge's number, in the best unit the pair can agree on: prose the human has not\n// read, else rows, else turns. The ladder is what keeps an older gateway (no `proseCount`\n// on the wire) badging exactly as it did before rather than going silent.\nexport function unseenCount(mark: Watermark | undefined, info: { proseCount?: number; activityCount?: number; turns?: number }): number {\n if (!mark) {\n return 0\n }\n if (info.proseCount !== undefined) {\n // `mark.prose` absent = a mark written before prose counting. Reading it as\n // \"caught up\" costs one missed badge on a session already visited; reading it as 0\n // would badge every such session with its entire history the first time it polls.\n return Math.max(0, info.proseCount - (mark.prose ?? info.proseCount))\n }\n if (info.activityCount !== undefined) {\n return Math.max(0, info.activityCount - mark.activity)\n }\n return Math.max(0, (info.turns ?? 0) - mark.turns)\n}\n","import type { ByModel, ProfileSpend } from './pricing.ts'\n\nexport const PROTOCOL_VERSION = 1\n\nexport type SessionStatus = 'starting' | 'running' | 'awaiting_approval' | 'idle' | 'parked' | 'failed' | 'closed'\n\nexport type PermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan' | 'dontAsk' | 'auto'\n\nexport type TextBlock = { type: 'text'; text: string }\nexport type ThinkingBlock = { type: 'thinking'; thinking: string }\nexport type ToolUseBlock = { type: 'tool_use'; id: string; name: string; input: unknown }\nexport type ToolResultBlock = {\n type: 'tool_result'\n tool_use_id: string\n content?: string | Array<{ type: string; text?: string; [key: string]: unknown }>\n is_error?: boolean\n truncated?: boolean\n total_chars?: number\n}\n\nexport const TOOL_RESULT_HEAD_CHARS = 8_000\n\nexport type ImageRefPart = {\n type: 'image_ref'\n media_type: string\n bytes: number\n part_index: number\n}\n\nfunction base64Bytes(data: string): number {\n const padding = data.endsWith('==') ? 2 : data.endsWith('=') ? 1 : 0\n return Math.max(0, Math.floor((data.length * 3) / 4) - padding)\n}\n\nexport function imagePartRef(part: { type?: string; [key: string]: unknown }, index: number): ImageRefPart | undefined {\n if (part.type !== 'image') {\n return undefined\n }\n const source = part.source as { type?: string; data?: unknown; media_type?: unknown } | undefined\n if (!source || source.type !== 'base64' || typeof source.data !== 'string') {\n return undefined\n }\n return {\n type: 'image_ref',\n media_type: typeof source.media_type === 'string' ? source.media_type : 'application/octet-stream',\n bytes: base64Bytes(source.data),\n part_index: index,\n }\n}\n\nexport type UnknownBlock = { type: string; [key: string]: unknown }\n\nexport type PatchHunk = {\n oldStart: number\n oldLines: number\n newStart: number\n newLines: number\n lines: string[]\n}\n\nexport type FilePatch = {\n path?: string\n kind?: 'create' | 'update'\n hunks: PatchHunk[]\n truncated?: boolean\n}\n\nexport type ContentBlock = TextBlock | ThinkingBlock | ToolUseBlock | ToolResultBlock | UnknownBlock\n\nexport type MessageAttachment = {\n id: string\n name: string\n mediaType: string\n bytes: number\n}\n\nexport type ApiMessage = {\n role: 'user' | 'assistant'\n content: string | ContentBlock[]\n model?: string\n stop_reason?: string | null\n usage?: {\n input_tokens?: number\n output_tokens?: number\n cache_creation_input_tokens?: number\n cache_read_input_tokens?: number\n }\n}\n\nexport type PermissionRequest = {\n id: string\n toolName: string\n input: Record<string, unknown>\n toolUseId: string\n title?: string\n displayName?: string\n description?: string\n decisionReason?: string\n agentId?: string\n expiresAt?: number\n}\n\nexport type PermissionDecisionSource = 'client' | 'timeout' | 'policy'\n\nexport type UserQuestionOption = {\n label: string\n description?: string\n preview?: string\n}\n\nexport type UserQuestion = {\n question: string\n header: string\n options: UserQuestionOption[]\n multiSelect?: boolean\n}\n\nexport type QuestionBehavior = 'ask' | 'auto' | 'deny'\n\nexport function parseUserQuestions(input: Record<string, unknown>): UserQuestion[] {\n const raw = Array.isArray(input.questions) ? input.questions : []\n return raw.flatMap((entry): UserQuestion[] => {\n const q = entry as Partial<UserQuestion>\n if (typeof q.question !== 'string' || !Array.isArray(q.options)) {\n return []\n }\n const options = q.options.filter((o): o is UserQuestionOption => typeof (o as UserQuestionOption | undefined)?.label === 'string')\n if (options.length === 0) {\n return []\n }\n return [\n {\n question: q.question,\n header: typeof q.header === 'string' ? q.header : '',\n options,\n multiSelect: q.multiSelect === true,\n },\n ]\n })\n}\n\nexport type ModelOption = {\n value: string\n resolvedModel?: string\n displayName: string\n description?: string\n primary?: boolean\n reasoningEfforts?: readonly string[]\n}\n\nexport type SkillInfo = {\n name: string\n description?: string\n shortDescription?: string\n displayName?: string\n defaultPrompt?: string\n scope?: string\n enabled: boolean\n}\n\nexport type SlashCommandInfo = {\n name: string\n description?: string\n argumentHint?: string\n aliases?: string[]\n}\n\nexport type ContextUsageCategory = {\n name: string\n tokens: number\n color: string\n}\n\nexport type ContextUsage = {\n categories: ContextUsageCategory[]\n totalTokens: number\n maxTokens: number\n percentage: number\n model?: string\n}\n\nexport type ContextReading = {\n totalTokens: number\n maxTokens: number\n percentage: number\n}\n\nexport type RateLimitInfo = {\n status: string\n rateLimitType?: string\n utilization?: number\n resetsAt?: number\n isUsingOverage?: boolean\n}\n\nexport type ToolExecutionStatus = 'pending' | 'deferred' | 'settled' | 'failed'\n\nexport type ToolExecutionBackend = 'server' | 'browser' | 'managed' | 'remote'\n\nexport type ToolExecutionOutput = { type: 'text'; value: string } | { type: 'json'; value: unknown }\n\nexport type SessionEventBody =\n | {\n type: 'system_init'\n sdkSessionId: string\n model: string\n cwd: string\n apiKeySource: string\n tools: string[]\n skills: string[]\n slashCommands: string[]\n permissionMode: PermissionMode\n claudeCodeVersion: string\n mcpServers: Array<{ name: string; status: string }>\n }\n | { type: 'status_changed'; status: SessionStatus; detail?: string }\n | {\n type: 'capabilities'\n models: ModelOption[]\n commands: SlashCommandInfo[]\n defaultModel?: string\n }\n | { type: 'skills'; skills: SkillInfo[] }\n | { type: 'tool_titles'; titles: Record<string, string> }\n | { type: 'checklist'; items: ChecklistItem[] }\n | {\n type: 'file_produced'\n fileId: string\n path: string\n mediaType?: string\n bytes?: number\n toolUseId?: string\n }\n | { type: 'model_changed'; model?: string }\n | { type: 'permission_mode_changed'; mode: PermissionMode }\n | { type: 'context_usage'; usage: ContextUsage }\n | { type: 'rate_limit'; info: RateLimitInfo }\n | { type: 'plan_info'; subscriptionType: string }\n | {\n type: 'conversation_reset'\n sdkSessionId?: string\n }\n | {\n type: 'context_compacted'\n uuid: string\n parentToolUseId?: string | null\n // The same `uuid` is emitted twice: once with `pending` when the engine starts summarising,\n // once without it when the boundary lands, so one row settles in place. A reader that\n // never sees the first (an older gateway, a replay coalesced to the last) draws the\n // boundary alone, which is what it drew before.\n pending?: boolean\n trigger?: 'manual' | 'auto'\n preTokens?: number\n postTokens?: number\n error?: string\n }\n | {\n type: 'assistant_message'\n message: ApiMessage\n parentToolUseId: string | null\n replay?: boolean\n uuid: string\n }\n | {\n type: 'user_message'\n message: ApiMessage\n parentToolUseId: string | null\n replay?: boolean\n synthetic?: boolean\n attachments?: MessageAttachment[]\n patch?: FilePatch\n uuid?: string\n }\n | {\n type: 'stream_delta'\n event: { type: string; [key: string]: unknown }\n parentToolUseId: string | null\n uuid: string\n }\n | {\n type: 'turn_result'\n subtype: 'success' | 'error_during_execution' | 'error_max_turns' | 'error_max_budget_usd' | 'error_max_structured_output_retries'\n isError: boolean\n durationMs: number\n numTurns: number\n totalCostUsd: number\n result?: string\n errors?: string[]\n usage?: unknown\n usageByModel?: ByModel\n costUsd?: number\n }\n | { type: 'permission_requested'; request: PermissionRequest }\n | {\n type: 'permission_resolved'\n requestId: string\n behavior: 'allow' | 'deny'\n resolvedBy: PermissionDecisionSource\n message?: string\n }\n | {\n type: 'execution_dispatched'\n executionId: string\n toolName: string\n backend: ToolExecutionBackend\n deferred?: boolean\n expiresAt?: number\n }\n | {\n type: 'execution_result'\n executionId: string\n output: ToolExecutionOutput\n logs?: string[]\n durationMs?: number\n }\n | {\n type: 'execution_failed'\n executionId: string\n reason: string\n error: string\n logs?: string[]\n durationMs?: number\n }\n | { type: 'file_delivered'; path: string; bytes: number; description?: string }\n | { type: 'sdk_event'; payload: { type: string; [key: string]: unknown } }\n | { type: 'session_error'; message: string }\n | { type: 'session_closed'; reason: 'client' | 'server' | 'error' }\n\nexport type SessionEvent = SessionEventBody & {\n seq: number\n ts: number\n}\n\nexport type SessionCommand =\n | {\n type: 'user_message'\n text: string\n attachmentIds?: string[]\n }\n | {\n type: 'permission_decision'\n requestId: string\n behavior: 'allow' | 'deny'\n updatedInput?: Record<string, unknown>\n message?: string\n interrupt?: boolean\n }\n | { type: 'interrupt' }\n | { type: 'clear_context' }\n | { type: 'set_permission_mode'; mode: PermissionMode }\n | { type: 'set_model'; model?: string }\n | {\n type: 'tool_call_result'\n executionId: string\n output: ToolExecutionOutput\n logs?: string[]\n }\n | {\n type: 'tool_call_error'\n executionId: string\n reason: string\n error: string\n logs?: string[]\n }\n | { type: 'shell_command'; command: string }\n | { type: 'close' }\n\nexport const SHELL_COMMAND_MAX = 4000\n\nexport type AttachedFrame = {\n type: 'attached'\n protocolVersion: number\n session: SessionInfo\n replayingFrom: number\n // Whether this principal may run `!` commands on this session: server config x operator x hostCwd.\n // Additive, so no PROTOCOL_VERSION bump; an older gateway omits it and the client never offers the mode.\n shell?: boolean\n}\n\nexport type ToolCallRequestFrame = {\n type: 'tool_call_request'\n executionId: string\n toolName: string\n input: unknown\n vfsSeed?: Record<string, string>\n limits?: { timeoutMs?: number; memoryLimitBytes?: number }\n expiresAt?: number\n}\n\nexport type ServerFrame =\n | AttachedFrame\n | { type: 'event'; event: SessionEvent }\n | ToolCallRequestFrame\n | { type: 'tool_call_canceled'; executionId: string; reason: string }\n | { type: 'protocol_error'; message: string }\n\nexport type ClientFrame = SessionCommand\n\nexport type ProfileDefaults = {\n model?: string\n permissionMode?: PermissionMode\n}\n\nexport type ProfileEngine = 'claude' | 'codex' | 'provider'\n\nexport type EngineCapabilities = {\n interactiveApprovals: boolean\n permissionModes: readonly PermissionMode[]\n defaultPermissionMode: PermissionMode\n resume: boolean\n resumeBackfill: boolean\n listSessions: boolean\n contextUsage: boolean\n rateLimits: boolean\n mcpStatus: boolean\n mcpServerActions: boolean\n sessionMcpServers: boolean\n slashCommands: boolean\n clearContext?: boolean\n skillsList: boolean\n settingSources: boolean\n budgets: boolean\n attachments: ReadonlyArray<'image' | 'pdf' | 'text'>\n reasoningEfforts?: readonly string[]\n vfs: boolean\n hostCwd?: boolean\n streaming: 'token' | 'item' | 'none'\n}\n\nexport const ENGINE_CAPABILITIES: Record<ProfileEngine, EngineCapabilities> = {\n claude: {\n interactiveApprovals: true,\n permissionModes: ['default', 'acceptEdits', 'bypassPermissions', 'plan', 'dontAsk', 'auto'],\n defaultPermissionMode: 'default',\n resume: true,\n resumeBackfill: true,\n listSessions: true,\n contextUsage: true,\n rateLimits: true,\n mcpStatus: true,\n mcpServerActions: true,\n sessionMcpServers: true,\n slashCommands: true,\n clearContext: true,\n skillsList: false,\n settingSources: true,\n budgets: true,\n attachments: ['image', 'pdf', 'text'],\n reasoningEfforts: ['low', 'medium', 'high', 'xhigh', 'max'],\n vfs: false,\n hostCwd: true,\n streaming: 'token',\n },\n codex: {\n interactiveApprovals: true,\n permissionModes: ['default', 'acceptEdits', 'bypassPermissions', 'auto'],\n defaultPermissionMode: 'default',\n resume: true,\n resumeBackfill: true,\n listSessions: true,\n contextUsage: true,\n rateLimits: true,\n mcpStatus: true,\n mcpServerActions: false,\n sessionMcpServers: false,\n slashCommands: false,\n clearContext: true,\n skillsList: true,\n settingSources: false,\n budgets: false,\n attachments: ['image', 'text'],\n reasoningEfforts: ['minimal', 'low', 'medium', 'high', 'xhigh'],\n vfs: false,\n hostCwd: true,\n streaming: 'token',\n },\n provider: {\n interactiveApprovals: false,\n permissionModes: ['default', 'bypassPermissions', 'dontAsk'],\n defaultPermissionMode: 'default',\n resume: false,\n resumeBackfill: false,\n listSessions: false,\n contextUsage: false,\n rateLimits: false,\n mcpStatus: true,\n mcpServerActions: false,\n sessionMcpServers: false,\n slashCommands: false,\n clearContext: true,\n skillsList: false,\n settingSources: false,\n budgets: false,\n attachments: ['image', 'pdf', 'text'],\n vfs: true,\n hostCwd: false,\n streaming: 'token',\n },\n}\n\nexport function supportsPermissionMode(engine: ProfileEngine | undefined, mode: PermissionMode): boolean {\n return ENGINE_CAPABILITIES[engine ?? 'claude'].permissionModes.includes(mode)\n}\n\nexport type ProviderConfig = {\n id: string\n model?: string\n models?: string[]\n baseUrl?: string\n apiKeyEnv?: string\n}\n\nexport type SessionCapability = 'web_search' | 'download' | 'web_fetch' | 'deliver_file'\n\nexport type ProfileSessionDefaults = {\n capabilities?: SessionCapability[]\n mcpServers?: string[]\n instructions?: string\n}\n\nexport type ProfileUsageWindow = {\n info: RateLimitInfo\n updatedAt: number\n inferredReset?: boolean\n}\n\nexport type ProfileUsage = Record<string, ProfileUsageWindow>\n\nexport type ProfileInfo = {\n name: string\n engine?: ProfileEngine\n configDir?: string\n codexHome?: string\n provider?: ProviderConfig\n description?: string\n defaults?: ProfileDefaults\n session?: ProfileSessionDefaults\n models?: ModelOption[]\n defaultModel?: string\n capabilities?: EngineCapabilities\n available?: boolean\n unavailableReason?: string\n usage?: ProfileUsage\n spend?: ProfileSpend\n managed?: boolean\n}\n\nexport type ProfileConfigSnapshot = {\n settings?: {\n model?: string\n defaultPermissionMode?: string\n permissionRules?: { allow: number; ask: number; deny: number }\n envKeys?: string[]\n hooks?: string[]\n }\n hasUserMemory: boolean\n skills: string[]\n agents: string[]\n commands: string[]\n}\n\nexport type McpServerConfigWire =\n | { type?: 'stdio'; command: string; args?: string[]; env?: Record<string, string> }\n | { type: 'http'; url: string; headers?: Record<string, string> }\n | { type: 'sse'; url: string; headers?: Record<string, string> }\n\nexport type McpServerToolInfo = {\n name: string\n title?: string\n description?: string\n annotations?: { readOnly?: boolean; destructive?: boolean; openWorld?: boolean }\n inputSchema?: unknown\n}\n\nexport type McpServerStatusInfo = {\n name: string\n status: string\n scope?: string\n error?: string\n serverInfo?: { name: string; version: string }\n transport?: 'stdio' | 'http' | 'sse' | 'sdk'\n command?: string\n args?: string[]\n url?: string\n tools?: McpServerToolInfo[]\n}\n\nexport type McpServersResponse = { servers: McpServerStatusInfo[] }\n\nexport type McpServerActionRequest = { action: 'reconnect' | 'enable' | 'disable' }\n\nexport type UploadAttachmentResponse = { attachment: MessageAttachment }\n\nexport type CreateSessionRequest = {\n cwd?: string\n profile?: string\n prompt?: string\n permissionMode?: PermissionMode\n allowDangerouslySkipPermissions?: boolean\n allowedTools?: string[]\n disallowedTools?: string[]\n mcpServers?: Record<string, McpServerConfigWire>\n settingSources?: Array<'user' | 'project' | 'local'>\n model?: string\n maxTurns?: number\n maxBudgetUsd?: number\n resume?: string\n forkSession?: boolean\n reasoningEffort?: string\n includePartialMessages?: boolean\n // Overrides the gateway's default. null (or 0) means a prompt never expires - it waits as long as the session lives.\n approvalTimeoutMs?: number | null\n questionBehavior?: QuestionBehavior\n capabilities?: SessionCapability[]\n meta?: Record<string, unknown>\n scope?: Record<string, string>\n}\n\nexport type SubagentInfo = {\n toolUseId: string\n agentType?: string\n description?: string\n status: 'running' | 'done' | 'failed'\n startedAt: number\n toolCount: number\n}\n\nexport const SUBAGENT_HISTORY = 8\n\n// Widening this union costs a PROTOCOL_VERSION bump: Swift decodes it strictly.\nexport type ChecklistStatus = 'pending' | 'in_progress' | 'completed'\n\nexport type ChecklistItem = { text: string; status: ChecklistStatus }\n\nexport const CHECKLIST_TEXT_MAX = 200\n\nexport type ProjectIcon = { type: 'glyph'; name: string } | { type: 'image'; mediaType: 'image/png' | 'image/svg+xml'; hash: string }\n\nexport type ProjectInfo = {\n name: string\n root: string\n icon?: ProjectIcon\n}\n\nexport type SessionInfo = {\n id: string\n sdkSessionId?: string\n status: SessionStatus\n cwd: string\n profile?: string\n engine?: ProfileEngine\n capabilities?: EngineCapabilities\n model?: string\n permissionMode?: PermissionMode\n canBypassPermissions?: boolean\n apiKeySource?: string\n createdAt: number\n lastSeq: number\n // Which log the seqs belong to. A dormant wake starts a fresh log and bumps it, so a `seq`\n // that outlived one - a notification sitting on a lock screen - can be told from a live one.\n // Absent from a gateway that predates it, and from a session that has never woken; additive,\n // so no `PROTOCOL_VERSION` bump, and a reader that finds it absent on either side must keep\n // trusting the seq.\n epoch?: number\n pendingPermissionCount: number\n subagents?: SubagentInfo[]\n checklist?: ChecklistItem[]\n meta?: Record<string, unknown>\n title?: string\n totalCostUsd?: number\n costUsd?: number\n usageByModel?: ByModel\n numTurns?: number\n activityCount?: number\n // Rows of the kind a person is actually waiting to read - see `transcriptProse`.\n // Absent from a gateway that predates it - additive, so no `PROTOCOL_VERSION` bump -\n // which is why every reader falls back to `activityCount`. This is the badge's number; `activityCount` stays the \"has\n // anything happened at all\" measure that sorting and dormancy read.\n proseCount?: number\n lastActivityAt?: number\n contextUsage?: ContextReading\n scope?: Record<string, string>\n project?: ProjectInfo\n}\n\nexport function contextReading(body: SessionEventBody): ContextReading | undefined {\n if (body.type !== 'context_usage') {\n return undefined\n }\n const { totalTokens, maxTokens, percentage } = body.usage\n return { totalTokens, maxTokens, percentage }\n}\n\nexport function transcriptActivity(body: SessionEventBody): number {\n if ('parentToolUseId' in body && body.parentToolUseId != null) {\n return 0\n }\n switch (body.type) {\n case 'assistant_message': {\n const content = body.message.content\n if (typeof content === 'string') {\n return content.trim() === '' ? 0 : 1\n }\n const rows = content.filter((block) => block.type === 'text' || block.type === 'thinking' || block.type === 'tool_use').length\n return rows\n }\n case 'user_message': {\n return body.synthetic ? 0 : 1\n }\n case 'turn_result':\n case 'file_delivered':\n case 'session_error': {\n return 1\n }\n default: {\n return 0\n }\n }\n}\n\n// The narrower door beside transcriptActivity: output addressed to the human, not evidence of work.\n// `user_message` is deliberately absent: the human wrote it, so it can never be unread by them, and\n// counting it badged the sender's own prompt whenever they navigated away before the list next polled.\nexport function transcriptProse(body: SessionEventBody): number {\n if ('parentToolUseId' in body && body.parentToolUseId != null) {\n return 0\n }\n switch (body.type) {\n case 'assistant_message': {\n const content = body.message.content\n if (typeof content === 'string') {\n return content.trim() === '' ? 0 : 1\n }\n return content.filter((block) => block.type === 'text' && typeof block.text === 'string' && block.text.trim() !== '').length\n }\n case 'turn_result': {\n return body.isError ? 1 : 0\n }\n case 'file_delivered':\n case 'session_error': {\n return 1\n }\n default: {\n return 0\n }\n }\n}\n\nexport function transcriptContent(body: SessionEventBody): boolean {\n switch (body.type) {\n case 'user_message':\n case 'assistant_message':\n case 'stream_delta':\n case 'turn_result':\n case 'execution_dispatched':\n case 'execution_result':\n case 'execution_failed':\n case 'file_delivered':\n case 'session_error':\n case 'session_closed':\n case 'conversation_reset':\n case 'context_compacted': {\n return true\n }\n default: {\n return false\n }\n }\n}\n\nexport function replayCoalesceKey(body: SessionEventBody): string | undefined {\n switch (body.type) {\n case 'context_usage': {\n return 'context_usage'\n }\n case 'rate_limit': {\n return body.info.rateLimitType ? `rate_limit:${body.info.rateLimitType}` : undefined\n }\n case 'status_changed': {\n return 'status_changed'\n }\n case 'context_compacted': {\n return `context_compacted:${body.uuid}`\n }\n case 'checklist': {\n return 'checklist'\n }\n case 'sdk_event': {\n return body.payload.type === 'system' && body.payload.subtype === 'status' ? 'sdk_event:system:status' : undefined\n }\n default: {\n return undefined\n }\n }\n}\n\nexport function replayRetains(body: SessionEventBody): boolean {\n if (body.type !== 'stream_delta') {\n return true\n }\n const delta = body.event as { type?: string; delta?: { type?: string } }\n if (delta.type !== 'content_block_delta') {\n return false\n }\n return delta.delta?.type === 'text_delta' || delta.delta?.type === 'thinking_delta'\n}\n\nexport function snapshotRetains(body: SessionEventBody): boolean {\n return body.type !== 'stream_delta'\n}\n\nexport type SdkSessionSummary = {\n sessionId: string\n summary: string\n lastModified: number\n createdAt?: number\n customTitle?: string\n firstPrompt?: string\n gitBranch?: string\n cwd?: string\n}\n\nexport type SessionFileInfo = { path: string; bytes: number }\nexport type ListSessionFilesResponse = { files: SessionFileInfo[] }\nexport type ListSessionsResponse = { sessions: SessionInfo[] }\nexport type CreateSessionResponse = { session: SessionInfo }\nexport type GetSessionResponse = { session: SessionInfo }\n\nexport type UpdateSessionRequest = { title?: string | null }\nexport type UpdateSessionResponse = { session: SessionInfo }\n\nexport type ResolvePermissionRequest =\n | { behavior: 'allow'; updatedInput?: Record<string, unknown> }\n | { behavior: 'deny'; message?: string; interrupt?: boolean }\nexport type ResolvePermissionResponse = { resolved: true }\n\nexport type SubmitExecutionResultRequest =\n | { status: 'ok'; output: ToolExecutionOutput; logs?: string[] }\n | { status: 'failed'; reason: string; error: string; logs?: string[] }\nexport type SubmitExecutionResultResponse = {\n applied: boolean\n sessionId: string\n}\n\nexport type ListSdkSessionsResponse = { sdkSessions: SdkSessionSummary[] }\nexport type ListProfilesResponse = {\n profiles: ProfileInfo[]\n canManage?: boolean\n}\n\nexport type CreateProfileRequest = ProfileInfo\n\nexport type UpdateProfileRequest = Omit<Partial<ProfileInfo>, 'name'>\n\nexport type HostFileRoot = {\n path: string\n name: string\n}\n\nexport type ListHostRootsResponse = {\n roots: HostFileRoot[]\n canWrite: boolean\n}\n\nexport type HostDirEntry = {\n name: string\n path: string\n type: 'file' | 'dir' | 'symlink' | 'other'\n bytes?: number\n modifiedAt?: number\n}\n\nexport type ListHostDirResponse = {\n path: string\n entries: HostDirEntry[]\n truncated?: boolean\n}\n\nexport type HostFileMatch = {\n path: string\n relative: string\n}\n\nexport type FindHostFilesResponse = {\n base: string\n matches: HostFileMatch[]\n truncated: boolean\n}\n\nexport type ReadHostFileResponse = {\n path: string\n content: string\n encoding: 'utf8' | 'base64'\n bytes: number\n hash: string\n modifiedAt: number\n}\n\nexport type WriteHostFileRequest = {\n path: string\n content: string\n encoding?: 'utf8' | 'base64'\n expectedHash?: string\n}\n\nexport type WriteHostFileResponse = {\n path: string\n bytes: number\n hash: string\n modifiedAt: number\n}\n\nexport type SaveProfileResponse = { profile: ProfileInfo }\nexport type GetProfileResponse = { profile: ProfileInfo; config: ProfileConfigSnapshot }\nexport type ErrorResponse = { error: string }\n\nexport type SessionNotificationType = 'permission_requested' | 'turn_completed' | 'session_error' | 'session_closed'\n\nexport type SessionNotification = {\n type: SessionNotificationType\n sessionId: string\n session: SessionInfo\n seq: number\n ts: number\n preview?: string\n request?: PermissionRequest\n result?: { isError: boolean; durationMs: number; numTurns: number; totalCostUsd: number }\n reason?: 'client' | 'server' | 'error'\n}\n\nexport type SessionWebhookConfig = {\n url: string\n headers?: Record<string, string>\n events?: SessionNotificationType[]\n}\n\nexport type JobStatus = 'queued' | 'running' | 'parked' | 'succeeded' | 'failed' | 'canceled'\n\nexport type WebhookConfig = {\n url: string\n headers?: Record<string, string>\n progress?: 'messages' | 'completion'\n}\n\nexport type CreateJobRequest = {\n session: CreateSessionRequest & { prompt: string }\n webhook?: WebhookConfig\n maxTokens?: number\n maxDurationMs?: number\n attempts?: number\n retryDelayMs?: number\n meta?: Record<string, unknown>\n}\n\nexport type JobUsage = {\n tokens: number\n totalCostUsd: number\n numTurns: number\n}\n\nexport type JobResult = {\n subtype: string\n isError: boolean\n result?: string\n errors?: string[]\n durationMs: number\n}\n\nexport type JobInfo = {\n id: string\n status: JobStatus\n cwd: string\n profile?: string\n prompt: string\n sessionId?: string\n sdkSessionId?: string\n createdAt: number\n startedAt?: number\n finishedAt?: number\n attempt?: number\n maxAttempts?: number\n nextRunAt?: number\n parkedAt?: number\n parkedExecutionId?: string\n usage: JobUsage\n result?: JobResult\n error?: string\n meta?: Record<string, unknown>\n scope?: Record<string, string>\n}\n\nexport type JobProgress = {\n kind: 'assistant_text' | 'tool_use' | 'permission_requested' | 'permission_resolved'\n preview?: string\n request?: PermissionRequest\n}\n\nexport type JobEvent =\n | { type: 'job_submitted'; job: JobInfo; ts: number }\n | { type: 'job_started'; job: JobInfo; ts: number }\n | { type: 'job_progress'; job: JobInfo; progress: JobProgress; ts: number }\n | { type: 'job_parked'; job: JobInfo; executionId: string; ts: number }\n | { type: 'job_resumed'; job: JobInfo; executionId: string; ts: number }\n | { type: 'job_retrying'; job: JobInfo; ts: number }\n | { type: 'job_completed'; job: JobInfo; ts: number }\n\nexport type QueueStats = {\n maxConcurrency: number\n running: number\n queued: number\n parked: number\n sessionTokenLimit?: number\n dailyTokenLimit?: number\n dailyTokensUsed: number\n paused: boolean\n}\n\nexport type QueueServerFrame =\n | { type: 'queue_attached'; protocolVersion: number; stats: QueueStats }\n | { type: 'job_event'; event: JobEvent }\n | { type: 'queue_stats'; stats: QueueStats }\n\nexport type CreateJobResponse = { job: JobInfo }\nexport type GetJobResponse = { job: JobInfo }\nexport type ListJobsResponse = { jobs: JobInfo[] }\nexport type QueueStatsResponse = { stats: QueueStats }\n\nexport * from './checklist.ts'\nexport * from './pricing.ts'\nexport * from './session-list.ts'\nexport * from './tool-titles.ts'\nexport * from './usage.ts'\nexport * from './watermarks.ts'\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/session-list.ts","../src/checklist.ts","../src/pricing.ts","../src/tool-titles.ts","../src/usage.ts","../src/watermarks.ts","../src/index.ts"],"sourcesContent":["import type { SessionInfo, SubagentInfo } from './index.ts'\n\nexport type SessionState = 'attention' | 'working' | 'idle' | 'ended'\n\nexport const STATE_ORDER: readonly SessionState[] = ['attention', 'working', 'idle', 'ended']\n\nexport const STATE_LABELS: Record<SessionState, string> = {\n attention: 'Needs attention',\n working: 'Working',\n idle: 'Idle',\n ended: 'Ended',\n}\n\nexport function sessionState(info: SessionInfo): SessionState {\n if (info.pendingPermissionCount > 0 || info.status === 'awaiting_approval') {\n return 'attention'\n }\n if (info.status === 'failed' || info.status === 'closed') {\n return 'ended'\n }\n if (info.status === 'running' || info.status === 'starting') {\n return 'working'\n }\n if (runningSubagents(info).length > 0) {\n return 'working'\n }\n return 'idle'\n}\n\nexport function runningSubagents(info: SessionInfo): SubagentInfo[] {\n return (info.subagents ?? []).filter((sub) => sub.status === 'running')\n}\n\nexport function isAgentRecord(sub: SubagentInfo): boolean {\n return (sub.agentType?.trim() ?? '') !== ''\n}\n\nexport function subagentLabel(sub: SubagentInfo): string {\n const agent = sub.agentType?.trim()\n const description = sub.description?.trim()\n if (agent && description) {\n return `${agent} · ${description}`\n }\n return agent || description || 'Sub-agent'\n}\n\nexport type Facet = 'gateway' | 'adapter' | 'state' | 'project'\nexport type GroupBy = 'none' | Facet\nexport type SortBy = 'recent' | 'name' | Facet\n\nexport type ViewConfig = {\n search: string\n gateways: string[]\n adapters: string[]\n states: SessionState[]\n projects?: string[]\n scoped: boolean\n groupBy: GroupBy\n sortBy: SortBy\n}\n\nexport const DEFAULT_VIEW_CONFIG: ViewConfig = {\n search: '',\n gateways: [],\n adapters: [],\n states: [],\n projects: [],\n scoped: true,\n groupBy: 'state',\n sortBy: 'recent',\n}\n\nexport type ScopeRoot = { hostId?: string; path: string }\n\nexport type WorkspaceScope = { label: string; roots: ScopeRoot[] }\n\nexport type SessionRow = {\n hostId: string\n hostName: string\n local: boolean\n adapter: string\n state: SessionState\n info: SessionInfo\n // Messages this client has not read - `unseenCount` against its watermark, so the\n // unit is prose (`SessionInfo.proseCount`) wherever the gateway reports it. A session\n // that is only running tools contributes 0: the badge answers \"is there something to\n // read\", not \"is anything happening\", which is what `state` is for.\n unseen: number\n}\n\nexport type SessionGroup = { key: string; label?: string; rows: SessionRow[] }\n\nexport function adaptersOf(rows: readonly SessionRow[]): string[] {\n return [...new Set(rows.map((r) => r.adapter))].sort()\n}\n\nexport function projectsOf(rows: readonly SessionRow[]): { key: string; label: string }[] {\n const byKey = new Map<string, string>()\n for (const row of rows) {\n byKey.set(projectKey(row), projectLabel(row))\n }\n return [...byKey].map(([key, label]) => ({ key, label })).sort((a, b) => a.label.toLowerCase().localeCompare(b.label.toLowerCase()))\n}\n\nexport function sessionLabel(info: SessionInfo): string {\n return info.title ?? info.id.slice(0, 8)\n}\n\nexport function projectKey(row: SessionRow): string {\n return `${row.hostId}:${normalizePath(row.info.project?.root ?? row.info.cwd)}`\n}\n\nexport function projectLabel(row: Pick<SessionRow, 'info'>): string {\n return row.info.project?.shortcode || projectName(row)\n}\n\nexport function projectName(row: Pick<SessionRow, 'info'>): string {\n const name = row.info.project?.name\n if (name) {\n return name\n }\n const dir = normalizePath(row.info.cwd)\n return dir.slice(dir.lastIndexOf('/') + 1) || 'No project'\n}\n\nexport function projectSubpath(row: Pick<SessionRow, 'info'>): string | undefined {\n const root = row.info.project?.root\n if (root === undefined || !row.info.cwd) {\n return undefined\n }\n const base = normalizePath(root)\n const dir = normalizePath(row.info.cwd)\n if (dir === base) {\n return undefined\n }\n if (!dir.startsWith(`${base}/`)) {\n return undefined\n }\n return dir.slice(base.length + 1) || undefined\n}\n\nexport function isJobRun(info: SessionInfo): boolean {\n return typeof info.meta?.jobId === 'string'\n}\n\nfunction matchesSearch(row: SessionRow, needle: string): boolean {\n if (!needle) {\n return true\n }\n return (\n sessionLabel(row.info).toLowerCase().includes(needle) ||\n row.info.cwd.toLowerCase().includes(needle) ||\n (row.info.project?.name.toLowerCase().includes(needle) ?? false) ||\n (row.info.project?.shortcode?.toLowerCase().includes(needle) ?? false) ||\n row.hostName.toLowerCase().includes(needle) ||\n row.adapter.toLowerCase().includes(needle) ||\n row.info.id.startsWith(needle)\n )\n}\n\nfunction normalizePath(path: string): string {\n return path.replace(/\\\\/g, '/').replace(/\\/+$/, '')\n}\n\nfunction isWithin(root: string, path: string): boolean {\n const base = normalizePath(root)\n const dir = normalizePath(path)\n // The separator matters: /a/project must not swallow /a/project-2.\n return dir === base || dir.startsWith(`${base}/`)\n}\n\nexport function inScope(row: SessionRow, scope: WorkspaceScope): boolean {\n return scope.roots.some(\n (root) => (root.hostId ? root.hostId.toLowerCase() === row.hostId.toLowerCase() : row.local) && isWithin(root.path, row.info.cwd),\n )\n}\n\nexport function scopeActive(config: ViewConfig, scope: WorkspaceScope | undefined): boolean {\n return config.scoped && scope !== undefined\n}\n\nexport function filterRows(rows: readonly SessionRow[], config: ViewConfig, scope?: WorkspaceScope): SessionRow[] {\n const needle = config.search.trim().toLowerCase()\n const scoping = scopeActive(config, scope) ? scope : undefined\n return rows.filter(\n (row) =>\n (config.gateways.length === 0 || config.gateways.includes(row.hostId)) &&\n (config.adapters.length === 0 || config.adapters.includes(row.adapter)) &&\n (config.states.length === 0 || config.states.includes(row.state)) &&\n (!config.projects?.length || config.projects.includes(projectKey(row))) &&\n (!scoping || inScope(row, scoping)) &&\n matchesSearch(row, needle),\n )\n}\n\nfunction facetKey(row: SessionRow, facet: Facet): string {\n return facet === 'gateway' ? row.hostId : facet === 'adapter' ? row.adapter : facet === 'project' ? projectKey(row) : row.state\n}\n\nfunction facetLabel(row: SessionRow, facet: Facet): string {\n return facet === 'gateway'\n ? row.hostName\n : facet === 'adapter'\n ? row.adapter\n : facet === 'project'\n ? projectLabel(row)\n : STATE_LABELS[row.state]\n}\n\nfunction facetRank(row: SessionRow, facet: Facet): string {\n if (facet === 'state') {\n return String(STATE_ORDER.indexOf(row.state))\n }\n return facetLabel(row, facet).toLowerCase()\n}\n\nfunction byRecency(a: SessionRow, b: SessionRow) {\n return (b.info.lastActivityAt ?? b.info.createdAt) - (a.info.lastActivityAt ?? a.info.createdAt)\n}\n\nfunction compare(a: SessionRow, b: SessionRow, sortBy: SortBy): number {\n if (sortBy === 'recent') {\n return byRecency(a, b)\n }\n if (sortBy === 'name') {\n return (\n sessionLabel(a.info).localeCompare(sessionLabel(b.info), undefined, {\n sensitivity: 'base',\n }) || byRecency(a, b)\n )\n }\n return facetRank(a, sortBy).localeCompare(facetRank(b, sortBy)) || byRecency(a, b)\n}\n\nexport function groupRows(rows: readonly SessionRow[], config: ViewConfig): SessionGroup[] {\n const sorted = [...rows].sort((a, b) => compare(a, b, config.sortBy))\n if (config.groupBy === 'none') {\n return sorted.length ? [{ key: 'all', rows: sorted }] : []\n }\n const facet = config.groupBy\n const groups = new Map<string, SessionGroup & { rank: string }>()\n for (const row of sorted) {\n const key = facetKey(row, facet)\n const group = groups.get(key)\n if (group) {\n group.rows.push(row)\n } else {\n groups.set(key, {\n key,\n label: facetLabel(row, facet),\n rank: facetRank(row, facet),\n rows: [row],\n })\n }\n }\n return [...groups.values()].sort((a, b) => a.rank.localeCompare(b.rank))\n}\n\nexport type SubsetSummary = { shown: number; total: number; causes: string[] }\n\nexport function subsetSummary(\n config: ViewConfig,\n scope: WorkspaceScope | undefined,\n shown: number,\n total: number,\n): SubsetSummary | undefined {\n if (shown >= total) {\n return undefined\n }\n const causes: string[] = []\n if (scope && scopeActive(config, scope)) {\n causes.push(scope.label)\n }\n const facets =\n (config.gateways.length ? 1 : 0) + (config.adapters.length ? 1 : 0) + (config.states.length ? 1 : 0) + (config.projects?.length ? 1 : 0)\n if (facets > 0) {\n causes.push(`${facets} filter${facets === 1 ? '' : 's'}`)\n }\n if (config.search.trim()) {\n causes.push('search')\n }\n return { shown, total, causes }\n}\n\nexport function hasFacetFilter(config: ViewConfig): boolean {\n return (\n config.search.trim().length > 0 ||\n config.gateways.length > 0 ||\n config.adapters.length > 0 ||\n config.states.length > 0 ||\n (config.projects?.length ?? 0) > 0\n )\n}\n\nexport function clearFilters(config: ViewConfig): ViewConfig {\n return {\n ...DEFAULT_VIEW_CONFIG,\n scoped: false,\n groupBy: config.groupBy,\n sortBy: config.sortBy,\n }\n}\n","import type { ChecklistItem, ChecklistStatus, SessionInfo } from './index.ts'\nimport { isAgentRecord } from './session-list.ts'\n\nexport type SessionTaskState = 'pending' | 'running' | 'done' | 'failed'\n\nexport type SessionTaskSource = 'checklist' | 'spawn'\n\nexport type SessionTask = {\n key: string\n label: string\n source: SessionTaskSource\n state: SessionTaskState\n detail?: string\n toolUseId?: string\n}\n\nexport type TaskSummary = { total: number; done: number; running: number; failed: number }\n\nfunction checklistEntry(value: unknown): ChecklistItem | undefined {\n if (typeof value !== 'object' || value === null) {\n return undefined\n }\n const raw = value as { content?: unknown; status?: unknown; activeForm?: unknown }\n const status = raw.status\n if (status !== 'pending' && status !== 'in_progress' && status !== 'completed') {\n return undefined\n }\n const content = typeof raw.content === 'string' ? raw.content.trim() : ''\n if (content === '') {\n return undefined\n }\n const active = typeof raw.activeForm === 'string' ? raw.activeForm.trim() : ''\n return { status, text: status === 'in_progress' && active !== '' ? active : content }\n}\n\n// Whole-or-nothing: a malformed entry (streaming, partial input) yields undefined rather than a half-read list.\n// A well-formed empty list is a clear, and answers `[]`.\nexport function parseTodoWriteInput(input: unknown): ChecklistItem[] | undefined {\n const todos = (input as { todos?: unknown } | null)?.todos\n if (!Array.isArray(todos)) {\n return undefined\n }\n const out: ChecklistItem[] = []\n for (const value of todos) {\n const entry = checklistEntry(value)\n if (entry === undefined) {\n return undefined\n }\n out.push(entry)\n }\n return out\n}\n\nfunction checklistState(status: ChecklistStatus): SessionTaskState {\n switch (status) {\n case 'in_progress': {\n return 'running'\n }\n case 'completed': {\n return 'done'\n }\n default: {\n return 'pending'\n }\n }\n}\n\nexport function sessionTasks(info: Pick<SessionInfo, 'checklist' | 'subagents'>): SessionTask[] {\n const checklist = (info.checklist ?? []).map((item, index) => ({\n key: `checklist:${index}`,\n label: item.text,\n source: 'checklist' as const,\n state: checklistState(item.status),\n }))\n const spawns = (info.subagents ?? [])\n .filter((sub) => !isAgentRecord(sub))\n .map((sub) => ({\n key: `spawn:${sub.toolUseId}`,\n label: sub.description?.trim() || 'Task',\n source: 'spawn' as const,\n state: sub.status,\n detail: sub.toolCount > 0 ? String(sub.toolCount) : undefined,\n toolUseId: sub.toolUseId,\n }))\n return [...checklist, ...spawns]\n}\n\nexport function taskSummary(tasks: readonly SessionTask[]): TaskSummary {\n let done = 0\n let running = 0\n let failed = 0\n for (const task of tasks) {\n if (task.state === 'done') {\n done += 1\n } else if (task.state === 'running') {\n running += 1\n } else if (task.state === 'failed') {\n failed += 1\n }\n }\n return { total: tasks.length, done, running, failed }\n}\n\nexport function taskCountLabel(summary: TaskSummary): string | undefined {\n return summary.total === 0 ? undefined : `${summary.done}/${summary.total}`\n}\n\nexport function visibleTasks(tasks: readonly SessionTask[], showCompleted: boolean): SessionTask[] {\n return showCompleted ? [...tasks] : tasks.filter((task) => task.state !== 'done')\n}\n","export type CostBasis = 'list' | 'managed' | 'unknown'\n\nexport type TokenUsage = {\n input: number\n output: number\n cacheWrite5m: number\n cacheWrite1h: number\n cacheRead: number\n costBasis?: CostBasis\n}\n\nexport type ByModel = Record<string, TokenUsage>\n\nexport type ModelRate = {\n input: number\n output: number\n cacheWrite5m: number\n cacheWrite1h: number\n cacheRead: number\n}\n\nexport type CostBreakdown = {\n input: number\n output: number\n cacheWrite: number\n cacheRead: number\n total: number\n unpriced: boolean\n unpricedTokens: number\n unpricedShare: number\n}\n\nexport const PRICING_AS_OF = '2026-09-19'\n\nexport const PRICING_SOURCES = 'platform.claude.com and developers.openai.com list prices, bundled'\n\nexport const PRICING_NOTE = `List rates as of ${PRICING_AS_OF}. A subscription is a flat fee, so this is what the same tokens would have cost on the pay-as-you-go API, not a bill.`\n\nexport const UNPRICED_WARN_SHARE = 0.005\n\nexport const PRICING_STALE_DAYS = 90\n\nconst MTOK = 1_000_000\n\nconst DAY_MS = 86_400_000\n\nconst BASIS_ORDER: Record<CostBasis, number> = { list: 0, managed: 1, unknown: 2 }\n\nconst RATE_FIELDS = ['input', 'output', 'cacheWrite5m', 'cacheWrite1h', 'cacheRead'] as const\n\nconst WEEKS_PER_MONTH = 52 / 12\n\nfunction anthropicRate(input: number, output: number, cacheRead?: number): ModelRate {\n return { input, output, cacheWrite5m: input * 1.25, cacheWrite1h: input * 2, cacheRead: cacheRead ?? input * 0.1 }\n}\n\nfunction openaiRate(input: number, output: number, cacheRead: number): ModelRate {\n return { input, output, cacheWrite5m: input, cacheWrite1h: input, cacheRead }\n}\n\nexport const DEFAULT_PRICING: Record<string, ModelRate> = {\n 'claude-fable-5-1': anthropicRate(10, 50, 0.25),\n 'claude-fable-5': anthropicRate(10, 50),\n 'claude-mythos-5-1': anthropicRate(10, 50, 0.25),\n 'claude-mythos-5': anthropicRate(10, 50),\n 'claude-opus-5': anthropicRate(5, 25),\n 'claude-opus-4-8': anthropicRate(5, 25),\n 'claude-opus-4-7': anthropicRate(5, 25),\n 'claude-opus-4-6': anthropicRate(5, 25),\n 'claude-opus-4-5': anthropicRate(5, 25),\n 'claude-sonnet-5': anthropicRate(2, 10),\n 'claude-sonnet-4-6': anthropicRate(3, 15),\n 'claude-sonnet-4-5': anthropicRate(3, 15),\n 'claude-haiku-4-5': anthropicRate(1, 5),\n 'gpt-6-astra': openaiRate(10, 50, 1),\n 'gpt-5.6-sol': openaiRate(4, 20, 0.4),\n 'gpt-5.6-terra': openaiRate(2, 12, 0.2),\n 'gpt-5.6-luna': openaiRate(0.2, 1.2, 0.02),\n 'gpt-5.5': openaiRate(5, 30, 0.5),\n 'gpt-5.4': openaiRate(2.5, 15, 0.25),\n 'gpt-5.2': openaiRate(1.75, 14, 0.175),\n 'gpt-5.1': openaiRate(1.25, 10, 0.125),\n 'gpt-5': openaiRate(1.25, 10, 0.125),\n}\n\nexport type PricingTable = Record<string, ModelRate>\n\nexport type PricingOverrides = Record<string, ModelRate>\n\nexport type PricingMerge = {\n pricing: PricingTable\n overrides: PricingOverrides\n dropped: string[]\n}\n\nlet activeTable: PricingTable = DEFAULT_PRICING\n\nfunction rateFromInput(value: unknown): ModelRate | undefined {\n if (value === null || typeof value !== 'object') {\n return undefined\n }\n const raw = value as Record<string, unknown>\n const rate: ModelRate = { input: 0, output: 0, cacheWrite5m: 0, cacheWrite1h: 0, cacheRead: 0 }\n for (const field of RATE_FIELDS) {\n const rest = raw[field]\n if (typeof rest !== 'number' || !Number.isFinite(rest) || rest < 0) {\n return undefined\n }\n rate[field] = rest\n }\n return rate\n}\n\nexport function mergePricing(overrides: unknown, base: PricingTable = DEFAULT_PRICING): PricingMerge {\n const accepted: PricingOverrides = {}\n const dropped: string[] = []\n if (overrides !== null && typeof overrides === 'object') {\n for (const [model, value] of Object.entries(overrides as Record<string, unknown>)) {\n const rate = rateFromInput(value)\n const key = canonicalModel(model)\n if (!rate || key === '') {\n dropped.push(model)\n continue\n }\n accepted[key] = rate\n }\n }\n return { pricing: { ...base, ...accepted }, overrides: accepted, dropped }\n}\n\nexport function activePricing(): PricingTable {\n return activeTable\n}\n\n// The table is process-wide configuration, like the bundled rates it replaces entries in, so the gateway sets it\n// once at start and every pricing call that names no table of its own reads it.\nexport function setPricingOverrides(overrides: unknown): PricingMerge {\n const merged = mergePricing(overrides)\n activeTable = merged.pricing\n return merged\n}\n\nexport function pricingAgeDays(now: number, asOf: string = PRICING_AS_OF): number {\n const dated = Date.parse(asOf)\n return Number.isFinite(dated) ? Math.floor((now - dated) / DAY_MS) : 0\n}\n\nexport function pricingAgeNote(now: number, asOf: string = PRICING_AS_OF): string | undefined {\n const days = pricingAgeDays(now, asOf)\n if (days <= PRICING_STALE_DAYS) {\n return undefined\n }\n return `This rate table is ${days} days old, so check the vendor's current list prices before you trust the total.`\n}\n\nexport function canonicalModel(model: string): string {\n const slash = model.lastIndexOf('/')\n const withoutProvider = slash === -1 ? model : model.slice(slash + 1)\n return withoutProvider\n .toLowerCase()\n .replace(/\\[[^\\]]*\\]$/, '')\n .replace(/^(?:[a-z]+\\.)*anthropic\\./, '')\n .replace(/[@-]\\d{8}$/, '')\n .replace(/-v\\d+:\\d+$/, '')\n}\n\nexport function rateFor(model: string | undefined, pricing: PricingTable = activePricing()): ModelRate | undefined {\n return model ? pricing[canonicalModel(model)] : undefined\n}\n\nexport function emptyTokenUsage(): TokenUsage {\n return { input: 0, output: 0, cacheWrite5m: 0, cacheWrite1h: 0, cacheRead: 0 }\n}\n\nexport function totalTokens(usage: TokenUsage): number {\n return usage.input + usage.output + usage.cacheWrite5m + usage.cacheWrite1h + usage.cacheRead\n}\n\nexport function addTokenUsage(into: TokenUsage, add: TokenUsage): TokenUsage {\n return {\n input: into.input + add.input,\n output: into.output + add.output,\n cacheWrite5m: into.cacheWrite5m + add.cacheWrite5m,\n cacheWrite1h: into.cacheWrite1h + add.cacheWrite1h,\n cacheRead: into.cacheRead + add.cacheRead,\n costBasis: worseBasis(into.costBasis, add.costBasis),\n }\n}\n\n// A total priced on a basis the engine could not identify stays suspect however little of it there was,\n// so the worse basis wins rather than the newer one.\nexport function worseBasis(a: CostBasis | undefined, b: CostBasis | undefined): CostBasis | undefined {\n if (a === undefined) {\n return b\n }\n if (b === undefined) {\n return a\n }\n return BASIS_ORDER[a] >= BASIS_ORDER[b] ? a : b\n}\n\nexport function unknownBasisModels(byModel: ByModel): string[] {\n return Object.entries(byModel)\n .filter(([, usage]) => usage.costBasis === 'unknown')\n .map(([model]) => canonicalModel(model))\n}\n\nexport function mergeByModel(into: ByModel, add: ByModel): ByModel {\n const out: ByModel = { ...into }\n for (const [model, usage] of Object.entries(add)) {\n out[model] = addTokenUsage(out[model] ?? emptyTokenUsage(), usage)\n }\n return out\n}\n\nexport function byModelTotalTokens(byModel: ByModel): number {\n let total = 0\n for (const usage of Object.values(byModel)) {\n total += totalTokens(usage)\n }\n return total\n}\n\nfunction num(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : 0\n}\n\nexport function tokenUsageFromWire(usage: unknown): TokenUsage {\n if (usage === null || typeof usage !== 'object') {\n return emptyTokenUsage()\n }\n const wire = usage as {\n input_tokens?: unknown\n output_tokens?: unknown\n cache_creation_input_tokens?: unknown\n cache_read_input_tokens?: unknown\n cache_creation?: { ephemeral_5m_input_tokens?: unknown; ephemeral_1h_input_tokens?: unknown } | null\n }\n const split = wire.cache_creation\n const write1h = num(split?.ephemeral_1h_input_tokens)\n const write5m = split ? num(split.ephemeral_5m_input_tokens) : num(wire.cache_creation_input_tokens)\n return {\n input: num(wire.input_tokens),\n output: num(wire.output_tokens),\n cacheWrite5m: write5m,\n cacheWrite1h: write1h,\n cacheRead: num(wire.cache_read_input_tokens),\n }\n}\n\nfunction unpricedBreakdown(tokens: number): CostBreakdown {\n return {\n input: 0,\n output: 0,\n cacheWrite: 0,\n cacheRead: 0,\n total: 0,\n unpriced: true,\n unpricedTokens: tokens,\n unpricedShare: tokens > 0 ? 1 : 0,\n }\n}\n\nexport function costOf(usage: TokenUsage, model: string | undefined, pricing: PricingTable = activePricing()): CostBreakdown {\n const rate = rateFor(model, pricing)\n if (!rate) {\n return unpricedBreakdown(totalTokens(usage))\n }\n const input = (usage.input / MTOK) * rate.input\n const output = (usage.output / MTOK) * rate.output\n const cacheWrite = (usage.cacheWrite5m / MTOK) * rate.cacheWrite5m + (usage.cacheWrite1h / MTOK) * rate.cacheWrite1h\n const cacheRead = (usage.cacheRead / MTOK) * rate.cacheRead\n return {\n input,\n output,\n cacheWrite,\n cacheRead,\n total: input + output + cacheWrite + cacheRead,\n unpriced: false,\n unpricedTokens: 0,\n unpricedShare: 0,\n }\n}\n\nexport function costOfByModel(byModel: ByModel, pricing: PricingTable = activePricing()): CostBreakdown {\n const acc: CostBreakdown = {\n input: 0,\n output: 0,\n cacheWrite: 0,\n cacheRead: 0,\n total: 0,\n unpriced: false,\n unpricedTokens: 0,\n unpricedShare: 0,\n }\n const models = Object.entries(byModel)\n let anyPriced = false\n let tokens = 0\n for (const [model, usage] of models) {\n tokens += totalTokens(usage)\n const cost = costOf(usage, model, pricing)\n if (cost.unpriced) {\n acc.unpricedTokens += cost.unpricedTokens\n continue\n }\n anyPriced = true\n acc.input += cost.input\n acc.output += cost.output\n acc.cacheWrite += cost.cacheWrite\n acc.cacheRead += cost.cacheRead\n acc.total += cost.total\n }\n acc.unpriced = !anyPriced && models.length > 0\n acc.unpricedShare = tokens > 0 ? acc.unpricedTokens / tokens : 0\n return acc\n}\n\nexport function unpricedModels(byModel: ByModel, pricing: PricingTable = activePricing()): string[] {\n return Object.keys(byModel).filter((model) => rateFor(model, pricing) === undefined)\n}\n\n// Rate limits meter fresh input, output and cache writes; a cache read is nearly free to serve and does not\n// count against a plan window, which is why quota burn and API-equivalent cost diverge on an agentic workload.\nexport function meteredCost(cost: CostBreakdown): number {\n return cost.input + cost.output + cost.cacheWrite\n}\n\nexport type SubscriptionComparison = {\n weeklyUsd: number\n monthlyUsd: number\n weeklyShareUsd: number\n ratio: number\n}\n\nexport function subscriptionComparison(weeklyUsd: number, monthlyUsd: number): SubscriptionComparison | undefined {\n if (!(monthlyUsd > 0) || !Number.isFinite(weeklyUsd) || weeklyUsd < 0) {\n return undefined\n }\n const weeklyShareUsd = monthlyUsd / WEEKS_PER_MONTH\n return { weeklyUsd, monthlyUsd, weeklyShareUsd, ratio: weeklyUsd / weeklyShareUsd }\n}\n\nexport type ProfileSpend = {\n weekUsd: number\n monthUsd: number\n weekByModel: ByModel\n unpricedShare: number\n monthlySubscriptionUsd?: number\n subscription?: SubscriptionComparison\n}\n","export const TOOL_TITLE_MAX_CHARS = 64\n\n// Capability tools the sandbox grants and the synthetic names the codex adapter invents: wire\n// names with no public vocabulary behind them. An engine's own tool names (`Bash`, `Read`,\n// `Task`) are deliberately absent - those are the CLI's published names and users read them.\nexport const BUILTIN_TOOL_TITLES: Record<string, string> = {\n fs_read: 'Reading a file',\n fs_write: 'Writing a file',\n fs_list: 'Listing files',\n eval_script: 'Running a script',\n web_fetch: 'Fetching a web page',\n web_search: 'Searching the web',\n deliver_file: 'Delivering a file',\n download: 'Downloading a file',\n CodexCommand: 'Running a command',\n CodexFileChange: 'Editing a file',\n CodexWebSearch: 'Searching the web',\n CodexImageGeneration: 'Generating an image',\n CodexImageView: 'Viewing an image',\n peers_list: 'Listing peer sessions',\n peers_peek: 'Peeking at a peer session',\n peers_send: 'Messaging a peer session',\n mcp__workerdeck__peers_list: 'Listing peer sessions',\n mcp__workerdeck__peers_peek: 'Peeking at a peer session',\n mcp__workerdeck__peers_send: 'Messaging a peer session',\n}\n\nexport function toolTitle(name: string, titles?: Record<string, string>): string | undefined {\n return sanitizeToolTitle(titles?.[name] ?? BUILTIN_TOOL_TITLES[name], name)\n}\n\n// Titles reach here from remote MCP servers, so they are untrusted display text: one line,\n// clamped, and never a restatement of the wire name the caller already has.\nexport function sanitizeToolTitle(title: string | undefined, name?: string): string | undefined {\n if (typeof title !== 'string') {\n return undefined\n }\n const flat = [...title]\n .map((char) => (char < ' ' || char === '\\u007f' ? ' ' : char))\n .join('')\n .replace(/\\s+/g, ' ')\n .trim()\n if (flat === '' || flat === name) {\n return undefined\n }\n // By code point, not code unit: a clamp that splits a surrogate pair renders a replacement\n // character, and the clients that mirror this rule do not count in UTF-16.\n const points = [...flat]\n return points.length > TOOL_TITLE_MAX_CHARS ? points.slice(0, TOOL_TITLE_MAX_CHARS - 1).join('') + '…' : flat\n}\n\n// The peer tools both engines expose, under the bare name and the MCP-prefixed one. A client that\n// draws peer traffic as its own kind of row has to recognise the call by name, so the list lives\n// here rather than in any one client.\nexport const PEER_SEND_TOOLS = ['peers_send', 'mcp__workerdeck__peers_send'] as const\n\nexport function isPeerSendTool(name: string): boolean {\n return (PEER_SEND_TOOLS as readonly string[]).includes(name)\n}\n","import type { ProfileUsage, RateLimitInfo } from './index.ts'\n\nexport type SessionUsage = {\n rateLimits?: Record<string, RateLimitInfo>\n updatedAt?: number\n}\n\nexport function mergeUsage(session: SessionUsage, profile: ProfileUsage | undefined): ProfileUsage {\n const out: ProfileUsage = {}\n for (const [key, info] of Object.entries(session.rateLimits ?? {})) {\n out[key] = { info, updatedAt: session.updatedAt ?? 0 }\n }\n for (const [key, window] of Object.entries(profile ?? {})) {\n out[key] = window\n }\n return out\n}\n\n// A rate-limit reading is a poll, not a stream: the engine reports one at a turn boundary, on an attach and on a\n// profiles read, and nothing in between. A window older than this is still the best answer anyone has, and it is\n// no longer a claim about right now, so every surface marks it rather than drawing it as current. Minutes, not\n// hours: the windows move over hours, so a reading from this morning can be wrong by a lot.\nexport const USAGE_STALE_AFTER_MS = 15 * 60_000\n\nexport function usageIsStale(row: Pick<UsageWindowRow, 'updatedAt' | 'inferredReset'>, now: number): boolean {\n // An inferred reset is not stale, it is derived at serve time from the wall clock, and it says so in its own words.\n if (row.inferredReset || row.updatedAt === undefined) {\n return false\n }\n return now - row.updatedAt > USAGE_STALE_AFTER_MS\n}\n\nexport type UsageWindowRow = {\n key: string\n info: RateLimitInfo\n updatedAt?: number\n inferredReset?: boolean\n}\n\nexport function orderUsageWindows(usage: ProfileUsage | undefined): UsageWindowRow[] {\n const all = Object.entries(usage ?? {})\n .filter(([, w]) => w.info.utilization !== undefined)\n .map(([key, w]) => ({ key, info: w.info, updatedAt: w.updatedAt, inferredReset: w.inferredReset }))\n const named = ['five_hour', 'seven_day'].flatMap((key) => all.filter((w) => w.key === key))\n const perModel = all.filter((w) => w.key.startsWith('seven_day_')).sort((a, b) => a.key.localeCompare(b.key))\n return [...named, ...perModel]\n}\n\nexport function usageInfos(usage: ProfileUsage | undefined): Record<string, RateLimitInfo> | undefined {\n if (!usage) {\n return undefined\n }\n const out: Record<string, RateLimitInfo> = {}\n for (const [key, window] of Object.entries(usage)) {\n out[key] = window.info\n }\n return out\n}\n","export type Watermark = {\n itemCount: number\n activity: number\n // Prose rows read (`SessionInfo.proseCount`). Optional because a mark stored before\n // prose counting existed cannot say - see `unseenCount`, which reads that absence as\n // \"caught up\" rather than badging a whole history the operator has already seen.\n prose?: number\n turns: number\n seenAt: number\n}\n\nexport type WatermarkStore = {\n read(): Record<string, Watermark> | undefined\n write(marks: Record<string, Watermark>): void\n}\n\nconst MAX_AGE_MS = 30 * 24 * 60 * 60 * 1000\n\nconst TOUCH_MS = 60_000\n\nexport function watermarkKey(hostId: string, sessionId: string) {\n return `${hostId}:${sessionId}`\n}\n\nexport class Watermarks {\n readonly #store: WatermarkStore\n #cache: Record<string, Watermark>\n\n constructor(store: WatermarkStore) {\n this.#store = store\n this.#cache = { ...store.read() }\n }\n\n get(hostId: string, sessionId: string): Watermark | undefined {\n return this.#cache[watermarkKey(hostId, sessionId)]\n }\n\n all(): Readonly<Record<string, Watermark>> {\n return this.#cache\n }\n\n mark(\n hostId: string,\n sessionId: string,\n seen: { itemCount?: number; activity?: number; prose?: number; turns?: number },\n now = Date.now(),\n ): boolean {\n const id = watermarkKey(hostId, sessionId)\n const previous = this.#cache[id]\n const next: Watermark = {\n itemCount: Math.max(previous?.itemCount ?? 0, seen.itemCount ?? 0),\n activity: Math.max(previous?.activity ?? 0, seen.activity ?? 0),\n // A caller with nothing to say about prose (an older gateway reports no `proseCount`)\n // must not overwrite a real mark with 0, which would re-badge everything already read.\n prose: seen.prose === undefined ? previous?.prose : Math.max(previous?.prose ?? 0, seen.prose),\n turns: Math.max(previous?.turns ?? 0, seen.turns ?? 0),\n seenAt: now,\n }\n if (\n previous &&\n previous.itemCount === next.itemCount &&\n previous.activity === next.activity &&\n previous.prose === next.prose &&\n previous.turns === next.turns &&\n next.seenAt - previous.seenAt < TOUCH_MS\n ) {\n return false\n }\n this.#cache[id] = next\n this.#store.write(this.#prune(now))\n return true\n }\n\n forget(hostId: string, sessionId: string): void {\n const id = watermarkKey(hostId, sessionId)\n if (!(id in this.#cache)) {\n return\n }\n delete this.#cache[id]\n this.#store.write(this.#cache)\n }\n\n #prune(now: number): Record<string, Watermark> {\n const cutoff = now - MAX_AGE_MS\n for (const [id, mark] of Object.entries(this.#cache)) {\n if (mark.seenAt < cutoff) {\n delete this.#cache[id]\n }\n }\n return this.#cache\n }\n}\n\n// The badge's number, in the best unit the pair can agree on: prose the human has not\n// read, else rows, else turns. The ladder is what keeps an older gateway (no `proseCount`\n// on the wire) badging exactly as it did before rather than going silent.\nexport function unseenCount(mark: Watermark | undefined, info: { proseCount?: number; activityCount?: number; turns?: number }): number {\n if (!mark) {\n return 0\n }\n if (info.proseCount !== undefined) {\n // `mark.prose` absent = a mark written before prose counting. Reading it as\n // \"caught up\" costs one missed badge on a session already visited; reading it as 0\n // would badge every such session with its entire history the first time it polls.\n return Math.max(0, info.proseCount - (mark.prose ?? info.proseCount))\n }\n if (info.activityCount !== undefined) {\n return Math.max(0, info.activityCount - mark.activity)\n }\n return Math.max(0, (info.turns ?? 0) - mark.turns)\n}\n","import type { ByModel, PricingOverrides, ProfileSpend } from './pricing.ts'\n\nexport const PROTOCOL_VERSION = 1\n\nexport type SessionStatus = 'starting' | 'running' | 'awaiting_approval' | 'idle' | 'parked' | 'failed' | 'closed'\n\nexport type PermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan' | 'dontAsk' | 'auto'\n\nexport type TextBlock = { type: 'text'; text: string }\nexport type ThinkingBlock = { type: 'thinking'; thinking: string }\nexport type ToolUseBlock = { type: 'tool_use'; id: string; name: string; input: unknown }\nexport type ToolResultBlock = {\n type: 'tool_result'\n tool_use_id: string\n content?: string | Array<{ type: string; text?: string; [key: string]: unknown }>\n is_error?: boolean\n truncated?: boolean\n total_chars?: number\n}\n\nexport const TOOL_RESULT_HEAD_CHARS = 8_000\n\nexport type ImageRefPart = {\n type: 'image_ref'\n media_type: string\n bytes: number\n part_index: number\n}\n\nfunction base64Bytes(data: string): number {\n const padding = data.endsWith('==') ? 2 : data.endsWith('=') ? 1 : 0\n return Math.max(0, Math.floor((data.length * 3) / 4) - padding)\n}\n\nexport function imagePartRef(part: { type?: string; [key: string]: unknown }, index: number): ImageRefPart | undefined {\n if (part.type !== 'image') {\n return undefined\n }\n const source = part.source as { type?: string; data?: unknown; media_type?: unknown } | undefined\n if (!source || source.type !== 'base64' || typeof source.data !== 'string') {\n return undefined\n }\n return {\n type: 'image_ref',\n media_type: typeof source.media_type === 'string' ? source.media_type : 'application/octet-stream',\n bytes: base64Bytes(source.data),\n part_index: index,\n }\n}\n\nexport type UnknownBlock = { type: string; [key: string]: unknown }\n\nexport type PatchHunk = {\n oldStart: number\n oldLines: number\n newStart: number\n newLines: number\n lines: string[]\n}\n\nexport type FilePatch = {\n path?: string\n kind?: 'create' | 'update'\n hunks: PatchHunk[]\n truncated?: boolean\n}\n\nexport type ContentBlock = TextBlock | ThinkingBlock | ToolUseBlock | ToolResultBlock | UnknownBlock\n\nexport type MessageAttachment = {\n id: string\n name: string\n mediaType: string\n bytes: number\n}\n\nexport type ApiMessage = {\n role: 'user' | 'assistant'\n content: string | ContentBlock[]\n model?: string\n stop_reason?: string | null\n usage?: {\n input_tokens?: number\n output_tokens?: number\n cache_creation_input_tokens?: number\n cache_read_input_tokens?: number\n }\n}\n\nexport type PermissionRequest = {\n id: string\n toolName: string\n input: Record<string, unknown>\n toolUseId: string\n title?: string\n displayName?: string\n description?: string\n decisionReason?: string\n agentId?: string\n expiresAt?: number\n}\n\nexport type PermissionDecisionSource = 'client' | 'timeout' | 'policy'\n\nexport type UserQuestionOption = {\n label: string\n description?: string\n preview?: string\n}\n\nexport type UserQuestion = {\n question: string\n header: string\n options: UserQuestionOption[]\n multiSelect?: boolean\n}\n\nexport type QuestionBehavior = 'ask' | 'auto' | 'deny'\n\nexport function parseUserQuestions(input: Record<string, unknown>): UserQuestion[] {\n const raw = Array.isArray(input.questions) ? input.questions : []\n return raw.flatMap((entry): UserQuestion[] => {\n const q = entry as Partial<UserQuestion>\n if (typeof q.question !== 'string' || !Array.isArray(q.options)) {\n return []\n }\n const options = q.options.filter((o): o is UserQuestionOption => typeof (o as UserQuestionOption | undefined)?.label === 'string')\n if (options.length === 0) {\n return []\n }\n return [\n {\n question: q.question,\n header: typeof q.header === 'string' ? q.header : '',\n options,\n multiSelect: q.multiSelect === true,\n },\n ]\n })\n}\n\nexport type ModelOption = {\n value: string\n resolvedModel?: string\n displayName: string\n description?: string\n primary?: boolean\n reasoningEfforts?: readonly string[]\n}\n\nexport type SkillInfo = {\n name: string\n description?: string\n shortDescription?: string\n displayName?: string\n defaultPrompt?: string\n scope?: string\n enabled: boolean\n}\n\nexport type SlashCommandInfo = {\n name: string\n description?: string\n argumentHint?: string\n aliases?: string[]\n}\n\nexport type ContextUsageCategory = {\n name: string\n tokens: number\n color: string\n}\n\nexport type ContextUsage = {\n categories: ContextUsageCategory[]\n totalTokens: number\n maxTokens: number\n percentage: number\n model?: string\n}\n\nexport type ContextReading = {\n totalTokens: number\n maxTokens: number\n percentage: number\n}\n\nexport type RateLimitInfo = {\n status: string\n rateLimitType?: string\n utilization?: number\n resetsAt?: number\n isUsingOverage?: boolean\n}\n\nexport type ToolExecutionStatus = 'pending' | 'deferred' | 'settled' | 'failed'\n\nexport type ToolExecutionBackend = 'server' | 'browser' | 'managed' | 'remote'\n\nexport type ToolExecutionOutput = { type: 'text'; value: string } | { type: 'json'; value: unknown }\n\nexport type SessionEventBody =\n | {\n type: 'system_init'\n sdkSessionId: string\n model: string\n cwd: string\n apiKeySource: string\n tools: string[]\n skills: string[]\n slashCommands: string[]\n permissionMode: PermissionMode\n claudeCodeVersion: string\n mcpServers: Array<{ name: string; status: string }>\n }\n | { type: 'status_changed'; status: SessionStatus; detail?: string }\n | {\n type: 'capabilities'\n models: ModelOption[]\n commands: SlashCommandInfo[]\n defaultModel?: string\n }\n | { type: 'skills'; skills: SkillInfo[] }\n | { type: 'tool_titles'; titles: Record<string, string> }\n | { type: 'checklist'; items: ChecklistItem[] }\n | {\n type: 'file_produced'\n fileId: string\n path: string\n mediaType?: string\n bytes?: number\n toolUseId?: string\n }\n | { type: 'model_changed'; model?: string }\n | { type: 'permission_mode_changed'; mode: PermissionMode }\n | { type: 'context_usage'; usage: ContextUsage }\n | { type: 'rate_limit'; info: RateLimitInfo }\n | { type: 'plan_info'; subscriptionType: string }\n | {\n type: 'conversation_reset'\n sdkSessionId?: string\n }\n | {\n type: 'context_compacted'\n uuid: string\n parentToolUseId?: string | null\n // The same `uuid` is emitted twice: once with `pending` when the engine starts summarising,\n // once without it when the boundary lands, so one row settles in place. A reader that\n // never sees the first (an older gateway, a replay coalesced to the last) draws the\n // boundary alone, which is what it drew before.\n pending?: boolean\n trigger?: 'manual' | 'auto'\n preTokens?: number\n postTokens?: number\n error?: string\n }\n | {\n type: 'assistant_message'\n message: ApiMessage\n parentToolUseId: string | null\n replay?: boolean\n uuid: string\n }\n | {\n type: 'user_message'\n message: ApiMessage\n parentToolUseId: string | null\n replay?: boolean\n synthetic?: boolean\n attachments?: MessageAttachment[]\n patch?: FilePatch\n uuid?: string\n origin?: MessageOrigin\n }\n | {\n type: 'stream_delta'\n event: { type: string; [key: string]: unknown }\n parentToolUseId: string | null\n uuid: string\n }\n | {\n type: 'turn_result'\n subtype: 'success' | 'error_during_execution' | 'error_max_turns' | 'error_max_budget_usd' | 'error_max_structured_output_retries'\n isError: boolean\n durationMs: number\n numTurns: number\n totalCostUsd: number\n result?: string\n errors?: string[]\n usage?: unknown\n usageByModel?: ByModel\n costUsd?: number\n }\n | { type: 'permission_requested'; request: PermissionRequest }\n | {\n type: 'permission_resolved'\n requestId: string\n behavior: 'allow' | 'deny'\n resolvedBy: PermissionDecisionSource\n message?: string\n }\n | {\n type: 'execution_dispatched'\n executionId: string\n toolName: string\n backend: ToolExecutionBackend\n deferred?: boolean\n expiresAt?: number\n }\n | {\n type: 'execution_result'\n executionId: string\n output: ToolExecutionOutput\n logs?: string[]\n durationMs?: number\n }\n | {\n type: 'execution_failed'\n executionId: string\n reason: string\n error: string\n logs?: string[]\n durationMs?: number\n }\n | { type: 'file_delivered'; path: string; bytes: number; description?: string }\n | { type: 'sdk_event'; payload: { type: string; [key: string]: unknown } }\n | { type: 'session_error'; message: string }\n | { type: 'session_closed'; reason: 'client' | 'server' | 'error' }\n\nexport type SessionEvent = SessionEventBody & {\n seq: number\n ts: number\n}\n\nexport type SessionCommand =\n | {\n type: 'user_message'\n text: string\n attachmentIds?: string[]\n }\n | {\n type: 'permission_decision'\n requestId: string\n behavior: 'allow' | 'deny'\n updatedInput?: Record<string, unknown>\n message?: string\n interrupt?: boolean\n }\n | { type: 'interrupt' }\n | { type: 'clear_context' }\n | { type: 'set_permission_mode'; mode: PermissionMode }\n | { type: 'set_model'; model?: string }\n | {\n type: 'tool_call_result'\n executionId: string\n output: ToolExecutionOutput\n logs?: string[]\n }\n | {\n type: 'tool_call_error'\n executionId: string\n reason: string\n error: string\n logs?: string[]\n }\n | { type: 'shell_command'; command: string }\n | { type: 'close' }\n\nexport const SHELL_COMMAND_MAX = 4000\n\nexport type AttachedFrame = {\n type: 'attached'\n protocolVersion: number\n session: SessionInfo\n replayingFrom: number\n // Whether this principal may run `!` commands on this session: server config x operator x hostCwd.\n // Additive, so no PROTOCOL_VERSION bump; an older gateway omits it and the client never offers the mode.\n shell?: boolean\n // The operator's rate overrides alone, never the bundled table: a client merges them over its own\n // `DEFAULT_PRICING` so what it prices for itself matches what this gateway priced. Additive, and an\n // older gateway omits it, which is the same thing as having no overrides.\n pricingOverrides?: PricingOverrides\n}\n\nexport type ToolCallRequestFrame = {\n type: 'tool_call_request'\n executionId: string\n toolName: string\n input: unknown\n vfsSeed?: Record<string, string>\n limits?: { timeoutMs?: number; memoryLimitBytes?: number }\n expiresAt?: number\n}\n\nexport type ServerFrame =\n | AttachedFrame\n | { type: 'event'; event: SessionEvent }\n | ToolCallRequestFrame\n | { type: 'tool_call_canceled'; executionId: string; reason: string }\n | { type: 'protocol_error'; message: string }\n\nexport type ClientFrame = SessionCommand\n\nexport type ProfileDefaults = {\n model?: string\n permissionMode?: PermissionMode\n}\n\nexport type ProfileEngine = 'claude' | 'codex' | 'provider'\n\nexport type EngineCapabilities = {\n interactiveApprovals: boolean\n permissionModes: readonly PermissionMode[]\n defaultPermissionMode: PermissionMode\n resume: boolean\n resumeBackfill: boolean\n listSessions: boolean\n contextUsage: boolean\n rateLimits: boolean\n mcpStatus: boolean\n mcpServerActions: boolean\n sessionMcpServers: boolean\n slashCommands: boolean\n clearContext?: boolean\n skillsList: boolean\n settingSources: boolean\n budgets: boolean\n attachments: ReadonlyArray<'image' | 'pdf' | 'text'>\n reasoningEfforts?: readonly string[]\n vfs: boolean\n hostCwd?: boolean\n streaming: 'token' | 'item' | 'none'\n}\n\nexport const ENGINE_CAPABILITIES: Record<ProfileEngine, EngineCapabilities> = {\n claude: {\n interactiveApprovals: true,\n permissionModes: ['default', 'acceptEdits', 'bypassPermissions', 'plan', 'dontAsk', 'auto'],\n defaultPermissionMode: 'default',\n resume: true,\n resumeBackfill: true,\n listSessions: true,\n contextUsage: true,\n rateLimits: true,\n mcpStatus: true,\n mcpServerActions: true,\n sessionMcpServers: true,\n slashCommands: true,\n clearContext: true,\n skillsList: false,\n settingSources: true,\n budgets: true,\n attachments: ['image', 'pdf', 'text'],\n reasoningEfforts: ['low', 'medium', 'high', 'xhigh', 'max'],\n vfs: false,\n hostCwd: true,\n streaming: 'token',\n },\n codex: {\n interactiveApprovals: true,\n permissionModes: ['default', 'acceptEdits', 'bypassPermissions', 'auto'],\n defaultPermissionMode: 'default',\n resume: true,\n resumeBackfill: true,\n listSessions: true,\n contextUsage: true,\n rateLimits: true,\n mcpStatus: true,\n mcpServerActions: false,\n sessionMcpServers: false,\n slashCommands: false,\n clearContext: true,\n skillsList: true,\n settingSources: false,\n budgets: false,\n attachments: ['image', 'text'],\n reasoningEfforts: ['minimal', 'low', 'medium', 'high', 'xhigh'],\n vfs: false,\n hostCwd: true,\n streaming: 'token',\n },\n provider: {\n interactiveApprovals: false,\n permissionModes: ['default', 'bypassPermissions', 'dontAsk'],\n defaultPermissionMode: 'default',\n resume: false,\n resumeBackfill: false,\n listSessions: false,\n contextUsage: false,\n rateLimits: false,\n mcpStatus: true,\n mcpServerActions: false,\n sessionMcpServers: false,\n slashCommands: false,\n clearContext: true,\n skillsList: false,\n settingSources: false,\n budgets: false,\n attachments: ['image', 'pdf', 'text'],\n vfs: true,\n hostCwd: false,\n streaming: 'token',\n },\n}\n\nexport function supportsPermissionMode(engine: ProfileEngine | undefined, mode: PermissionMode): boolean {\n return ENGINE_CAPABILITIES[engine ?? 'claude'].permissionModes.includes(mode)\n}\n\nexport type ProviderConfig = {\n id: string\n model?: string\n models?: string[]\n baseUrl?: string\n apiKeyEnv?: string\n}\n\nexport type SessionCapability = 'web_search' | 'download' | 'web_fetch' | 'deliver_file'\n\nexport type ProfileSessionDefaults = {\n capabilities?: SessionCapability[]\n mcpServers?: string[]\n instructions?: string\n}\n\nexport type ProfileUsageWindow = {\n info: RateLimitInfo\n updatedAt: number\n inferredReset?: boolean\n}\n\nexport type ProfileUsage = Record<string, ProfileUsageWindow>\n\nexport type ProfileInfo = {\n name: string\n engine?: ProfileEngine\n configDir?: string\n codexHome?: string\n provider?: ProviderConfig\n description?: string\n defaults?: ProfileDefaults\n session?: ProfileSessionDefaults\n models?: ModelOption[]\n defaultModel?: string\n capabilities?: EngineCapabilities\n available?: boolean\n unavailableReason?: string\n usage?: ProfileUsage\n spend?: ProfileSpend\n managed?: boolean\n}\n\nexport type ProfileConfigSnapshot = {\n settings?: {\n model?: string\n defaultPermissionMode?: string\n permissionRules?: { allow: number; ask: number; deny: number }\n envKeys?: string[]\n hooks?: string[]\n }\n hasUserMemory: boolean\n skills: string[]\n agents: string[]\n commands: string[]\n}\n\nexport type McpServerConfigWire =\n | { type?: 'stdio'; command: string; args?: string[]; env?: Record<string, string> }\n | { type: 'http'; url: string; headers?: Record<string, string> }\n | { type: 'sse'; url: string; headers?: Record<string, string> }\n\nexport type McpServerToolInfo = {\n name: string\n title?: string\n description?: string\n annotations?: { readOnly?: boolean; destructive?: boolean; openWorld?: boolean }\n inputSchema?: unknown\n}\n\nexport type McpServerStatusInfo = {\n name: string\n status: string\n scope?: string\n error?: string\n serverInfo?: { name: string; version: string }\n transport?: 'stdio' | 'http' | 'sse' | 'sdk'\n command?: string\n args?: string[]\n url?: string\n tools?: McpServerToolInfo[]\n}\n\nexport type McpServersResponse = { servers: McpServerStatusInfo[] }\n\nexport type McpServerActionRequest = { action: 'reconnect' | 'enable' | 'disable' }\n\nexport type UploadAttachmentResponse = { attachment: MessageAttachment }\n\nexport type CreateSessionRequest = {\n cwd?: string\n profile?: string\n prompt?: string\n permissionMode?: PermissionMode\n allowDangerouslySkipPermissions?: boolean\n allowedTools?: string[]\n disallowedTools?: string[]\n mcpServers?: Record<string, McpServerConfigWire>\n settingSources?: Array<'user' | 'project' | 'local'>\n model?: string\n maxTurns?: number\n maxBudgetUsd?: number\n resume?: string\n forkSession?: boolean\n reasoningEffort?: string\n includePartialMessages?: boolean\n // Overrides the gateway's default. null (or 0) means a prompt never expires - it waits as long as the session lives.\n approvalTimeoutMs?: number | null\n questionBehavior?: QuestionBehavior\n capabilities?: SessionCapability[]\n meta?: Record<string, unknown>\n scope?: Record<string, string>\n}\n\nexport type SubagentInfo = {\n toolUseId: string\n agentType?: string\n description?: string\n status: 'running' | 'done' | 'failed'\n startedAt: number\n toolCount: number\n}\n\nexport const SUBAGENT_HISTORY = 8\n\n// Widening this union costs a PROTOCOL_VERSION bump: Swift decodes it strictly.\nexport type ChecklistStatus = 'pending' | 'in_progress' | 'completed'\n\nexport type ChecklistItem = { text: string; status: ChecklistStatus }\n\nexport const CHECKLIST_TEXT_MAX = 200\n\nexport type ProjectIcon = { type: 'glyph'; name: string } | { type: 'image'; mediaType: 'image/png' | 'image/svg+xml'; hash: string }\n\nexport type ProjectInfo = {\n name: string\n root: string\n icon?: ProjectIcon\n shortcode?: string\n}\n\n// Who wrote a `user_message` when it was not the person at the keyboard. Absent means the human;\n// `peer` is another session on this or a sibling gateway, delivered through the peer tools.\nexport type MessageOrigin = {\n kind: 'peer'\n sessionId: string\n name?: string\n engine?: ProfileEngine\n hostId?: string\n hops?: string[]\n}\n\n// `peers_send` answers the model in prose, not in a structured result, so the recipient's name only\n// ever reaches a client inside that sentence. Both sides go through this pair rather than each\n// inventing a format: the engine writes the line, the transcript reads the name back out of it.\nexport function peerDeliveredPrefix(sessionId: string, name?: string): string {\n return `Delivered to ${name ? `${name} (${sessionId})` : sessionId}`\n}\n\nexport function peerDeliveredTo(text: string): { sessionId: string; name?: string } | undefined {\n const named = /^Delivered to (.+) \\(([^()]+)\\);/.exec(text)\n if (named) {\n return { sessionId: named[2]!, name: named[1]! }\n }\n const bare = /^Delivered to ([^()\\s]+);/.exec(text)\n return bare ? { sessionId: bare[1]! } : undefined\n}\n\nexport type SessionInfo = {\n id: string\n sdkSessionId?: string\n status: SessionStatus\n cwd: string\n profile?: string\n engine?: ProfileEngine\n capabilities?: EngineCapabilities\n model?: string\n permissionMode?: PermissionMode\n canBypassPermissions?: boolean\n apiKeySource?: string\n createdAt: number\n lastSeq: number\n // Which log the seqs belong to. A dormant wake starts a fresh log and bumps it, so a `seq`\n // that outlived one - a notification sitting on a lock screen - can be told from a live one.\n // Absent from a gateway that predates it, and from a session that has never woken; additive,\n // so no `PROTOCOL_VERSION` bump, and a reader that finds it absent on either side must keep\n // trusting the seq.\n epoch?: number\n pendingPermissionCount: number\n subagents?: SubagentInfo[]\n checklist?: ChecklistItem[]\n meta?: Record<string, unknown>\n title?: string\n totalCostUsd?: number\n costUsd?: number\n usageByModel?: ByModel\n numTurns?: number\n activityCount?: number\n // Rows of the kind a person is actually waiting to read - see `transcriptProse`.\n // Absent from a gateway that predates it - additive, so no `PROTOCOL_VERSION` bump -\n // which is why every reader falls back to `activityCount`. This is the badge's number; `activityCount` stays the \"has\n // anything happened at all\" measure that sorting and dormancy read.\n proseCount?: number\n lastActivityAt?: number\n contextUsage?: ContextReading\n scope?: Record<string, string>\n project?: ProjectInfo\n}\n\nexport function contextReading(body: SessionEventBody): ContextReading | undefined {\n if (body.type !== 'context_usage') {\n return undefined\n }\n const { totalTokens, maxTokens, percentage } = body.usage\n return { totalTokens, maxTokens, percentage }\n}\n\nexport function transcriptActivity(body: SessionEventBody): number {\n if ('parentToolUseId' in body && body.parentToolUseId != null) {\n return 0\n }\n switch (body.type) {\n case 'assistant_message': {\n const content = body.message.content\n if (typeof content === 'string') {\n return content.trim() === '' ? 0 : 1\n }\n const rows = content.filter((block) => block.type === 'text' || block.type === 'thinking' || block.type === 'tool_use').length\n return rows\n }\n case 'user_message': {\n return body.synthetic ? 0 : 1\n }\n case 'turn_result':\n case 'file_delivered':\n case 'session_error': {\n return 1\n }\n default: {\n return 0\n }\n }\n}\n\n// The narrower door beside transcriptActivity: output addressed to the human, not evidence of work.\n// A `user_message` the human typed is deliberately absent: they wrote it, so it can never be unread by\n// them, and counting it badged the sender's own prompt whenever they navigated away before the list next\n// polled. One with an `origin` is the opposite case - a peer wrote it, the human has not seen it.\nexport function transcriptProse(body: SessionEventBody): number {\n if ('parentToolUseId' in body && body.parentToolUseId != null) {\n return 0\n }\n switch (body.type) {\n case 'user_message': {\n return body.origin && !body.synthetic ? 1 : 0\n }\n case 'assistant_message': {\n const content = body.message.content\n if (typeof content === 'string') {\n return content.trim() === '' ? 0 : 1\n }\n return content.filter((block) => block.type === 'text' && typeof block.text === 'string' && block.text.trim() !== '').length\n }\n case 'turn_result': {\n return body.isError ? 1 : 0\n }\n case 'file_delivered':\n case 'session_error': {\n return 1\n }\n default: {\n return 0\n }\n }\n}\n\nexport function transcriptContent(body: SessionEventBody): boolean {\n switch (body.type) {\n case 'user_message':\n case 'assistant_message':\n case 'stream_delta':\n case 'turn_result':\n case 'execution_dispatched':\n case 'execution_result':\n case 'execution_failed':\n case 'file_delivered':\n case 'session_error':\n case 'session_closed':\n case 'conversation_reset':\n case 'context_compacted': {\n return true\n }\n default: {\n return false\n }\n }\n}\n\nexport function replayCoalesceKey(body: SessionEventBody): string | undefined {\n switch (body.type) {\n case 'context_usage': {\n return 'context_usage'\n }\n case 'rate_limit': {\n return body.info.rateLimitType ? `rate_limit:${body.info.rateLimitType}` : undefined\n }\n case 'status_changed': {\n return 'status_changed'\n }\n case 'context_compacted': {\n return `context_compacted:${body.uuid}`\n }\n case 'checklist': {\n return 'checklist'\n }\n case 'sdk_event': {\n return body.payload.type === 'system' && body.payload.subtype === 'status' ? 'sdk_event:system:status' : undefined\n }\n default: {\n return undefined\n }\n }\n}\n\nexport function replayRetains(body: SessionEventBody): boolean {\n if (body.type !== 'stream_delta') {\n return true\n }\n const delta = body.event as { type?: string; delta?: { type?: string } }\n if (delta.type !== 'content_block_delta') {\n return false\n }\n return delta.delta?.type === 'text_delta' || delta.delta?.type === 'thinking_delta'\n}\n\nexport function snapshotRetains(body: SessionEventBody): boolean {\n return body.type !== 'stream_delta'\n}\n\nexport type SdkSessionSummary = {\n sessionId: string\n summary: string\n lastModified: number\n createdAt?: number\n customTitle?: string\n firstPrompt?: string\n gitBranch?: string\n cwd?: string\n}\n\nexport type SessionFileInfo = { path: string; bytes: number }\nexport type ListSessionFilesResponse = { files: SessionFileInfo[] }\nexport type ListSessionsResponse = { sessions: SessionInfo[] }\nexport type CreateSessionResponse = { session: SessionInfo }\nexport type GetSessionResponse = { session: SessionInfo }\n\nexport type UpdateSessionRequest = { title?: string | null }\nexport type UpdateSessionResponse = { session: SessionInfo }\n\nexport type ResolvePermissionRequest =\n | { behavior: 'allow'; updatedInput?: Record<string, unknown> }\n | { behavior: 'deny'; message?: string; interrupt?: boolean }\nexport type ResolvePermissionResponse = { resolved: true }\n\nexport type SubmitExecutionResultRequest =\n | { status: 'ok'; output: ToolExecutionOutput; logs?: string[] }\n | { status: 'failed'; reason: string; error: string; logs?: string[] }\nexport type SubmitExecutionResultResponse = {\n applied: boolean\n sessionId: string\n}\n\nexport type ListSdkSessionsResponse = { sdkSessions: SdkSessionSummary[] }\nexport type ListProfilesResponse = {\n profiles: ProfileInfo[]\n canManage?: boolean\n}\n\nexport type CreateProfileRequest = ProfileInfo\n\nexport type UpdateProfileRequest = Omit<Partial<ProfileInfo>, 'name'>\n\nexport type HostFileRoot = {\n path: string\n name: string\n}\n\nexport type ListHostRootsResponse = {\n roots: HostFileRoot[]\n canWrite: boolean\n}\n\nexport type HostDirEntry = {\n name: string\n path: string\n type: 'file' | 'dir' | 'symlink' | 'other'\n bytes?: number\n modifiedAt?: number\n}\n\nexport type ListHostDirResponse = {\n path: string\n entries: HostDirEntry[]\n truncated?: boolean\n}\n\nexport type HostFileMatch = {\n path: string\n relative: string\n}\n\nexport type FindHostFilesResponse = {\n base: string\n matches: HostFileMatch[]\n truncated: boolean\n}\n\nexport type ReadHostFileResponse = {\n path: string\n content: string\n encoding: 'utf8' | 'base64'\n bytes: number\n hash: string\n modifiedAt: number\n}\n\nexport type WriteHostFileRequest = {\n path: string\n content: string\n encoding?: 'utf8' | 'base64'\n expectedHash?: string\n}\n\nexport type WriteHostFileResponse = {\n path: string\n bytes: number\n hash: string\n modifiedAt: number\n}\n\nexport type SaveProfileResponse = { profile: ProfileInfo }\nexport type GetProfileResponse = { profile: ProfileInfo; config: ProfileConfigSnapshot }\nexport type ErrorResponse = { error: string }\n\nexport type SessionNotificationType = 'permission_requested' | 'turn_completed' | 'session_error' | 'session_closed'\n\nexport type SessionNotification = {\n type: SessionNotificationType\n sessionId: string\n session: SessionInfo\n seq: number\n ts: number\n preview?: string\n request?: PermissionRequest\n result?: { isError: boolean; durationMs: number; numTurns: number; totalCostUsd: number }\n reason?: 'client' | 'server' | 'error'\n}\n\nexport type SessionWebhookConfig = {\n url: string\n headers?: Record<string, string>\n events?: SessionNotificationType[]\n}\n\nexport type JobStatus = 'queued' | 'running' | 'parked' | 'succeeded' | 'failed' | 'canceled'\n\nexport type WebhookConfig = {\n url: string\n headers?: Record<string, string>\n progress?: 'messages' | 'completion'\n}\n\nexport type CreateJobRequest = {\n session: CreateSessionRequest & { prompt: string }\n webhook?: WebhookConfig\n maxTokens?: number\n maxDurationMs?: number\n attempts?: number\n retryDelayMs?: number\n meta?: Record<string, unknown>\n}\n\nexport type JobUsage = {\n tokens: number\n totalCostUsd: number\n numTurns: number\n costUsd?: number\n}\n\nexport type JobResult = {\n subtype: string\n isError: boolean\n result?: string\n errors?: string[]\n durationMs: number\n}\n\nexport type JobInfo = {\n id: string\n status: JobStatus\n cwd: string\n profile?: string\n prompt: string\n sessionId?: string\n sdkSessionId?: string\n createdAt: number\n startedAt?: number\n finishedAt?: number\n attempt?: number\n maxAttempts?: number\n nextRunAt?: number\n parkedAt?: number\n parkedExecutionId?: string\n usage: JobUsage\n result?: JobResult\n error?: string\n meta?: Record<string, unknown>\n scope?: Record<string, string>\n}\n\nexport type JobProgress = {\n kind: 'assistant_text' | 'tool_use' | 'permission_requested' | 'permission_resolved'\n preview?: string\n request?: PermissionRequest\n}\n\nexport type JobEvent =\n | { type: 'job_submitted'; job: JobInfo; ts: number }\n | { type: 'job_started'; job: JobInfo; ts: number }\n | { type: 'job_progress'; job: JobInfo; progress: JobProgress; ts: number }\n | { type: 'job_parked'; job: JobInfo; executionId: string; ts: number }\n | { type: 'job_resumed'; job: JobInfo; executionId: string; ts: number }\n | { type: 'job_retrying'; job: JobInfo; ts: number }\n | { type: 'job_completed'; job: JobInfo; ts: number }\n\nexport type QueueStats = {\n maxConcurrency: number\n running: number\n queued: number\n parked: number\n sessionTokenLimit?: number\n dailyTokenLimit?: number\n dailyTokensUsed: number\n paused: boolean\n}\n\nexport type QueueServerFrame =\n | { type: 'queue_attached'; protocolVersion: number; stats: QueueStats }\n | { type: 'job_event'; event: JobEvent }\n | { type: 'queue_stats'; stats: QueueStats }\n\nexport type CreateJobResponse = { job: JobInfo }\nexport type GetJobResponse = { job: JobInfo }\nexport type ListJobsResponse = { jobs: JobInfo[] }\nexport type QueueStatsResponse = { stats: QueueStats }\n\nexport * from './checklist.ts'\nexport * from './pricing.ts'\nexport * from './session-list.ts'\nexport * from './tool-titles.ts'\nexport * from './usage.ts'\nexport * from './watermarks.ts'\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workerdeck/protocol",
3
- "version": "2.10.0",
3
+ "version": "2.11.0",
4
4
  "type": "module",
5
5
  "description": "The WorkerDeck wire protocol: typed session events, commands, and REST shapes shared by server and clients. Dependency-free, browser-safe. This protocol is the product boundary - versioned from day one.",
6
6
  "license": "MIT",