@workerdeck/protocol 3.2.0 → 3.4.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
@@ -85,8 +85,14 @@ declare function visibleSubagents(info: SessionInfo, show: SubagentDisplay): Sub
85
85
  declare function isAgentRecord(sub: SubagentInfo): boolean;
86
86
  declare function subagentLabel(sub: SubagentInfo): string;
87
87
  type Facet = 'gateway' | 'adapter' | 'state' | 'project';
88
- type GroupBy = 'none' | Facet;
88
+ type GroupBy = 'none' | 'state' | 'adapter' | 'project' | 'custom';
89
89
  type SortBy = 'recent' | 'name' | Facet;
90
+ declare const GROUP_BY: readonly GroupBy[];
91
+ type CustomGroup = {
92
+ id: string;
93
+ name: string;
94
+ members: string[];
95
+ };
90
96
  type StepDisplay = 'all' | 'active' | 'none';
91
97
  type SubagentDisplay = StepDisplay;
92
98
  type ViewConfig = {
@@ -101,6 +107,7 @@ type ViewConfig = {
101
107
  subagents: SubagentDisplay;
102
108
  shells?: StepDisplay;
103
109
  tasks?: StepDisplay;
110
+ customGroups?: CustomGroup[];
104
111
  };
105
112
  declare const DEFAULT_VIEW_CONFIG: ViewConfig;
106
113
  type ScopeRoot = {
@@ -123,8 +130,19 @@ type SessionRow = {
123
130
  type SessionGroup = {
124
131
  key: string;
125
132
  label?: string;
133
+ gateway?: string;
134
+ project?: string;
126
135
  rows: SessionRow[];
136
+ hostId?: string;
137
+ cwd?: string;
138
+ custom?: string;
139
+ };
140
+ type GroupOptions = {
141
+ gatewayCount?: number;
127
142
  };
143
+ declare const UNGROUPED_KEY = "custom:ungrouped";
144
+ declare function sessionKey(row: Pick<SessionRow, 'hostId' | 'info'>): string;
145
+ declare function normalizeViewConfig(stored: Partial<ViewConfig> | undefined): ViewConfig;
128
146
  declare function adaptersOf(rows: readonly SessionRow[]): string[];
129
147
  declare function projectsOf(rows: readonly SessionRow[]): {
130
148
  key: string;
@@ -141,7 +159,13 @@ declare function visibleShells(info: SessionInfo, show: StepDisplay, now: number
141
159
  declare function inScope(row: SessionRow, scope: WorkspaceScope): boolean;
142
160
  declare function scopeActive(config: ViewConfig, scope: WorkspaceScope | undefined): boolean;
143
161
  declare function filterRows(rows: readonly SessionRow[], config: ViewConfig, scope?: WorkspaceScope): SessionRow[];
144
- declare function groupRows(rows: readonly SessionRow[], config: ViewConfig): SessionGroup[];
162
+ declare function groupRows(rows: readonly SessionRow[], config: ViewConfig, options?: GroupOptions): SessionGroup[];
163
+ declare function newCustomGroupId(): string;
164
+ declare function addCustomGroup(groups: readonly CustomGroup[], name: string, id?: string): CustomGroup[];
165
+ declare function renameCustomGroup(groups: readonly CustomGroup[], id: string, name: string): CustomGroup[];
166
+ declare function removeCustomGroup(groups: readonly CustomGroup[], id: string): CustomGroup[];
167
+ declare function moveToCustomGroup(groups: readonly CustomGroup[], key: string, target: string | undefined, before?: string): CustomGroup[];
168
+ declare function moveCustomGroup(groups: readonly CustomGroup[], id: string, before: string | undefined): CustomGroup[];
145
169
  type SubsetSummary = {
146
170
  shown: number;
147
171
  total: number;
@@ -194,6 +218,25 @@ type PeerMentionToken = {
194
218
  end: number;
195
219
  body: string;
196
220
  };
221
+ type PeerSessionSummary = {
222
+ id: string;
223
+ gateway?: string;
224
+ engine?: ProfileEngine;
225
+ status: SessionStatus;
226
+ title?: string;
227
+ project?: string;
228
+ projectRoot?: string;
229
+ cwd: string;
230
+ profile?: string;
231
+ model?: string;
232
+ contextUsage?: ContextReading;
233
+ lastActivityAt?: number;
234
+ pendingPermissionCount: number;
235
+ allow?: Array<'send' | 'peek'>;
236
+ };
237
+ type PeerSessionsResponse = {
238
+ peers: PeerSessionSummary[];
239
+ };
197
240
  declare const PROMPT_SENTENCE_TAIL: ReadonlySet<string>;
198
241
  declare function peerMentionSlug(title: string | undefined, id: string): string;
199
242
  declare function peerMentionKey(body: string): string;
@@ -457,6 +500,9 @@ type SessionEventBody = {
457
500
  } | {
458
501
  type: 'model_changed';
459
502
  model?: string;
503
+ } | {
504
+ type: 'effort_changed';
505
+ effort: string | null;
460
506
  } | {
461
507
  type: 'permission_mode_changed';
462
508
  mode: PermissionMode;
@@ -469,9 +515,13 @@ type SessionEventBody = {
469
515
  } | {
470
516
  type: 'plan_info';
471
517
  subscriptionType: string;
518
+ } | {
519
+ type: 'engine_sleep';
520
+ asleep: boolean;
472
521
  } | {
473
522
  type: 'conversation_reset';
474
523
  sdkSessionId?: string;
524
+ agentReason?: string;
475
525
  } | {
476
526
  type: 'context_compacted';
477
527
  uuid: string;
@@ -552,6 +602,10 @@ type SessionEventBody = {
552
602
  path: string;
553
603
  bytes: number;
554
604
  description?: string;
605
+ } | {
606
+ type: 'tool_output';
607
+ toolUseId: string;
608
+ tail: string;
555
609
  } | {
556
610
  type: 'sdk_event';
557
611
  payload: {
@@ -608,12 +662,20 @@ type SessionCommand = {
608
662
  type: 'interrupt';
609
663
  } | {
610
664
  type: 'clear_context';
665
+ } | {
666
+ type: 'sleep';
667
+ } | {
668
+ type: 'background_task';
669
+ toolUseId?: string;
611
670
  } | {
612
671
  type: 'set_permission_mode';
613
672
  mode: PermissionMode;
614
673
  } | {
615
674
  type: 'set_model';
616
675
  model?: string;
676
+ } | {
677
+ type: 'set_effort';
678
+ effort?: string;
617
679
  } | {
618
680
  type: 'tool_call_result';
619
681
  executionId: string;
@@ -730,6 +792,8 @@ type ClientFrame = SessionCommand;
730
792
  type ProfileDefaults = {
731
793
  model?: string;
732
794
  permissionMode?: PermissionMode;
795
+ efforts?: Record<string, string>;
796
+ agentContextReset?: boolean;
733
797
  };
734
798
  type ProfileEngine = 'claude' | 'codex' | 'provider';
735
799
  type EngineCapabilities = {
@@ -755,16 +819,20 @@ type EngineCapabilities = {
755
819
  vfs: boolean;
756
820
  hostCwd?: boolean;
757
821
  systemInstructions?: boolean;
822
+ engineSleep?: boolean;
823
+ backgroundTasks?: boolean;
758
824
  streaming: 'token' | 'item' | 'none';
759
825
  };
760
826
  declare const ENGINE_CAPABILITIES: Record<ProfileEngine, EngineCapabilities>;
761
827
  declare function supportsPermissionMode(engine: ProfileEngine | undefined, mode: PermissionMode): boolean;
828
+ type ProviderContextWindow = number | Record<string, number>;
762
829
  type ProviderConfig = {
763
830
  id: string;
764
831
  model?: string;
765
832
  models?: string[];
766
833
  baseUrl?: string;
767
834
  apiKeyEnv?: string;
835
+ contextWindow?: ProviderContextWindow;
768
836
  };
769
837
  type SessionCapability = 'web_search' | 'download' | 'web_fetch' | 'deliver_file';
770
838
  type ProfileSessionDefaults = {
@@ -884,6 +952,7 @@ type CreateSessionRequest = {
884
952
  capabilities?: SessionCapability[];
885
953
  meta?: Record<string, unknown>;
886
954
  scope?: Record<string, string>;
955
+ agentContextReset?: boolean;
887
956
  };
888
957
  declare const CREATE_SESSION_REQUEST_KEYS: ReadonlyArray<keyof CreateSessionRequest>;
889
958
  declare function pickCreateSessionRequest(body: Record<string, unknown>): CreateSessionRequest;
@@ -927,6 +996,7 @@ type MessageOrigin = {
927
996
  hops?: string[];
928
997
  };
929
998
  declare function peerDeliveredPrefix(sessionId: string, name?: string): string;
999
+ declare function peerShortId(sessionId: string): string;
930
1000
  declare function peerDeliveredTo(text: string): {
931
1001
  sessionId: string;
932
1002
  name?: string;
@@ -940,6 +1010,7 @@ type SessionInfo = {
940
1010
  engine?: ProfileEngine;
941
1011
  capabilities?: EngineCapabilities;
942
1012
  model?: string;
1013
+ effort?: string | null;
943
1014
  permissionMode?: PermissionMode;
944
1015
  canBypassPermissions?: boolean;
945
1016
  apiKeySource?: string;
@@ -963,6 +1034,8 @@ type SessionInfo = {
963
1034
  project?: ProjectInfo;
964
1035
  shells?: ShellInfo[];
965
1036
  shellAgentWrite?: 'gated' | 'allow';
1037
+ engineAsleep?: true;
1038
+ agentContextReset?: true;
966
1039
  };
967
1040
  declare function contextReading(body: SessionEventBody): ContextReading | undefined;
968
1041
  declare function transcriptActivity(body: SessionEventBody): number;
@@ -1246,5 +1319,5 @@ type QueueStatsResponse = {
1246
1319
  stats: QueueStats;
1247
1320
  };
1248
1321
  //#endregion
1249
- export { ApiMessage, AttachedFrame, BUILTIN_TOOL_TITLES, ByModel, CHECKLIST_TEXT_MAX, CREATE_SESSION_REQUEST_KEYS, 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, GatewayMeta, 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_MENTION_BODY_MAX, PEER_MENTION_MAX, PEER_MENTION_SCAN_MAX, PEER_MENTION_SIGIL, PEER_SEND_TOOLS, PRICING_AS_OF, PRICING_NOTE, PRICING_SOURCES, PRICING_STALE_DAYS, PROMPT_SENTENCE_TAIL, PROTOCOL_VERSION, PatchHunk, PeerMentionToken, 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_ARTIFACT_MAX_BYTES, SHELL_ARTIFACT_TTL_MS, SHELL_ATTACH_REPLAY_BYTES, SHELL_COLS, SHELL_COMMAND_MAX, SHELL_CONTEXT_FLUSH_MAX_CHARS, SHELL_CONTEXT_HEAD_CHARS, SHELL_CONTEXT_HEAD_LINES, SHELL_CONTEXT_TAIL_CHARS, SHELL_CONTEXT_TAIL_LINES, SHELL_INLINE_CHARS, SHELL_INLINE_LINES, SHELL_INLINE_LINE_CHARS, SHELL_INPUT_MAX, SHELL_INTERACTIVE_NOTE, SHELL_LABEL_MAX, SHELL_LINGER_MS, SHELL_MAX_COLS, SHELL_MAX_ROWS, SHELL_MAX_RUNNING_PER_SESSION, SHELL_MAX_RUNNING_TOTAL, SHELL_MIN_COLS, SHELL_MIN_ROWS, SHELL_PROMOTE_MS, SHELL_READ_DEFAULT_LINES, SHELL_READ_MAX_LINES, SHELL_ROWS, SHELL_SPILL_BYTES, SHELL_TAIL_FLUSH_MS, SHELL_TAIL_RING_BYTES, SHELL_WAIT_DEFAULT_MS, SHELL_WAIT_MAX_MS, 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, ShellEndReason, ShellInfo, ShellOwner, ShellStatus, SkillInfo, SlashCommandInfo, SortBy, StepDisplay, SubagentDisplay, 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, displayCustomized, displayedTasks, emptyTokenUsage, errorMessage, facetFilterCount, filterRows, groupRows, hasFacetFilter, imagePartRef, inScope, isAgentRecord, isJobRun, isPeerMentionBody, isPeerSendTool, logCoalesceKey, mergeByModel, mergePricing, mergeUsage, meteredCost, orderUsageWindows, parseTodoWriteInput, parseUserQuestions, peerDeliveredPrefix, peerDeliveredTo, peerMentionKey, peerMentionSlug, pickCreateSessionRequest, pricingAgeDays, pricingAgeNote, projectKey, projectLabel, projectName, projectSubpath, projectsOf, promotedShells, rateFor, replayCoalesceKey, replayRetains, resolvePosix, runningSubagents, sanitizeToolTitle, scanPeerMentions, scopeActive, sessionLabel, sessionState, sessionTasks, setPricingOverrides, snapshotRetains, subagentLabel, subscriptionComparison, subsetSummary, supportsPermissionMode, taskCountLabel, taskSummary, tokenUsageFromWire, toolTitle, totalTokens, transcriptActivity, transcriptContent, transcriptProse, unknownBasisModels, unpricedModels, unseenCount, usageInfos, usageIsStale, visibleShells, visibleSubagents, visibleTasks, watermarkKey, worseBasis };
1322
+ export { ApiMessage, AttachedFrame, BUILTIN_TOOL_TITLES, ByModel, CHECKLIST_TEXT_MAX, CREATE_SESSION_REQUEST_KEYS, ChecklistItem, ChecklistStatus, ClientFrame, ContentBlock, ContextReading, ContextUsage, ContextUsageCategory, CostBasis, CostBreakdown, CreateJobRequest, CreateJobResponse, CreateProfileRequest, CreateSessionRequest, CreateSessionResponse, CustomGroup, DEFAULT_PRICING, DEFAULT_VIEW_CONFIG, ENGINE_CAPABILITIES, EngineCapabilities, ErrorResponse, Facet, FilePatch, FindHostFilesResponse, GROUP_BY, GatewayMeta, GetJobResponse, GetProfileResponse, GetSessionResponse, GroupBy, GroupOptions, 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_MENTION_BODY_MAX, PEER_MENTION_MAX, PEER_MENTION_SCAN_MAX, PEER_MENTION_SIGIL, PEER_SEND_TOOLS, PRICING_AS_OF, PRICING_NOTE, PRICING_SOURCES, PRICING_STALE_DAYS, PROMPT_SENTENCE_TAIL, PROTOCOL_VERSION, PatchHunk, PeerMentionToken, PeerSessionSummary, PeerSessionsResponse, PermissionDecisionSource, PermissionMode, PermissionRequest, PricingMerge, PricingOverrides, PricingTable, ProfileConfigSnapshot, ProfileDefaults, ProfileEngine, ProfileInfo, ProfileSessionDefaults, ProfileSpend, ProfileUsage, ProfileUsageWindow, ProjectIcon, ProjectInfo, ProviderConfig, ProviderContextWindow, QuestionBehavior, QueueServerFrame, QueueStats, QueueStatsResponse, RateLimitInfo, ReadHostFileResponse, ResolvePermissionRequest, ResolvePermissionResponse, SHELL_ARTIFACT_MAX_BYTES, SHELL_ARTIFACT_TTL_MS, SHELL_ATTACH_REPLAY_BYTES, SHELL_COLS, SHELL_COMMAND_MAX, SHELL_CONTEXT_FLUSH_MAX_CHARS, SHELL_CONTEXT_HEAD_CHARS, SHELL_CONTEXT_HEAD_LINES, SHELL_CONTEXT_TAIL_CHARS, SHELL_CONTEXT_TAIL_LINES, SHELL_INLINE_CHARS, SHELL_INLINE_LINES, SHELL_INLINE_LINE_CHARS, SHELL_INPUT_MAX, SHELL_INTERACTIVE_NOTE, SHELL_LABEL_MAX, SHELL_LINGER_MS, SHELL_MAX_COLS, SHELL_MAX_ROWS, SHELL_MAX_RUNNING_PER_SESSION, SHELL_MAX_RUNNING_TOTAL, SHELL_MIN_COLS, SHELL_MIN_ROWS, SHELL_PROMOTE_MS, SHELL_READ_DEFAULT_LINES, SHELL_READ_MAX_LINES, SHELL_ROWS, SHELL_SPILL_BYTES, SHELL_TAIL_FLUSH_MS, SHELL_TAIL_RING_BYTES, SHELL_WAIT_DEFAULT_MS, SHELL_WAIT_MAX_MS, 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, ShellEndReason, ShellInfo, ShellOwner, ShellStatus, SkillInfo, SlashCommandInfo, SortBy, StepDisplay, SubagentDisplay, SubagentInfo, SubmitExecutionResultRequest, SubmitExecutionResultResponse, SubscriptionComparison, SubsetSummary, TOOL_RESULT_HEAD_CHARS, TOOL_TITLE_MAX_CHARS, TaskSummary, TextBlock, ThinkingBlock, TokenUsage, ToolCallRequestFrame, ToolExecutionBackend, ToolExecutionOutput, ToolExecutionStatus, ToolResultBlock, ToolUseBlock, UNGROUPED_KEY, 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, addCustomGroup, addTokenUsage, byModelTotalTokens, canonicalModel, clearFilters, contextReading, costOf, costOfByModel, displayCustomized, displayedTasks, emptyTokenUsage, errorMessage, facetFilterCount, filterRows, groupRows, hasFacetFilter, imagePartRef, inScope, isAgentRecord, isJobRun, isPeerMentionBody, isPeerSendTool, logCoalesceKey, mergeByModel, mergePricing, mergeUsage, meteredCost, moveCustomGroup, moveToCustomGroup, newCustomGroupId, normalizeViewConfig, orderUsageWindows, parseTodoWriteInput, parseUserQuestions, peerDeliveredPrefix, peerDeliveredTo, peerMentionKey, peerMentionSlug, peerShortId, pickCreateSessionRequest, pricingAgeDays, pricingAgeNote, projectKey, projectLabel, projectName, projectSubpath, projectsOf, promotedShells, rateFor, removeCustomGroup, renameCustomGroup, replayCoalesceKey, replayRetains, resolvePosix, runningSubagents, sanitizeToolTitle, scanPeerMentions, scopeActive, sessionKey, sessionLabel, sessionState, sessionTasks, setPricingOverrides, snapshotRetains, subagentLabel, subscriptionComparison, subsetSummary, supportsPermissionMode, taskCountLabel, taskSummary, tokenUsageFromWire, toolTitle, totalTokens, transcriptActivity, transcriptContent, transcriptProse, unknownBasisModels, unpricedModels, unseenCount, usageInfos, usageIsStale, visibleShells, visibleSubagents, visibleTasks, watermarkKey, worseBasis };
1250
1323
  //# sourceMappingURL=index.d.mts.map
package/build/index.mjs CHANGED
@@ -35,6 +35,13 @@ function subagentLabel(sub) {
35
35
  if (agent && description) return `${agent} · ${description}`;
36
36
  return agent || description || "Sub-agent";
37
37
  }
38
+ const GROUP_BY = [
39
+ "none",
40
+ "state",
41
+ "adapter",
42
+ "project",
43
+ "custom"
44
+ ];
38
45
  const DEFAULT_VIEW_CONFIG = {
39
46
  search: "",
40
47
  gateways: [],
@@ -48,6 +55,21 @@ const DEFAULT_VIEW_CONFIG = {
48
55
  shells: "active",
49
56
  tasks: "active"
50
57
  };
58
+ const UNGROUPED_KEY = "custom:ungrouped";
59
+ function sessionKey(row) {
60
+ return `${row.hostId}:${row.info.id}`;
61
+ }
62
+ function normalizeViewConfig(stored) {
63
+ const config = {
64
+ ...DEFAULT_VIEW_CONFIG,
65
+ ...stored
66
+ };
67
+ const groupBy = config.groupBy;
68
+ return GROUP_BY.includes(groupBy) ? config : {
69
+ ...config,
70
+ groupBy: groupBy === "gateway" ? "project" : DEFAULT_VIEW_CONFIG.groupBy
71
+ };
72
+ }
51
73
  function adaptersOf(rows) {
52
74
  return [...new Set(rows.map((r) => r.adapter))].sort();
53
75
  }
@@ -124,11 +146,13 @@ function filterRows(rows, config, scope) {
124
146
  function facetKey(row, facet) {
125
147
  return facet === "gateway" ? row.hostId : facet === "adapter" ? row.adapter : facet === "project" ? projectKey(row) : row.state;
126
148
  }
127
- function facetLabel(row, facet) {
128
- return facet === "gateway" ? row.hostName : facet === "adapter" ? row.adapter : facet === "project" ? projectLabel(row) : STATE_LABELS[row.state];
149
+ function facetLabel(row, facet, multiGateway = false) {
150
+ if (facet === "project") return multiGateway ? `${row.hostName} ${projectLabel(row)}` : projectLabel(row);
151
+ return facet === "gateway" ? row.hostName : facet === "adapter" ? row.adapter : STATE_LABELS[row.state];
129
152
  }
130
- function facetRank(row, facet) {
153
+ function facetRank(row, facet, multiGateway = false) {
131
154
  if (facet === "state") return String(STATE_ORDER.indexOf(row.state));
155
+ if (facet === "project" && multiGateway) return `${row.hostName.toLowerCase()}\u0000${projectLabel(row).toLowerCase()}`;
132
156
  return facetLabel(row, facet).toLowerCase();
133
157
  }
134
158
  function byRecency(a, b) {
@@ -139,26 +163,117 @@ function compare(a, b, sortBy) {
139
163
  if (sortBy === "name") return sessionLabel(a.info).localeCompare(sessionLabel(b.info), void 0, { sensitivity: "base" }) || byRecency(a, b);
140
164
  return facetRank(a, sortBy).localeCompare(facetRank(b, sortBy)) || byRecency(a, b);
141
165
  }
142
- function groupRows(rows, config) {
166
+ function groupRows(rows, config, options = {}) {
143
167
  const sorted = [...rows].sort((a, b) => compare(a, b, config.sortBy));
144
168
  if (config.groupBy === "none") return sorted.length ? [{
145
169
  key: "all",
146
170
  rows: sorted
147
171
  }] : [];
172
+ if (config.groupBy === "custom") return customGroupRows(sorted, config.customGroups ?? []);
148
173
  const facet = config.groupBy;
174
+ const multiGateway = (options.gatewayCount ?? new Set(rows.map((row) => row.hostId)).size) > 1;
149
175
  const groups = /* @__PURE__ */ new Map();
176
+ const ranks = /* @__PURE__ */ new Map();
150
177
  for (const row of sorted) {
151
178
  const key = facetKey(row, facet);
152
179
  const group = groups.get(key);
153
180
  if (group) group.rows.push(row);
154
- else groups.set(key, {
155
- key,
156
- label: facetLabel(row, facet),
157
- rank: facetRank(row, facet),
158
- rows: [row]
159
- });
181
+ else {
182
+ ranks.set(key, facetRank(row, facet, multiGateway));
183
+ groups.set(key, {
184
+ key,
185
+ label: facetLabel(row, facet, multiGateway),
186
+ rows: [row],
187
+ ...facet === "project" ? projectTarget(row) : {},
188
+ ...facet === "project" && multiGateway ? {
189
+ gateway: row.hostName,
190
+ project: projectLabel(row)
191
+ } : {}
192
+ });
193
+ }
160
194
  }
161
- return [...groups.values()].sort((a, b) => a.rank.localeCompare(b.rank));
195
+ return [...groups.values()].sort((a, b) => ranks.get(a.key).localeCompare(ranks.get(b.key)));
196
+ }
197
+ function projectTarget(row) {
198
+ const cwd = row.info.project?.root ?? row.info.cwd;
199
+ return cwd ? {
200
+ hostId: row.hostId,
201
+ cwd
202
+ } : { hostId: row.hostId };
203
+ }
204
+ function customGroupRows(sorted, custom) {
205
+ const byKey = new Map(sorted.map((row) => [sessionKey(row), row]));
206
+ const placed = /* @__PURE__ */ new Set();
207
+ const groups = custom.map((group) => {
208
+ const rows = [];
209
+ for (const member of group.members) {
210
+ const row = byKey.get(member);
211
+ if (row && !placed.has(member)) {
212
+ placed.add(member);
213
+ rows.push(row);
214
+ }
215
+ }
216
+ return {
217
+ key: `custom:${group.id}`,
218
+ label: group.name,
219
+ rows,
220
+ custom: group.id
221
+ };
222
+ });
223
+ const rest = sorted.filter((row) => !placed.has(sessionKey(row)));
224
+ return rest.length ? [...groups, {
225
+ key: UNGROUPED_KEY,
226
+ label: "Ungrouped",
227
+ rows: rest
228
+ }] : groups;
229
+ }
230
+ function newCustomGroupId() {
231
+ return `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
232
+ }
233
+ function addCustomGroup(groups, name, id = newCustomGroupId()) {
234
+ return [...groups, {
235
+ id,
236
+ name,
237
+ members: []
238
+ }];
239
+ }
240
+ function renameCustomGroup(groups, id, name) {
241
+ return groups.map((group) => group.id === id ? {
242
+ ...group,
243
+ name
244
+ } : group);
245
+ }
246
+ function removeCustomGroup(groups, id) {
247
+ return groups.filter((group) => group.id !== id);
248
+ }
249
+ function moveToCustomGroup(groups, key, target, before) {
250
+ return groups.map((group) => {
251
+ const members = group.members.filter((member) => member !== key);
252
+ if (group.id !== target) return members.length === group.members.length ? group : {
253
+ ...group,
254
+ members
255
+ };
256
+ const at = before === void 0 ? -1 : members.indexOf(before);
257
+ return {
258
+ ...group,
259
+ members: at < 0 ? [...members, key] : [
260
+ ...members.slice(0, at),
261
+ key,
262
+ ...members.slice(at)
263
+ ]
264
+ };
265
+ });
266
+ }
267
+ function moveCustomGroup(groups, id, before) {
268
+ const moving = groups.find((group) => group.id === id);
269
+ if (!moving || id === before) return [...groups];
270
+ const rest = groups.filter((group) => group.id !== id);
271
+ const at = before === void 0 ? -1 : rest.findIndex((group) => group.id === before);
272
+ return at < 0 ? [...rest, moving] : [
273
+ ...rest.slice(0, at),
274
+ moving,
275
+ ...rest.slice(at)
276
+ ];
162
277
  }
163
278
  function subsetSummary(config, scope, shown, total) {
164
279
  if (shown >= total) return;
@@ -195,7 +310,8 @@ function clearFilters(config) {
195
310
  sortBy: config.sortBy,
196
311
  subagents: config.subagents,
197
312
  shells: config.shells,
198
- tasks: config.tasks
313
+ tasks: config.tasks,
314
+ customGroups: config.customGroups
199
315
  };
200
316
  }
201
317
  //#endregion
@@ -583,7 +699,7 @@ const PROMPT_SENTENCE_TAIL = /* @__PURE__ */ new Set([
583
699
  ]);
584
700
  const MENTION_BODY = /^[\p{L}\p{N}][\p{L}\p{N}\-_]*$/u;
585
701
  function peerMentionSlug(title, id) {
586
- return (title ?? "").normalize("NFKC").replace(/[^\p{L}\p{N}]+/gu, "-").replace(/^-+|-+$/g, "").slice(0, 64).replace(/^-+|-+$/g, "") || id.slice(0, 8);
702
+ return (title ?? "").normalize("NFKC").replace(/[^\p{L}\p{N}]+/gu, "-").replace(/^-+|-+$/g, "").slice(0, 64).replace(/^-+|-+$/g, "") || id.slice(id.indexOf(":") + 1, id.indexOf(":") + 9);
587
703
  }
588
704
  function peerMentionKey(body) {
589
705
  return body.normalize("NFKC").toLowerCase().replace(/[_\s]+/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
@@ -631,7 +747,9 @@ const BUILTIN_TOOL_TITLES = {
631
747
  peers_send: "Messaging a peer session",
632
748
  mcp__workerdeck__peers_list: "Listing peer sessions",
633
749
  mcp__workerdeck__peers_peek: "Peeking at a peer session",
634
- mcp__workerdeck__peers_send: "Messaging a peer session"
750
+ mcp__workerdeck__peers_send: "Messaging a peer session",
751
+ session_info: "Checking session info",
752
+ mcp__workerdeck__session_info: "Checking session info"
635
753
  };
636
754
  function toolTitle(name, titles) {
637
755
  return sanitizeToolTitle(titles?.[name] ?? BUILTIN_TOOL_TITLES[name], name);
@@ -837,6 +955,8 @@ const ENGINE_CAPABILITIES = {
837
955
  vfs: false,
838
956
  hostCwd: true,
839
957
  systemInstructions: true,
958
+ engineSleep: true,
959
+ backgroundTasks: true,
840
960
  streaming: "token"
841
961
  },
842
962
  codex: {
@@ -873,6 +993,7 @@ const ENGINE_CAPABILITIES = {
873
993
  vfs: false,
874
994
  hostCwd: true,
875
995
  systemInstructions: true,
996
+ engineSleep: true,
876
997
  streaming: "token"
877
998
  },
878
999
  provider: {
@@ -905,6 +1026,7 @@ const ENGINE_CAPABILITIES = {
905
1026
  vfs: true,
906
1027
  hostCwd: false,
907
1028
  systemInstructions: true,
1029
+ engineSleep: false,
908
1030
  streaming: "token"
909
1031
  }
910
1032
  };
@@ -932,7 +1054,8 @@ const CREATE_SESSION_REQUEST_KEYS = Object.keys({
932
1054
  questionBehavior: true,
933
1055
  capabilities: true,
934
1056
  meta: true,
935
- scope: true
1057
+ scope: true,
1058
+ agentContextReset: true
936
1059
  });
937
1060
  function pickCreateSessionRequest(body) {
938
1061
  const picked = {};
@@ -944,6 +1067,10 @@ const CHECKLIST_TEXT_MAX = 200;
944
1067
  function peerDeliveredPrefix(sessionId, name) {
945
1068
  return `Delivered to ${name ? `${name} (${sessionId})` : sessionId}`;
946
1069
  }
1070
+ function peerShortId(sessionId) {
1071
+ const at = sessionId.indexOf(":");
1072
+ return at > 0 ? `${sessionId.slice(0, at)}:${sessionId.slice(at + 1, at + 9)}` : sessionId.slice(0, 8);
1073
+ }
947
1074
  function peerDeliveredTo(text) {
948
1075
  const named = /^Delivered to (.+) \(([^()]+)\);/.exec(text);
949
1076
  if (named) return {
@@ -1017,12 +1144,15 @@ function replayCoalesceKey(body) {
1017
1144
  case "context_compacted": return `context_compacted:${body.uuid}`;
1018
1145
  case "user_message": return body.shell ? `shell:${body.shell.id}` : void 0;
1019
1146
  case "checklist": return "checklist";
1147
+ case "engine_sleep": return "engine_sleep";
1148
+ case "effort_changed": return "effort_changed";
1149
+ case "tool_output": return `tool_output:${body.toolUseId}`;
1020
1150
  case "sdk_event": return body.payload.type === "system" && body.payload.subtype === "status" ? "sdk_event:system:status" : void 0;
1021
1151
  default: return;
1022
1152
  }
1023
1153
  }
1024
1154
  function logCoalesceKey(body) {
1025
- return body.type === "user_message" && body.shell ? replayCoalesceKey(body) : void 0;
1155
+ return body.type === "user_message" && body.shell || body.type === "tool_output" ? replayCoalesceKey(body) : void 0;
1026
1156
  }
1027
1157
  function replayRetains(body) {
1028
1158
  if (body.type !== "stream_delta") return true;
@@ -1031,9 +1161,9 @@ function replayRetains(body) {
1031
1161
  return delta.delta?.type === "text_delta" || delta.delta?.type === "thinking_delta";
1032
1162
  }
1033
1163
  function snapshotRetains(body) {
1034
- return body.type !== "stream_delta";
1164
+ return body.type !== "stream_delta" && body.type !== "tool_output";
1035
1165
  }
1036
1166
  //#endregion
1037
- export { BUILTIN_TOOL_TITLES, CHECKLIST_TEXT_MAX, CREATE_SESSION_REQUEST_KEYS, DEFAULT_PRICING, DEFAULT_VIEW_CONFIG, ENGINE_CAPABILITIES, PEER_MENTION_BODY_MAX, PEER_MENTION_MAX, PEER_MENTION_SCAN_MAX, PEER_MENTION_SIGIL, PEER_SEND_TOOLS, PRICING_AS_OF, PRICING_NOTE, PRICING_SOURCES, PRICING_STALE_DAYS, PROMPT_SENTENCE_TAIL, PROTOCOL_VERSION, SHELL_ARTIFACT_MAX_BYTES, SHELL_ARTIFACT_TTL_MS, SHELL_ATTACH_REPLAY_BYTES, SHELL_COLS, SHELL_COMMAND_MAX, SHELL_CONTEXT_FLUSH_MAX_CHARS, SHELL_CONTEXT_HEAD_CHARS, SHELL_CONTEXT_HEAD_LINES, SHELL_CONTEXT_TAIL_CHARS, SHELL_CONTEXT_TAIL_LINES, SHELL_INLINE_CHARS, SHELL_INLINE_LINES, SHELL_INLINE_LINE_CHARS, SHELL_INPUT_MAX, SHELL_INTERACTIVE_NOTE, SHELL_LABEL_MAX, SHELL_LINGER_MS, SHELL_MAX_COLS, SHELL_MAX_ROWS, SHELL_MAX_RUNNING_PER_SESSION, SHELL_MAX_RUNNING_TOTAL, SHELL_MIN_COLS, SHELL_MIN_ROWS, SHELL_PROMOTE_MS, SHELL_READ_DEFAULT_LINES, SHELL_READ_MAX_LINES, SHELL_ROWS, SHELL_SPILL_BYTES, SHELL_TAIL_FLUSH_MS, SHELL_TAIL_RING_BYTES, SHELL_WAIT_DEFAULT_MS, SHELL_WAIT_MAX_MS, 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, displayCustomized, displayedTasks, emptyTokenUsage, errorMessage, facetFilterCount, filterRows, groupRows, hasFacetFilter, imagePartRef, inScope, isAgentRecord, isJobRun, isPeerMentionBody, isPeerSendTool, logCoalesceKey, mergeByModel, mergePricing, mergeUsage, meteredCost, orderUsageWindows, parseTodoWriteInput, parseUserQuestions, peerDeliveredPrefix, peerDeliveredTo, peerMentionKey, peerMentionSlug, pickCreateSessionRequest, pricingAgeDays, pricingAgeNote, projectKey, projectLabel, projectName, projectSubpath, projectsOf, promotedShells, rateFor, replayCoalesceKey, replayRetains, resolvePosix, runningSubagents, sanitizeToolTitle, scanPeerMentions, scopeActive, sessionLabel, sessionState, sessionTasks, setPricingOverrides, snapshotRetains, subagentLabel, subscriptionComparison, subsetSummary, supportsPermissionMode, taskCountLabel, taskSummary, tokenUsageFromWire, toolTitle, totalTokens, transcriptActivity, transcriptContent, transcriptProse, unknownBasisModels, unpricedModels, unseenCount, usageInfos, usageIsStale, visibleShells, visibleSubagents, visibleTasks, watermarkKey, worseBasis };
1167
+ export { BUILTIN_TOOL_TITLES, CHECKLIST_TEXT_MAX, CREATE_SESSION_REQUEST_KEYS, DEFAULT_PRICING, DEFAULT_VIEW_CONFIG, ENGINE_CAPABILITIES, GROUP_BY, PEER_MENTION_BODY_MAX, PEER_MENTION_MAX, PEER_MENTION_SCAN_MAX, PEER_MENTION_SIGIL, PEER_SEND_TOOLS, PRICING_AS_OF, PRICING_NOTE, PRICING_SOURCES, PRICING_STALE_DAYS, PROMPT_SENTENCE_TAIL, PROTOCOL_VERSION, SHELL_ARTIFACT_MAX_BYTES, SHELL_ARTIFACT_TTL_MS, SHELL_ATTACH_REPLAY_BYTES, SHELL_COLS, SHELL_COMMAND_MAX, SHELL_CONTEXT_FLUSH_MAX_CHARS, SHELL_CONTEXT_HEAD_CHARS, SHELL_CONTEXT_HEAD_LINES, SHELL_CONTEXT_TAIL_CHARS, SHELL_CONTEXT_TAIL_LINES, SHELL_INLINE_CHARS, SHELL_INLINE_LINES, SHELL_INLINE_LINE_CHARS, SHELL_INPUT_MAX, SHELL_INTERACTIVE_NOTE, SHELL_LABEL_MAX, SHELL_LINGER_MS, SHELL_MAX_COLS, SHELL_MAX_ROWS, SHELL_MAX_RUNNING_PER_SESSION, SHELL_MAX_RUNNING_TOTAL, SHELL_MIN_COLS, SHELL_MIN_ROWS, SHELL_PROMOTE_MS, SHELL_READ_DEFAULT_LINES, SHELL_READ_MAX_LINES, SHELL_ROWS, SHELL_SPILL_BYTES, SHELL_TAIL_FLUSH_MS, SHELL_TAIL_RING_BYTES, SHELL_WAIT_DEFAULT_MS, SHELL_WAIT_MAX_MS, STATE_LABELS, STATE_ORDER, SUBAGENT_HISTORY, TOOL_RESULT_HEAD_CHARS, TOOL_TITLE_MAX_CHARS, UNGROUPED_KEY, UNPRICED_WARN_SHARE, USAGE_STALE_AFTER_MS, Watermarks, activePricing, adaptersOf, addCustomGroup, addTokenUsage, byModelTotalTokens, canonicalModel, clearFilters, contextReading, costOf, costOfByModel, displayCustomized, displayedTasks, emptyTokenUsage, errorMessage, facetFilterCount, filterRows, groupRows, hasFacetFilter, imagePartRef, inScope, isAgentRecord, isJobRun, isPeerMentionBody, isPeerSendTool, logCoalesceKey, mergeByModel, mergePricing, mergeUsage, meteredCost, moveCustomGroup, moveToCustomGroup, newCustomGroupId, normalizeViewConfig, orderUsageWindows, parseTodoWriteInput, parseUserQuestions, peerDeliveredPrefix, peerDeliveredTo, peerMentionKey, peerMentionSlug, peerShortId, pickCreateSessionRequest, pricingAgeDays, pricingAgeNote, projectKey, projectLabel, projectName, projectSubpath, projectsOf, promotedShells, rateFor, removeCustomGroup, renameCustomGroup, replayCoalesceKey, replayRetains, resolvePosix, runningSubagents, sanitizeToolTitle, scanPeerMentions, scopeActive, sessionKey, sessionLabel, sessionState, sessionTasks, setPricingOverrides, snapshotRetains, subagentLabel, subscriptionComparison, subsetSummary, supportsPermissionMode, taskCountLabel, taskSummary, tokenUsageFromWire, toolTitle, totalTokens, transcriptActivity, transcriptContent, transcriptProse, unknownBasisModels, unpricedModels, unseenCount, usageInfos, usageIsStale, visibleShells, visibleSubagents, visibleTasks, watermarkKey, worseBasis };
1038
1168
 
1039
1169
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/session-list.ts","../src/checklist.ts","../src/errors.ts","../src/paths.ts","../src/pricing.ts","../src/peer-mentions.ts","../src/tool-titles.ts","../src/usage.ts","../src/watermarks.ts","../src/index.ts"],"sourcesContent":["import { SHELL_LINGER_MS, SHELL_PROMOTE_MS } from './index.ts'\nimport type { SessionInfo, ShellInfo, 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 visibleSubagents(info: SessionInfo, show: SubagentDisplay): SubagentInfo[] {\n if (show === 'none') {\n return []\n }\n const subagents = info.subagents ?? []\n return show === 'all' ? [...subagents] : subagents.filter((sub) => sub.status === 'running')\n}\n\nexport function isAgentRecord(sub: SubagentInfo): boolean {\n return sub.isAgent === true || (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\n// How much of one of a card's child lists it draws. A layout preference, not a facet filter.\nexport type StepDisplay = 'all' | 'active' | 'none'\n\nexport type SubagentDisplay = StepDisplay\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 subagents: SubagentDisplay\n shells?: StepDisplay\n tasks?: StepDisplay\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 subagents: 'active',\n shells: 'active',\n tasks: 'active',\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\nexport function promotedShells(info: SessionInfo, now: number): ShellInfo[] {\n return (info.shells ?? []).filter((shell) => {\n if (shell.status === 'running') {\n return now - shell.startedAt >= SHELL_PROMOTE_MS\n }\n // A *reported* non-zero exit, not merely \"no zero\": a killed shell and one reconciled from a restart carry no\n // exitCode at all, and `!== 0` kept both on the card for a minute drawn as failures. The linger exists for the\n // dev server that died on its own, which is the only case the operator has not already been told about.\n if (shell.endedAt === undefined || typeof shell.exitCode !== 'number' || shell.exitCode === 0) {\n return false\n }\n return shell.endedAt - shell.startedAt >= SHELL_PROMOTE_MS && now - shell.endedAt < SHELL_LINGER_MS\n })\n}\n\nexport function visibleShells(info: SessionInfo, show: StepDisplay, now: number): ShellInfo[] {\n if (show === 'none') {\n return []\n }\n const shells = (info.shells ?? []).filter((shell) => shell.status !== 'running' || now - shell.startedAt >= SHELL_PROMOTE_MS)\n return show === 'active' ? shells.filter((shell) => shell.status === 'running') : shells\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 facetFilterCount(config: ViewConfig): number {\n return [config.gateways, config.adapters, config.states, config.projects ?? []].filter((facet) => facet.length > 0).length\n}\n\nexport function displayCustomized(config: ViewConfig): boolean {\n return (\n config.subagents !== DEFAULT_VIEW_CONFIG.subagents ||\n (config.shells ?? DEFAULT_VIEW_CONFIG.shells) !== DEFAULT_VIEW_CONFIG.shells ||\n (config.tasks ?? DEFAULT_VIEW_CONFIG.tasks) !== DEFAULT_VIEW_CONFIG.tasks\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 subagents: config.subagents,\n shells: config.shells,\n tasks: config.tasks,\n }\n}\n","import type { ChecklistItem, ChecklistStatus, SessionInfo } from './index.ts'\nimport { isAgentRecord } from './session-list.ts'\nimport type { StepDisplay } 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 stoppable?: boolean\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 stoppable: sub.status === 'running' && sub.stoppable === true ? true : undefined,\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\nexport function displayedTasks(info: Pick<SessionInfo, 'checklist' | 'subagents'>, show: StepDisplay): SessionTask[] {\n if (show === 'none') {\n return []\n }\n const tasks = sessionTasks(info)\n return show === 'all' ? tasks : tasks.filter((task) => task.state === 'running' || task.state === 'pending')\n}\n","export function errorMessage(error: unknown, fallback?: string): string {\n if (error instanceof Error) {\n return error.message\n }\n return fallback ?? String(error)\n}\n","export function resolvePosix(target: string, cwd: string | undefined): string | undefined {\n if (target.startsWith('/')) {\n return normalizePosix(target)\n }\n return cwd ? normalizePosix(`${cwd}/${target}`) : undefined\n}\n\nfunction normalizePosix(path: string): string {\n const out: string[] = []\n for (const part of path.split('/')) {\n if (part === '' || part === '.') {\n continue\n }\n if (part === '..') {\n out.pop()\n } else {\n out.push(part)\n }\n }\n return `/${out.join('/')}`\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-29'\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-5': anthropicRate(4, 20, 0.2),\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-5': anthropicRate(2, 10),\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-6-sol': openaiRate(2, 10, 0.2),\n 'gpt-6-luna': openaiRate(0.1, 0.5, 0.01),\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/** @deprecated Mutates a process-wide table that every caller naming no table reads. Merge with `mergePricing` and pass the table explicitly. */\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","// `#Name` in a composer names another session on the gateway. The client writes the token, the\n// gateway resolves it, and the two must fold a title the same way or a picked name would not match\n// itself. Everything here is pure, so the same rule runs in a browser, in a webview and on a server.\n\nexport const PEER_MENTION_SIGIL = '#'\n\n// Distinct sessions expanded per message. Four is past any real sentence, and keeps the block a\n// short prompt carries from outweighing the prompt.\nexport const PEER_MENTION_MAX = 4\n\nexport const PEER_MENTION_BODY_MAX = 64\n\n// A scan bound, not a policy: a pasted file of hashes must not cost a resolution pass per line.\nexport const PEER_MENTION_SCAN_MAX = 32\n\nexport type PeerMentionToken = { start: number; end: number; body: string }\n\n// Trailing punctuation belongs to the sentence, not to the name. Shared with `scanPromptTokens`,\n// which scans the same text for `@file` and `/command`, so one boundary answers for all of them.\nexport const PROMPT_SENTENCE_TAIL: ReadonlySet<string> = new Set(['.', ',', ';', ':', '!', '?', ')', ']', '}', '\"', \"'\"])\n\nconst MENTION_BODY = /^[\\p{L}\\p{N}][\\p{L}\\p{N}\\-_]*$/u\n\n// What the composer writes for a session, and the only spelling the resolver is guaranteed to\n// match. An untitled session falls back to the short id `sessionLabel` already draws.\nexport function peerMentionSlug(title: string | undefined, id: string): string {\n const slug = (title ?? '')\n .normalize('NFKC')\n .replace(/[^\\p{L}\\p{N}]+/gu, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, PEER_MENTION_BODY_MAX)\n .replace(/^-+|-+$/g, '')\n return slug || id.slice(0, 8)\n}\n\n// The comparison key. Both sides fold; neither compares raw, so `#astra` finds `Astra` and\n// `#fix_login_bug` finds `Fix login bug`.\nexport function peerMentionKey(body: string): string {\n return body\n .normalize('NFKC')\n .toLowerCase()\n .replace(/[_\\s]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '')\n}\n\nexport function isPeerMentionBody(body: string): boolean {\n return body.length > 0 && body.length <= PEER_MENTION_BODY_MAX && MENTION_BODY.test(body)\n}\n\n// The boundary rule, mirroring `scanPromptTokens`: a sigil at the start of a word, a body to the\n// next whitespace, sentence punctuation peeled off the end. `# heading` and `issue#42` are not\n// mentions, and neither is `#-x`.\nexport function scanPeerMentions(text: string): PeerMentionToken[] {\n const tokens: PeerMentionToken[] = []\n const words = /\\S+/g\n let match: RegExpExecArray | null\n while ((match = words.exec(text)) !== null && tokens.length < PEER_MENTION_SCAN_MAX) {\n if (match[0][0] !== PEER_MENTION_SIGIL) {\n continue\n }\n let end = match.index + match[0].length\n while (end > match.index && PROMPT_SENTENCE_TAIL.has(text[end - 1]!)) {\n end--\n }\n const body = text.slice(match.index + 1, end)\n if (!isPeerMentionBody(body)) {\n continue\n }\n tokens.push({ start: match.index, end, body })\n }\n return tokens\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 // Optional because a mark persisted before prose counting has none; `unseenCount` reads that as caught up.\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 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\nexport function unseenCount(mark: Watermark | undefined, info: { proseCount?: number }): number {\n if (!mark || info.proseCount === undefined) {\n return 0\n }\n return Math.max(0, info.proseCount - (mark.prose ?? info.proseCount))\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 shell?: ShellInfo\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 ShellOwner = 'user' | 'agent'\nexport type ShellStatus = 'running' | 'exited'\nexport type ShellEndReason = 'exit' | 'killed' | 'timeout' | 'server_stopped' | 'server_restarted' | 'spawn_failed'\n\nexport type ShellInfo = {\n id: string\n sessionId: string\n ordinal: number\n command: string\n label: string\n cwd: string\n owner: ShellOwner\n status: ShellStatus\n startedAt: number\n endedAt?: number\n exitCode?: number\n signal?: number\n endReason?: ShellEndReason\n bytes: number\n capped?: boolean\n cols: number\n rows: number\n agentWrite?: boolean\n interactive?: boolean\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: 'shell_attach'; shellId: string; cols: number; rows: number }\n | { type: 'shell_input'; shellId: string; data: string }\n | { type: 'shell_resize'; shellId: string; cols: number; rows: number }\n | { type: 'shell_detach'; shellId: string }\n | { type: 'close' }\n\nexport const SHELL_COMMAND_MAX = 4000\nexport const SHELL_COLS = 120\nexport const SHELL_ROWS = 40\nexport const SHELL_MIN_COLS = 1\nexport const SHELL_MAX_COLS = 1000\nexport const SHELL_MIN_ROWS = 1\nexport const SHELL_MAX_ROWS = 500\nexport const SHELL_INPUT_MAX = 4096\nexport const SHELL_LABEL_MAX = 80\nexport const SHELL_INLINE_LINES = 8\nexport const SHELL_INTERACTIVE_NOTE = 'interactive output, no preview'\nexport const SHELL_INLINE_LINE_CHARS = 512\nexport const SHELL_INLINE_CHARS = 2048\nexport const SHELL_PROMOTE_MS = 3000\nexport const SHELL_LINGER_MS = 60_000\nexport const SHELL_MAX_RUNNING_PER_SESSION = 8\nexport const SHELL_MAX_RUNNING_TOTAL = 32\nexport const SHELL_SPILL_BYTES = 64 * 1024\nexport const SHELL_TAIL_RING_BYTES = 64 * 1024\nexport const SHELL_TAIL_FLUSH_MS = 5000\nexport const SHELL_ARTIFACT_MAX_BYTES = 16 * 1024 * 1024\nexport const SHELL_ARTIFACT_TTL_MS = 7 * 24 * 60 * 60 * 1000\nexport const SHELL_ATTACH_REPLAY_BYTES = 256 * 1024\nexport const SHELL_CONTEXT_HEAD_LINES = 40\nexport const SHELL_CONTEXT_HEAD_CHARS = 4096\nexport const SHELL_CONTEXT_TAIL_LINES = 80\nexport const SHELL_CONTEXT_TAIL_CHARS = 12288\nexport const SHELL_CONTEXT_FLUSH_MAX_CHARS = 49152\nexport const SHELL_READ_DEFAULT_LINES = 200\nexport const SHELL_READ_MAX_LINES = 2000\nexport const SHELL_WAIT_DEFAULT_MS = 30_000\nexport const SHELL_WAIT_MAX_MS = 120_000\n\nexport type AttachedFrame = {\n type: 'attached'\n protocolVersion: number\n session: SessionInfo\n replayingFrom: number\n // Whether this principal may run `$` shell 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: 'shell_attached'; shellId: string; shell: ShellInfo; cols: number; rows: number; scrollback: string }\n | { type: 'shell_output'; shellId: string; data: string }\n | { type: 'shell_detached'; shellId: 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 forkSession?: 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 systemInstructions?: 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 forkSession: 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 systemInstructions: 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 forkSession: false,\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 systemInstructions: 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 forkSession: 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 systemInstructions: true,\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\n// Typed as a record over the request's keys so a field added above without an entry here, or an entry left behind\n// after a field is removed, fails typecheck: this list is what the gateway projects an untrusted body through.\nconst CREATE_SESSION_REQUEST_KEY_SET: Record<keyof CreateSessionRequest, true> = {\n cwd: true,\n profile: true,\n prompt: true,\n permissionMode: true,\n allowDangerouslySkipPermissions: true,\n allowedTools: true,\n disallowedTools: true,\n mcpServers: true,\n settingSources: true,\n model: true,\n maxTurns: true,\n maxBudgetUsd: true,\n resume: true,\n forkSession: true,\n reasoningEffort: true,\n includePartialMessages: true,\n approvalTimeoutMs: true,\n questionBehavior: true,\n capabilities: true,\n meta: true,\n scope: true,\n}\n\nexport const CREATE_SESSION_REQUEST_KEYS = Object.keys(CREATE_SESSION_REQUEST_KEY_SET) as ReadonlyArray<keyof CreateSessionRequest>\n\nexport function pickCreateSessionRequest(body: Record<string, unknown>): CreateSessionRequest {\n const picked: Record<string, unknown> = {}\n for (const key of CREATE_SESSION_REQUEST_KEYS) {\n if (body[key] !== undefined) {\n picked[key] = body[key]\n }\n }\n return picked as CreateSessionRequest\n}\n\nexport type SubagentInfo = {\n toolUseId: string\n agentType?: string\n description?: string\n // Set by an engine whose every record is a delegated agent, however it was named. Codex runs\n // each one as its own thread and often has no name for it, so presence of `agentType` cannot\n // be the test. Additive, so no `PROTOCOL_VERSION` bump.\n isAgent?: boolean\n status: 'running' | 'done' | 'failed'\n startedAt: number\n toolCount: number\n // The engine can stop this record's background task on request (`POST .../tasks/:toolUseId/stop`).\n stoppable?: boolean\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`. This is the badge's number;\n // `activityCount` stays the \"has 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 shells?: ShellInfo[]\n // Present when the agent holds the shell write tools, so a client offers the operator's grant only where it can bite.\n shellAgentWrite?: 'gated' | 'allow'\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 'user_message': {\n return body.shell ? `shell:${body.shell.id}` : undefined\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 logCoalesceKey(body: SessionEventBody): string | undefined {\n return body.type === 'user_message' && body.shell ? replayCoalesceKey(body) : undefined\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\n// A gateway's answer to \"which machine am I?\". `machineId` is an opaque fingerprint of the host\n// the gateway process runs on, not an identity or a secret: a client that computes the same\n// fingerprint for itself knows the gateway's paths are its own paths, and can open them natively\n// instead of proxying them over `/fs`. Optional, so a gateway that predates it just stays remote.\nexport type GatewayMeta = {\n protocolVersion: number\n machineId?: string\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 './errors.ts'\nexport * from './paths.ts'\nexport * from './pricing.ts'\nexport * from './peer-mentions.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/errors.ts","../src/paths.ts","../src/pricing.ts","../src/peer-mentions.ts","../src/tool-titles.ts","../src/usage.ts","../src/watermarks.ts","../src/index.ts"],"sourcesContent":["import { SHELL_LINGER_MS, SHELL_PROMOTE_MS } from './index.ts'\nimport type { SessionInfo, ShellInfo, 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 visibleSubagents(info: SessionInfo, show: SubagentDisplay): SubagentInfo[] {\n if (show === 'none') {\n return []\n }\n const subagents = info.subagents ?? []\n return show === 'all' ? [...subagents] : subagents.filter((sub) => sub.status === 'running')\n}\n\nexport function isAgentRecord(sub: SubagentInfo): boolean {\n return sub.isAgent === true || (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' | 'state' | 'adapter' | 'project' | 'custom'\nexport type SortBy = 'recent' | 'name' | Facet\n\nexport const GROUP_BY: readonly GroupBy[] = ['none', 'state', 'adapter', 'project', 'custom']\n\n// `members` are `sessionKey` values, in the order the group draws them.\nexport type CustomGroup = { id: string; name: string; members: string[] }\n\n// How much of one of a card's child lists it draws. A layout preference, not a facet filter.\nexport type StepDisplay = 'all' | 'active' | 'none'\n\nexport type SubagentDisplay = StepDisplay\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 subagents: SubagentDisplay\n shells?: StepDisplay\n tasks?: StepDisplay\n customGroups?: CustomGroup[]\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 subagents: 'active',\n shells: 'active',\n tasks: 'active',\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 = {\n key: string\n label?: string\n // Set on a project group once there is more than one gateway: `label` split into its two parts.\n gateway?: string\n project?: string\n rows: SessionRow[]\n // Set on a project group: where a session started from its header runs.\n hostId?: string\n cwd?: string\n // Set on a custom group; the ungrouped bucket has neither this nor a place in `customGroups`.\n custom?: string\n}\n\nexport type GroupOptions = { gatewayCount?: number }\n\nexport const UNGROUPED_KEY = 'custom:ungrouped'\n\nexport function sessionKey(row: Pick<SessionRow, 'hostId' | 'info'>): string {\n return `${row.hostId}:${row.info.id}`\n}\n\n// A stored `groupBy: 'gateway'` predates the merge into project groups, which name their gateway once there is more than one.\nexport function normalizeViewConfig(stored: Partial<ViewConfig> | undefined): ViewConfig {\n const config = { ...DEFAULT_VIEW_CONFIG, ...stored }\n const groupBy = config.groupBy as string\n return GROUP_BY.includes(groupBy as GroupBy)\n ? config\n : { ...config, groupBy: groupBy === 'gateway' ? 'project' : DEFAULT_VIEW_CONFIG.groupBy }\n}\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\nexport function promotedShells(info: SessionInfo, now: number): ShellInfo[] {\n return (info.shells ?? []).filter((shell) => {\n if (shell.status === 'running') {\n return now - shell.startedAt >= SHELL_PROMOTE_MS\n }\n // A *reported* non-zero exit, not merely \"no zero\": a killed shell and one reconciled from a restart carry no\n // exitCode at all, and `!== 0` kept both on the card for a minute drawn as failures. The linger exists for the\n // dev server that died on its own, which is the only case the operator has not already been told about.\n if (shell.endedAt === undefined || typeof shell.exitCode !== 'number' || shell.exitCode === 0) {\n return false\n }\n return shell.endedAt - shell.startedAt >= SHELL_PROMOTE_MS && now - shell.endedAt < SHELL_LINGER_MS\n })\n}\n\nexport function visibleShells(info: SessionInfo, show: StepDisplay, now: number): ShellInfo[] {\n if (show === 'none') {\n return []\n }\n const shells = (info.shells ?? []).filter((shell) => shell.status !== 'running' || now - shell.startedAt >= SHELL_PROMOTE_MS)\n return show === 'active' ? shells.filter((shell) => shell.status === 'running') : shells\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, multiGateway = false): string {\n if (facet === 'project') {\n return multiGateway ? `${row.hostName} ${projectLabel(row)}` : projectLabel(row)\n }\n return facet === 'gateway' ? row.hostName : facet === 'adapter' ? row.adapter : STATE_LABELS[row.state]\n}\n\nfunction facetRank(row: SessionRow, facet: Facet, multiGateway = false): string {\n if (facet === 'state') {\n return String(STATE_ORDER.indexOf(row.state))\n }\n if (facet === 'project' && multiGateway) {\n return `${row.hostName.toLowerCase()}\\u0000${projectLabel(row).toLowerCase()}`\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\n// `gatewayCount` defaults to the gateways among `rows`; a host passing filtered rows passes the unfiltered count, so a\n// filter never renames a project heading.\nexport function groupRows(rows: readonly SessionRow[], config: ViewConfig, options: GroupOptions = {}): 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 if (config.groupBy === 'custom') {\n return customGroupRows(sorted, config.customGroups ?? [])\n }\n const facet = config.groupBy\n const multiGateway = (options.gatewayCount ?? new Set(rows.map((row) => row.hostId)).size) > 1\n const groups = new Map<string, SessionGroup>()\n const ranks = new Map<string, 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 ranks.set(key, facetRank(row, facet, multiGateway))\n groups.set(key, {\n key,\n label: facetLabel(row, facet, multiGateway),\n rows: [row],\n ...(facet === 'project' ? projectTarget(row) : {}),\n ...(facet === 'project' && multiGateway ? { gateway: row.hostName, project: projectLabel(row) } : {}),\n })\n }\n }\n return [...groups.values()].sort((a, b) => ranks.get(a.key)!.localeCompare(ranks.get(b.key)!))\n}\n\nfunction projectTarget(row: SessionRow): { hostId: string; cwd?: string } {\n const cwd = row.info.project?.root ?? row.info.cwd\n return cwd ? { hostId: row.hostId, cwd } : { hostId: row.hostId }\n}\n\n// Custom groups keep their stored order, rows in member order; a session belongs to the first group listing it.\nfunction customGroupRows(sorted: readonly SessionRow[], custom: readonly CustomGroup[]): SessionGroup[] {\n const byKey = new Map(sorted.map((row) => [sessionKey(row), row]))\n const placed = new Set<string>()\n const groups: SessionGroup[] = custom.map((group) => {\n const rows: SessionRow[] = []\n for (const member of group.members) {\n const row = byKey.get(member)\n if (row && !placed.has(member)) {\n placed.add(member)\n rows.push(row)\n }\n }\n return { key: `custom:${group.id}`, label: group.name, rows, custom: group.id }\n })\n const rest = sorted.filter((row) => !placed.has(sessionKey(row)))\n return rest.length ? [...groups, { key: UNGROUPED_KEY, label: 'Ungrouped', rows: rest }] : groups\n}\n\nexport function newCustomGroupId(): string {\n return `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`\n}\n\nexport function addCustomGroup(groups: readonly CustomGroup[], name: string, id = newCustomGroupId()): CustomGroup[] {\n return [...groups, { id, name, members: [] }]\n}\n\nexport function renameCustomGroup(groups: readonly CustomGroup[], id: string, name: string): CustomGroup[] {\n return groups.map((group) => (group.id === id ? { ...group, name } : group))\n}\n\nexport function removeCustomGroup(groups: readonly CustomGroup[], id: string): CustomGroup[] {\n return groups.filter((group) => group.id !== id)\n}\n\n// `target` undefined moves the session to the ungrouped bucket; `before` is the member it lands above, else it appends.\nexport function moveToCustomGroup(groups: readonly CustomGroup[], key: string, target: string | undefined, before?: string): CustomGroup[] {\n return groups.map((group) => {\n const members = group.members.filter((member) => member !== key)\n if (group.id !== target) {\n return members.length === group.members.length ? group : { ...group, members }\n }\n const at = before === undefined ? -1 : members.indexOf(before)\n return { ...group, members: at < 0 ? [...members, key] : [...members.slice(0, at), key, ...members.slice(at)] }\n })\n}\n\nexport function moveCustomGroup(groups: readonly CustomGroup[], id: string, before: string | undefined): CustomGroup[] {\n const moving = groups.find((group) => group.id === id)\n if (!moving || id === before) {\n return [...groups]\n }\n const rest = groups.filter((group) => group.id !== id)\n const at = before === undefined ? -1 : rest.findIndex((group) => group.id === before)\n return at < 0 ? [...rest, moving] : [...rest.slice(0, at), moving, ...rest.slice(at)]\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 facetFilterCount(config: ViewConfig): number {\n return [config.gateways, config.adapters, config.states, config.projects ?? []].filter((facet) => facet.length > 0).length\n}\n\nexport function displayCustomized(config: ViewConfig): boolean {\n return (\n config.subagents !== DEFAULT_VIEW_CONFIG.subagents ||\n (config.shells ?? DEFAULT_VIEW_CONFIG.shells) !== DEFAULT_VIEW_CONFIG.shells ||\n (config.tasks ?? DEFAULT_VIEW_CONFIG.tasks) !== DEFAULT_VIEW_CONFIG.tasks\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 subagents: config.subagents,\n shells: config.shells,\n tasks: config.tasks,\n customGroups: config.customGroups,\n }\n}\n","import type { ChecklistItem, ChecklistStatus, SessionInfo } from './index.ts'\nimport { isAgentRecord } from './session-list.ts'\nimport type { StepDisplay } 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 stoppable?: boolean\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 stoppable: sub.status === 'running' && sub.stoppable === true ? true : undefined,\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\nexport function displayedTasks(info: Pick<SessionInfo, 'checklist' | 'subagents'>, show: StepDisplay): SessionTask[] {\n if (show === 'none') {\n return []\n }\n const tasks = sessionTasks(info)\n return show === 'all' ? tasks : tasks.filter((task) => task.state === 'running' || task.state === 'pending')\n}\n","export function errorMessage(error: unknown, fallback?: string): string {\n if (error instanceof Error) {\n return error.message\n }\n return fallback ?? String(error)\n}\n","export function resolvePosix(target: string, cwd: string | undefined): string | undefined {\n if (target.startsWith('/')) {\n return normalizePosix(target)\n }\n return cwd ? normalizePosix(`${cwd}/${target}`) : undefined\n}\n\nfunction normalizePosix(path: string): string {\n const out: string[] = []\n for (const part of path.split('/')) {\n if (part === '' || part === '.') {\n continue\n }\n if (part === '..') {\n out.pop()\n } else {\n out.push(part)\n }\n }\n return `/${out.join('/')}`\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-29'\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-5': anthropicRate(4, 20, 0.2),\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-5': anthropicRate(2, 10),\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-6-sol': openaiRate(2, 10, 0.2),\n 'gpt-6-luna': openaiRate(0.1, 0.5, 0.01),\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/** @deprecated Mutates a process-wide table that every caller naming no table reads. Merge with `mergePricing` and pass the table explicitly. */\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","import type { ContextReading, ProfileEngine, SessionStatus } from './index.ts'\n\n// `#Name` in a composer names another session on the gateway. The client writes the token, the\n// gateway resolves it, and the two must fold a title the same way or a picked name would not match\n// itself. Everything here is pure, so the same rule runs in a browser, in a webview and on a server.\n\nexport const PEER_MENTION_SIGIL = '#'\n\n// Distinct sessions expanded per message. Four is past any real sentence, and keeps the block a\n// short prompt carries from outweighing the prompt.\nexport const PEER_MENTION_MAX = 4\n\nexport const PEER_MENTION_BODY_MAX = 64\n\n// A scan bound, not a policy: a pasted file of hashes must not cost a resolution pass per line.\nexport const PEER_MENTION_SCAN_MAX = 32\n\nexport type PeerMentionToken = { start: number; end: number; body: string }\n\n// A session another session may address. `gateway` is set, and `id` is `gateway:session`, for a\n// session reached through a relay; `allow` says what that relay permits.\nexport type PeerSessionSummary = {\n id: string\n gateway?: string\n engine?: ProfileEngine\n status: SessionStatus\n title?: string\n project?: string\n projectRoot?: string\n cwd: string\n profile?: string\n model?: string\n contextUsage?: ContextReading\n lastActivityAt?: number\n pendingPermissionCount: number\n allow?: Array<'send' | 'peek'>\n}\n\nexport type PeerSessionsResponse = { peers: PeerSessionSummary[] }\n\n// Trailing punctuation belongs to the sentence, not to the name. Shared with `scanPromptTokens`,\n// which scans the same text for `@file` and `/command`, so one boundary answers for all of them.\nexport const PROMPT_SENTENCE_TAIL: ReadonlySet<string> = new Set(['.', ',', ';', ':', '!', '?', ')', ']', '}', '\"', \"'\"])\n\nconst MENTION_BODY = /^[\\p{L}\\p{N}][\\p{L}\\p{N}\\-_]*$/u\n\n// What the composer writes for a session, and the only spelling the resolver is guaranteed to\n// match. An untitled session falls back to the short id `sessionLabel` already draws.\nexport function peerMentionSlug(title: string | undefined, id: string): string {\n const slug = (title ?? '')\n .normalize('NFKC')\n .replace(/[^\\p{L}\\p{N}]+/gu, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, PEER_MENTION_BODY_MAX)\n .replace(/^-+|-+$/g, '')\n return slug || id.slice(id.indexOf(':') + 1, id.indexOf(':') + 9)\n}\n\n// The comparison key. Both sides fold; neither compares raw, so `#astra` finds `Astra` and\n// `#fix_login_bug` finds `Fix login bug`.\nexport function peerMentionKey(body: string): string {\n return body\n .normalize('NFKC')\n .toLowerCase()\n .replace(/[_\\s]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '')\n}\n\nexport function isPeerMentionBody(body: string): boolean {\n return body.length > 0 && body.length <= PEER_MENTION_BODY_MAX && MENTION_BODY.test(body)\n}\n\n// The boundary rule, mirroring `scanPromptTokens`: a sigil at the start of a word, a body to the\n// next whitespace, sentence punctuation peeled off the end. `# heading` and `issue#42` are not\n// mentions, and neither is `#-x`.\nexport function scanPeerMentions(text: string): PeerMentionToken[] {\n const tokens: PeerMentionToken[] = []\n const words = /\\S+/g\n let match: RegExpExecArray | null\n while ((match = words.exec(text)) !== null && tokens.length < PEER_MENTION_SCAN_MAX) {\n if (match[0][0] !== PEER_MENTION_SIGIL) {\n continue\n }\n let end = match.index + match[0].length\n while (end > match.index && PROMPT_SENTENCE_TAIL.has(text[end - 1]!)) {\n end--\n }\n const body = text.slice(match.index + 1, end)\n if (!isPeerMentionBody(body)) {\n continue\n }\n tokens.push({ start: match.index, end, body })\n }\n return tokens\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 session_info: 'Checking session info',\n mcp__workerdeck__session_info: 'Checking session info',\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 // Optional because a mark persisted before prose counting has none; `unseenCount` reads that as caught up.\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 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\nexport function unseenCount(mark: Watermark | undefined, info: { proseCount?: number }): number {\n if (!mark || info.proseCount === undefined) {\n return 0\n }\n return Math.max(0, info.proseCount - (mark.prose ?? info.proseCount))\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: 'effort_changed'; effort: string | null }\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 | { type: 'engine_sleep'; asleep: boolean }\n | {\n type: 'conversation_reset'\n sdkSessionId?: string\n // Present when the session's own agent asked for the reset through `context_reset`.\n agentReason?: 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 shell?: ShellInfo\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: 'tool_output'; toolUseId: string; tail: 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 ShellOwner = 'user' | 'agent'\nexport type ShellStatus = 'running' | 'exited'\nexport type ShellEndReason = 'exit' | 'killed' | 'timeout' | 'server_stopped' | 'server_restarted' | 'spawn_failed'\n\nexport type ShellInfo = {\n id: string\n sessionId: string\n ordinal: number\n command: string\n label: string\n cwd: string\n owner: ShellOwner\n status: ShellStatus\n startedAt: number\n endedAt?: number\n exitCode?: number\n signal?: number\n endReason?: ShellEndReason\n bytes: number\n capped?: boolean\n cols: number\n rows: number\n agentWrite?: boolean\n interactive?: boolean\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: 'sleep' }\n | { type: 'background_task'; toolUseId?: string }\n | { type: 'set_permission_mode'; mode: PermissionMode }\n | { type: 'set_model'; model?: string }\n | { type: 'set_effort'; effort?: 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: 'shell_attach'; shellId: string; cols: number; rows: number }\n | { type: 'shell_input'; shellId: string; data: string }\n | { type: 'shell_resize'; shellId: string; cols: number; rows: number }\n | { type: 'shell_detach'; shellId: string }\n | { type: 'close' }\n\nexport const SHELL_COMMAND_MAX = 4000\nexport const SHELL_COLS = 120\nexport const SHELL_ROWS = 40\nexport const SHELL_MIN_COLS = 1\nexport const SHELL_MAX_COLS = 1000\nexport const SHELL_MIN_ROWS = 1\nexport const SHELL_MAX_ROWS = 500\nexport const SHELL_INPUT_MAX = 4096\nexport const SHELL_LABEL_MAX = 80\nexport const SHELL_INLINE_LINES = 8\nexport const SHELL_INTERACTIVE_NOTE = 'interactive output, no preview'\nexport const SHELL_INLINE_LINE_CHARS = 512\nexport const SHELL_INLINE_CHARS = 2048\nexport const SHELL_PROMOTE_MS = 3000\nexport const SHELL_LINGER_MS = 60_000\nexport const SHELL_MAX_RUNNING_PER_SESSION = 8\nexport const SHELL_MAX_RUNNING_TOTAL = 32\nexport const SHELL_SPILL_BYTES = 64 * 1024\nexport const SHELL_TAIL_RING_BYTES = 64 * 1024\nexport const SHELL_TAIL_FLUSH_MS = 5000\nexport const SHELL_ARTIFACT_MAX_BYTES = 16 * 1024 * 1024\nexport const SHELL_ARTIFACT_TTL_MS = 7 * 24 * 60 * 60 * 1000\nexport const SHELL_ATTACH_REPLAY_BYTES = 256 * 1024\nexport const SHELL_CONTEXT_HEAD_LINES = 40\nexport const SHELL_CONTEXT_HEAD_CHARS = 4096\nexport const SHELL_CONTEXT_TAIL_LINES = 80\nexport const SHELL_CONTEXT_TAIL_CHARS = 12288\nexport const SHELL_CONTEXT_FLUSH_MAX_CHARS = 49152\nexport const SHELL_READ_DEFAULT_LINES = 200\nexport const SHELL_READ_MAX_LINES = 2000\nexport const SHELL_WAIT_DEFAULT_MS = 30_000\nexport const SHELL_WAIT_MAX_MS = 120_000\n\nexport type AttachedFrame = {\n type: 'attached'\n protocolVersion: number\n session: SessionInfo\n replayingFrom: number\n // Whether this principal may run `$` shell 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: 'shell_attached'; shellId: string; shell: ShellInfo; cols: number; rows: number; scrollback: string }\n | { type: 'shell_output'; shellId: string; data: string }\n | { type: 'shell_detached'; shellId: 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 efforts?: Record<string, string>\n agentContextReset?: boolean\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 forkSession?: 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 systemInstructions?: boolean\n engineSleep?: boolean\n backgroundTasks?: 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 forkSession: 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 systemInstructions: true,\n engineSleep: true,\n backgroundTasks: 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 forkSession: false,\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 systemInstructions: true,\n engineSleep: 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 forkSession: 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 systemInstructions: true,\n engineSleep: 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 ProviderContextWindow = number | Record<string, number>\n\nexport type ProviderConfig = {\n id: string\n model?: string\n models?: string[]\n baseUrl?: string\n apiKeyEnv?: string\n contextWindow?: ProviderContextWindow\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 agentContextReset?: boolean\n}\n\n// Typed as a record over the request's keys so a field added above without an entry here, or an entry left behind\n// after a field is removed, fails typecheck: this list is what the gateway projects an untrusted body through.\nconst CREATE_SESSION_REQUEST_KEY_SET: Record<keyof CreateSessionRequest, true> = {\n cwd: true,\n profile: true,\n prompt: true,\n permissionMode: true,\n allowDangerouslySkipPermissions: true,\n allowedTools: true,\n disallowedTools: true,\n mcpServers: true,\n settingSources: true,\n model: true,\n maxTurns: true,\n maxBudgetUsd: true,\n resume: true,\n forkSession: true,\n reasoningEffort: true,\n includePartialMessages: true,\n approvalTimeoutMs: true,\n questionBehavior: true,\n capabilities: true,\n meta: true,\n scope: true,\n agentContextReset: true,\n}\n\nexport const CREATE_SESSION_REQUEST_KEYS = Object.keys(CREATE_SESSION_REQUEST_KEY_SET) as ReadonlyArray<keyof CreateSessionRequest>\n\nexport function pickCreateSessionRequest(body: Record<string, unknown>): CreateSessionRequest {\n const picked: Record<string, unknown> = {}\n for (const key of CREATE_SESSION_REQUEST_KEYS) {\n if (body[key] !== undefined) {\n picked[key] = body[key]\n }\n }\n return picked as CreateSessionRequest\n}\n\nexport type SubagentInfo = {\n toolUseId: string\n agentType?: string\n description?: string\n // Set by an engine whose every record is a delegated agent, however it was named. Codex runs\n // each one as its own thread and often has no name for it, so presence of `agentType` cannot\n // be the test. Additive, so no `PROTOCOL_VERSION` bump.\n isAgent?: boolean\n status: 'running' | 'done' | 'failed'\n startedAt: number\n toolCount: number\n // The engine can stop this record's background task on request (`POST .../tasks/:toolUseId/stop`).\n stoppable?: boolean\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\n// A remote peer's id is `gateway:session`; the short form keeps the gateway whole and clips the session.\nexport function peerShortId(sessionId: string): string {\n const at = sessionId.indexOf(':')\n return at > 0 ? `${sessionId.slice(0, at)}:${sessionId.slice(at + 1, at + 9)}` : sessionId.slice(0, 8)\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 effort?: string | null\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`. This is the badge's number;\n // `activityCount` stays the \"has 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 shells?: ShellInfo[]\n // Present when the agent holds the shell write tools, so a client offers the operator's grant only where it can bite.\n shellAgentWrite?: 'gated' | 'allow'\n // The engine child is stopped while the session stays live and listed; the next message resumes it.\n engineAsleep?: true\n // The agent holds `context_reset` and may clear its own conversation between turns.\n agentContextReset?: true\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 'user_message': {\n return body.shell ? `shell:${body.shell.id}` : undefined\n }\n case 'checklist': {\n return 'checklist'\n }\n case 'engine_sleep': {\n return 'engine_sleep'\n }\n case 'effort_changed': {\n return 'effort_changed'\n }\n case 'tool_output': {\n return `tool_output:${body.toolUseId}`\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 logCoalesceKey(body: SessionEventBody): string | undefined {\n return (body.type === 'user_message' && body.shell) || body.type === 'tool_output' ? replayCoalesceKey(body) : undefined\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' && body.type !== 'tool_output'\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\n// A gateway's answer to \"which machine am I?\". `machineId` is an opaque fingerprint of the host\n// the gateway process runs on, not an identity or a secret: a client that computes the same\n// fingerprint for itself knows the gateway's paths are its own paths, and can open them natively\n// instead of proxying them over `/fs`. Optional, so a gateway that predates it just stays remote.\nexport type GatewayMeta = {\n protocolVersion: number\n machineId?: string\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 './errors.ts'\nexport * from './paths.ts'\nexport * from './pricing.ts'\nexport * from './peer-mentions.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": "3.2.0",
3
+ "version": "3.4.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",