@workerdeck/protocol 3.3.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.d.mts CHANGED
@@ -1,3 +1,68 @@
1
+ //#region src/agents.d.ts
2
+ type AgentRef = {
3
+ id: string;
4
+ name: string;
5
+ avatar?: string;
6
+ lead?: string;
7
+ team?: string;
8
+ leads?: true;
9
+ order?: number;
10
+ conversation?: number;
11
+ };
12
+ type AgentConfig = {
13
+ cwd?: string;
14
+ profile?: string;
15
+ model?: string;
16
+ reasoningEffort?: string;
17
+ permissionMode?: PermissionMode;
18
+ brief?: string;
19
+ agentContextReset?: boolean;
20
+ sleepAfterMs?: number;
21
+ };
22
+ type AgentInfo = {
23
+ id: string;
24
+ name: string;
25
+ createdAt: number;
26
+ updatedAt: number;
27
+ avatar?: string;
28
+ sessionId?: string;
29
+ pastSessions: string[];
30
+ config: AgentConfig;
31
+ lead?: string;
32
+ order?: number;
33
+ };
34
+ type CreateAgentRequest = {
35
+ name?: string;
36
+ config?: AgentConfig;
37
+ prompt?: string;
38
+ lead?: string;
39
+ adopt?: string;
40
+ };
41
+ type UpdateAgentRequest = {
42
+ name?: string;
43
+ config?: AgentConfig;
44
+ lead?: string | null;
45
+ order?: number;
46
+ };
47
+ type RetireAgentRequest = {
48
+ members?: 'release' | 'retire';
49
+ };
50
+ type AgentsResponse = {
51
+ agents: AgentInfo[];
52
+ };
53
+ type AgentResponse = {
54
+ agent: AgentInfo;
55
+ session?: SessionInfo;
56
+ };
57
+ declare const AGENT_SLEEP_AFTER_MS_DEFAULT: number;
58
+ declare function agentRef(agent: AgentInfo, team?: {
59
+ leadName?: string;
60
+ leads?: boolean;
61
+ }): AgentRef;
62
+ declare function teamRole(agent: AgentRef | undefined): 'lead' | 'member' | undefined;
63
+ declare function teamReaches(from: AgentRef | undefined, to: AgentRef | undefined): boolean;
64
+ declare function projectAccent(key: string): string;
65
+ //#endregion
1
66
  //#region src/pricing.d.ts
2
67
  type CostBasis = 'list' | 'managed' | 'unknown';
3
68
  type TokenUsage = {
@@ -108,6 +173,8 @@ type ViewConfig = {
108
173
  shells?: StepDisplay;
109
174
  tasks?: StepDisplay;
110
175
  customGroups?: CustomGroup[];
176
+ collapsedTeams?: string[];
177
+ earlierOpen?: boolean;
111
178
  };
112
179
  declare const DEFAULT_VIEW_CONFIG: ViewConfig;
113
180
  type ScopeRoot = {
@@ -126,17 +193,24 @@ type SessionRow = {
126
193
  state: SessionState;
127
194
  info: SessionInfo;
128
195
  unseen: number;
196
+ members?: SessionRow[];
197
+ teamState?: SessionState;
198
+ context?: true;
129
199
  };
130
200
  type SessionGroup = {
131
201
  key: string;
132
202
  label?: string;
203
+ gateway?: string;
204
+ project?: string;
133
205
  rows: SessionRow[];
134
206
  hostId?: string;
135
207
  cwd?: string;
136
208
  custom?: string;
209
+ earlier?: true;
137
210
  };
138
211
  type GroupOptions = {
139
212
  gatewayCount?: number;
213
+ all?: readonly SessionRow[];
140
214
  };
141
215
  declare const UNGROUPED_KEY = "custom:ungrouped";
142
216
  declare function sessionKey(row: Pick<SessionRow, 'hostId' | 'info'>): string;
@@ -158,6 +232,17 @@ declare function inScope(row: SessionRow, scope: WorkspaceScope): boolean;
158
232
  declare function scopeActive(config: ViewConfig, scope: WorkspaceScope | undefined): boolean;
159
233
  declare function filterRows(rows: readonly SessionRow[], config: ViewConfig, scope?: WorkspaceScope): SessionRow[];
160
234
  declare function groupRows(rows: readonly SessionRow[], config: ViewConfig, options?: GroupOptions): SessionGroup[];
235
+ declare function teamKey(row: Pick<SessionRow, 'hostId' | 'info'>): string | undefined;
236
+ declare function teamState(rows: readonly SessionRow[]): SessionState;
237
+ declare function isTeamCollapsed(config: ViewConfig, row: SessionRow): boolean;
238
+ declare function toggleTeamCollapsed(config: ViewConfig, row: SessionRow): ViewConfig;
239
+ type TeamSummary = {
240
+ members: number;
241
+ working: number;
242
+ attention: number;
243
+ unseen: number;
244
+ };
245
+ declare function teamSummary(lead: SessionRow): TeamSummary;
161
246
  declare function newCustomGroupId(): string;
162
247
  declare function addCustomGroup(groups: readonly CustomGroup[], name: string, id?: string): CustomGroup[];
163
248
  declare function renameCustomGroup(groups: readonly CustomGroup[], id: string, name: string): CustomGroup[];
@@ -216,6 +301,28 @@ type PeerMentionToken = {
216
301
  end: number;
217
302
  body: string;
218
303
  };
304
+ type PeerSessionSummary = {
305
+ id: string;
306
+ gateway?: string;
307
+ engine?: ProfileEngine;
308
+ status: SessionStatus;
309
+ title?: string;
310
+ project?: string;
311
+ projectRoot?: string;
312
+ cwd: string;
313
+ profile?: string;
314
+ model?: string;
315
+ contextUsage?: ContextReading;
316
+ lastActivityAt?: number;
317
+ pendingPermissionCount: number;
318
+ allow?: Array<'send' | 'peek'>;
319
+ agent?: string;
320
+ role?: 'lead' | 'member';
321
+ team?: string;
322
+ };
323
+ type PeerSessionsResponse = {
324
+ peers: PeerSessionSummary[];
325
+ };
219
326
  declare const PROMPT_SENTENCE_TAIL: ReadonlySet<string>;
220
327
  declare function peerMentionSlug(title: string | undefined, id: string): string;
221
328
  declare function peerMentionKey(body: string): string;
@@ -479,6 +586,9 @@ type SessionEventBody = {
479
586
  } | {
480
587
  type: 'model_changed';
481
588
  model?: string;
589
+ } | {
590
+ type: 'effort_changed';
591
+ effort: string | null;
482
592
  } | {
483
593
  type: 'permission_mode_changed';
484
594
  mode: PermissionMode;
@@ -491,9 +601,13 @@ type SessionEventBody = {
491
601
  } | {
492
602
  type: 'plan_info';
493
603
  subscriptionType: string;
604
+ } | {
605
+ type: 'engine_sleep';
606
+ asleep: boolean;
494
607
  } | {
495
608
  type: 'conversation_reset';
496
609
  sdkSessionId?: string;
610
+ agentReason?: string;
497
611
  } | {
498
612
  type: 'context_compacted';
499
613
  uuid: string;
@@ -574,6 +688,10 @@ type SessionEventBody = {
574
688
  path: string;
575
689
  bytes: number;
576
690
  description?: string;
691
+ } | {
692
+ type: 'tool_output';
693
+ toolUseId: string;
694
+ tail: string;
577
695
  } | {
578
696
  type: 'sdk_event';
579
697
  payload: {
@@ -630,12 +748,20 @@ type SessionCommand = {
630
748
  type: 'interrupt';
631
749
  } | {
632
750
  type: 'clear_context';
751
+ } | {
752
+ type: 'sleep';
753
+ } | {
754
+ type: 'background_task';
755
+ toolUseId?: string;
633
756
  } | {
634
757
  type: 'set_permission_mode';
635
758
  mode: PermissionMode;
636
759
  } | {
637
760
  type: 'set_model';
638
761
  model?: string;
762
+ } | {
763
+ type: 'set_effort';
764
+ effort?: string;
639
765
  } | {
640
766
  type: 'tool_call_result';
641
767
  executionId: string;
@@ -752,6 +878,8 @@ type ClientFrame = SessionCommand;
752
878
  type ProfileDefaults = {
753
879
  model?: string;
754
880
  permissionMode?: PermissionMode;
881
+ efforts?: Record<string, string>;
882
+ agentContextReset?: boolean;
755
883
  };
756
884
  type ProfileEngine = 'claude' | 'codex' | 'provider';
757
885
  type EngineCapabilities = {
@@ -777,16 +905,20 @@ type EngineCapabilities = {
777
905
  vfs: boolean;
778
906
  hostCwd?: boolean;
779
907
  systemInstructions?: boolean;
908
+ engineSleep?: boolean;
909
+ backgroundTasks?: boolean;
780
910
  streaming: 'token' | 'item' | 'none';
781
911
  };
782
912
  declare const ENGINE_CAPABILITIES: Record<ProfileEngine, EngineCapabilities>;
783
913
  declare function supportsPermissionMode(engine: ProfileEngine | undefined, mode: PermissionMode): boolean;
914
+ type ProviderContextWindow = number | Record<string, number>;
784
915
  type ProviderConfig = {
785
916
  id: string;
786
917
  model?: string;
787
918
  models?: string[];
788
919
  baseUrl?: string;
789
920
  apiKeyEnv?: string;
921
+ contextWindow?: ProviderContextWindow;
790
922
  };
791
923
  type SessionCapability = 'web_search' | 'download' | 'web_fetch' | 'deliver_file';
792
924
  type ProfileSessionDefaults = {
@@ -906,6 +1038,7 @@ type CreateSessionRequest = {
906
1038
  capabilities?: SessionCapability[];
907
1039
  meta?: Record<string, unknown>;
908
1040
  scope?: Record<string, string>;
1041
+ agentContextReset?: boolean;
909
1042
  };
910
1043
  declare const CREATE_SESSION_REQUEST_KEYS: ReadonlyArray<keyof CreateSessionRequest>;
911
1044
  declare function pickCreateSessionRequest(body: Record<string, unknown>): CreateSessionRequest;
@@ -963,6 +1096,7 @@ type SessionInfo = {
963
1096
  engine?: ProfileEngine;
964
1097
  capabilities?: EngineCapabilities;
965
1098
  model?: string;
1099
+ effort?: string | null;
966
1100
  permissionMode?: PermissionMode;
967
1101
  canBypassPermissions?: boolean;
968
1102
  apiKeySource?: string;
@@ -986,6 +1120,9 @@ type SessionInfo = {
986
1120
  project?: ProjectInfo;
987
1121
  shells?: ShellInfo[];
988
1122
  shellAgentWrite?: 'gated' | 'allow';
1123
+ engineAsleep?: true;
1124
+ agentContextReset?: true;
1125
+ agent?: AgentRef;
989
1126
  };
990
1127
  declare function contextReading(body: SessionEventBody): ContextReading | undefined;
991
1128
  declare function transcriptActivity(body: SessionEventBody): number;
@@ -1269,5 +1406,5 @@ type QueueStatsResponse = {
1269
1406
  stats: QueueStats;
1270
1407
  };
1271
1408
  //#endregion
1272
- 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, 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, 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 };
1409
+ export { AGENT_SLEEP_AFTER_MS_DEFAULT, AgentConfig, AgentInfo, AgentRef, AgentResponse, AgentsResponse, ApiMessage, AttachedFrame, BUILTIN_TOOL_TITLES, ByModel, CHECKLIST_TEXT_MAX, CREATE_SESSION_REQUEST_KEYS, ChecklistItem, ChecklistStatus, ClientFrame, ContentBlock, ContextReading, ContextUsage, ContextUsageCategory, CostBasis, CostBreakdown, CreateAgentRequest, 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, RetireAgentRequest, 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, TeamSummary, TextBlock, ThinkingBlock, TokenUsage, ToolCallRequestFrame, ToolExecutionBackend, ToolExecutionOutput, ToolExecutionStatus, ToolResultBlock, ToolUseBlock, UNGROUPED_KEY, UNPRICED_WARN_SHARE, USAGE_STALE_AFTER_MS, UnknownBlock, UpdateAgentRequest, UpdateProfileRequest, UpdateSessionRequest, UpdateSessionResponse, UploadAttachmentResponse, UsageWindowRow, UserQuestion, UserQuestionOption, ViewConfig, Watermark, WatermarkStore, Watermarks, WebhookConfig, WorkspaceScope, WriteHostFileRequest, WriteHostFileResponse, activePricing, adaptersOf, addCustomGroup, addTokenUsage, agentRef, byModelTotalTokens, canonicalModel, clearFilters, contextReading, costOf, costOfByModel, displayCustomized, displayedTasks, emptyTokenUsage, errorMessage, facetFilterCount, filterRows, groupRows, hasFacetFilter, imagePartRef, inScope, isAgentRecord, isJobRun, isPeerMentionBody, isPeerSendTool, isTeamCollapsed, logCoalesceKey, mergeByModel, mergePricing, mergeUsage, meteredCost, moveCustomGroup, moveToCustomGroup, newCustomGroupId, normalizeViewConfig, orderUsageWindows, parseTodoWriteInput, parseUserQuestions, peerDeliveredPrefix, peerDeliveredTo, peerMentionKey, peerMentionSlug, peerShortId, pickCreateSessionRequest, pricingAgeDays, pricingAgeNote, projectAccent, 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, teamKey, teamReaches, teamRole, teamState, teamSummary, toggleTeamCollapsed, tokenUsageFromWire, toolTitle, totalTokens, transcriptActivity, transcriptContent, transcriptProse, unknownBasisModels, unpricedModels, unseenCount, usageInfos, usageIsStale, visibleShells, visibleSubagents, visibleTasks, watermarkKey, worseBasis };
1273
1410
  //# sourceMappingURL=index.d.mts.map
package/build/index.mjs CHANGED
@@ -1,3 +1,44 @@
1
+ //#region src/agents.ts
2
+ const AGENT_SLEEP_AFTER_MS_DEFAULT = 9e5;
3
+ function agentRef(agent, team = {}) {
4
+ const ref = {
5
+ id: agent.id,
6
+ name: agent.name
7
+ };
8
+ if (agent.avatar !== void 0) ref.avatar = agent.avatar;
9
+ if (agent.lead !== void 0) {
10
+ ref.lead = agent.lead;
11
+ if (team.leadName !== void 0) ref.team = team.leadName;
12
+ }
13
+ if (team.leads) ref.leads = true;
14
+ if (agent.pastSessions.length > 0) ref.conversation = agent.pastSessions.length + 1;
15
+ if (agent.order !== void 0) ref.order = agent.order;
16
+ return ref;
17
+ }
18
+ function teamRole(agent) {
19
+ return agent?.lead !== void 0 ? "member" : agent?.leads ? "lead" : void 0;
20
+ }
21
+ function teamReaches(from, to) {
22
+ if (to?.lead !== void 0) return from !== void 0 && (from.id === to.lead || from.lead === to.lead);
23
+ if (from?.lead !== void 0) return to !== void 0 && to.id === from.lead;
24
+ return true;
25
+ }
26
+ const PROJECT_ACCENTS = [
27
+ "#497eae",
28
+ "#8a6bb8",
29
+ "#3f8f6b",
30
+ "#b0794a",
31
+ "#a85a6e",
32
+ "#4f8f96",
33
+ "#7c8a3f",
34
+ "#6b72b8"
35
+ ];
36
+ function projectAccent(key) {
37
+ let hash = 2166136261;
38
+ for (let i = 0; i < key.length; i++) hash = Math.imul(hash ^ key.charCodeAt(i), 16777619);
39
+ return PROJECT_ACCENTS[(hash >>> 0) % PROJECT_ACCENTS.length];
40
+ }
41
+ //#endregion
1
42
  //#region src/session-list.ts
2
43
  const STATE_ORDER = [
3
44
  "attention",
@@ -122,7 +163,7 @@ function visibleShells(info, show, now) {
122
163
  }
123
164
  function matchesSearch(row, needle) {
124
165
  if (!needle) return true;
125
- return sessionLabel(row.info).toLowerCase().includes(needle) || row.info.cwd.toLowerCase().includes(needle) || (row.info.project?.name.toLowerCase().includes(needle) ?? false) || (row.info.project?.shortcode?.toLowerCase().includes(needle) ?? false) || row.hostName.toLowerCase().includes(needle) || row.adapter.toLowerCase().includes(needle) || row.info.id.startsWith(needle);
166
+ return sessionLabel(row.info).toLowerCase().includes(needle) || (row.info.agent?.name.toLowerCase().includes(needle) ?? false) || row.info.cwd.toLowerCase().includes(needle) || (row.info.project?.name.toLowerCase().includes(needle) ?? false) || (row.info.project?.shortcode?.toLowerCase().includes(needle) ?? false) || row.hostName.toLowerCase().includes(needle) || row.adapter.toLowerCase().includes(needle) || row.info.id.startsWith(needle);
126
167
  }
127
168
  function normalizePath(path) {
128
169
  return path.replace(/\\/g, "/").replace(/\/+$/, "");
@@ -144,14 +185,17 @@ function filterRows(rows, config, scope) {
144
185
  return rows.filter((row) => (config.gateways.length === 0 || config.gateways.includes(row.hostId)) && (config.adapters.length === 0 || config.adapters.includes(row.adapter)) && (config.states.length === 0 || config.states.includes(row.state)) && (!config.projects?.length || config.projects.includes(projectKey(row))) && (!scoping || inScope(row, scoping)) && matchesSearch(row, needle));
145
186
  }
146
187
  function facetKey(row, facet) {
147
- return facet === "gateway" ? row.hostId : facet === "adapter" ? row.adapter : facet === "project" ? projectKey(row) : row.state;
188
+ return facet === "gateway" ? row.hostId : facet === "adapter" ? row.adapter : facet === "project" ? projectKey(row) : unitState(row);
189
+ }
190
+ function unitState(row) {
191
+ return row.teamState ?? row.state;
148
192
  }
149
193
  function facetLabel(row, facet, multiGateway = false) {
150
194
  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];
195
+ return facet === "gateway" ? row.hostName : facet === "adapter" ? row.adapter : STATE_LABELS[unitState(row)];
152
196
  }
153
197
  function facetRank(row, facet, multiGateway = false) {
154
- if (facet === "state") return String(STATE_ORDER.indexOf(row.state));
198
+ if (facet === "state") return String(STATE_ORDER.indexOf(unitState(row)));
155
199
  if (facet === "project" && multiGateway) return `${row.hostName.toLowerCase()}\u0000${projectLabel(row).toLowerCase()}`;
156
200
  return facetLabel(row, facet).toLowerCase();
157
201
  }
@@ -164,11 +208,19 @@ function compare(a, b, sortBy) {
164
208
  return facetRank(a, sortBy).localeCompare(facetRank(b, sortBy)) || byRecency(a, b);
165
209
  }
166
210
  function groupRows(rows, config, options = {}) {
167
- const sorted = [...rows].sort((a, b) => compare(a, b, config.sortBy));
168
- if (config.groupBy === "none") return sorted.length ? [{
211
+ const units = teamUnits(rows, options.all ?? rows).sort((a, b) => compare(a, b, config.sortBy));
212
+ const earlier = config.groupBy !== "state" && config.groupBy !== "custom" ? units.filter(isEarlier) : [];
213
+ const sorted = earlier.length ? units.filter((row) => !isEarlier(row)) : units;
214
+ const trailing = earlier.length ? [{
215
+ key: "earlier",
216
+ label: "Earlier",
217
+ rows: earlier,
218
+ earlier: true
219
+ }] : [];
220
+ if (config.groupBy === "none") return [...sorted.length ? [{
169
221
  key: "all",
170
222
  rows: sorted
171
- }] : [];
223
+ }] : [], ...trailing];
172
224
  if (config.groupBy === "custom") return customGroupRows(sorted, config.customGroups ?? []);
173
225
  const facet = config.groupBy;
174
226
  const multiGateway = (options.gatewayCount ?? new Set(rows.map((row) => row.hostId)).size) > 1;
@@ -184,11 +236,89 @@ function groupRows(rows, config, options = {}) {
184
236
  key,
185
237
  label: facetLabel(row, facet, multiGateway),
186
238
  rows: [row],
187
- ...facet === "project" ? projectTarget(row) : {}
239
+ ...facet === "project" ? projectTarget(row) : {},
240
+ ...facet === "project" && multiGateway ? {
241
+ gateway: row.hostName,
242
+ project: projectLabel(row)
243
+ } : {}
188
244
  });
189
245
  }
190
246
  }
191
- return [...groups.values()].sort((a, b) => ranks.get(a.key).localeCompare(ranks.get(b.key)));
247
+ return [...[...groups.values()].sort((a, b) => ranks.get(a.key).localeCompare(ranks.get(b.key))), ...trailing];
248
+ }
249
+ function teamKey(row) {
250
+ const agent = row.info.agent;
251
+ return agent ? `${row.hostId}:${agent.id}` : void 0;
252
+ }
253
+ function leadKeyOf(row) {
254
+ const lead = row.info.agent?.lead;
255
+ return lead === void 0 ? void 0 : `${row.hostId}:${lead}`;
256
+ }
257
+ function isEarlier(row) {
258
+ return row.info.agent === void 0 && row.state === "ended";
259
+ }
260
+ function teamUnits(rows, all) {
261
+ const leads = /* @__PURE__ */ new Map();
262
+ for (const row of all) {
263
+ const key = teamKey(row);
264
+ if (key !== void 0 && row.info.agent?.lead === void 0) leads.set(key, row);
265
+ }
266
+ const shown = new Set(rows.map((row) => sessionKey(row)));
267
+ const members = /* @__PURE__ */ new Map();
268
+ const top = [];
269
+ for (const row of rows) {
270
+ const lead = leadKeyOf(row);
271
+ if (lead !== void 0 && leads.has(lead)) members.set(lead, [...members.get(lead) ?? [], row]);
272
+ else top.push(row);
273
+ }
274
+ for (const lead of members.keys()) {
275
+ const leadRow = leads.get(lead);
276
+ if (!shown.has(sessionKey(leadRow))) top.push({
277
+ ...leadRow,
278
+ context: true
279
+ });
280
+ }
281
+ return top.map((row) => {
282
+ const key = teamKey(row);
283
+ const crew = key === void 0 ? void 0 : members.get(key);
284
+ if (!crew) return row;
285
+ const ordered = [...crew].sort(byTeamOrder);
286
+ return {
287
+ ...row,
288
+ members: ordered,
289
+ teamState: teamState([row, ...ordered])
290
+ };
291
+ });
292
+ }
293
+ function byTeamOrder(a, b) {
294
+ return (a.info.agent?.order ?? Number.MAX_SAFE_INTEGER) - (b.info.agent?.order ?? Number.MAX_SAFE_INTEGER) || a.info.createdAt - b.info.createdAt;
295
+ }
296
+ function teamState(rows) {
297
+ let best = STATE_ORDER.length - 1;
298
+ for (const row of rows) best = Math.min(best, STATE_ORDER.indexOf(row.state));
299
+ return STATE_ORDER[best];
300
+ }
301
+ function isTeamCollapsed(config, row) {
302
+ const key = teamKey(row);
303
+ return key !== void 0 && (config.collapsedTeams ?? []).includes(key);
304
+ }
305
+ function toggleTeamCollapsed(config, row) {
306
+ const key = teamKey(row);
307
+ if (key === void 0) return config;
308
+ const held = config.collapsedTeams ?? [];
309
+ return {
310
+ ...config,
311
+ collapsedTeams: held.includes(key) ? held.filter((k) => k !== key) : [...held, key]
312
+ };
313
+ }
314
+ function teamSummary(lead) {
315
+ const members = lead.members ?? [];
316
+ return {
317
+ members: members.length,
318
+ working: members.filter((row) => row.state === "working").length,
319
+ attention: members.filter((row) => row.state === "attention").length,
320
+ unseen: members.reduce((sum, row) => sum + row.unseen, 0)
321
+ };
192
322
  }
193
323
  function projectTarget(row) {
194
324
  const cwd = row.info.project?.root ?? row.info.cwd;
@@ -695,7 +825,7 @@ const PROMPT_SENTENCE_TAIL = /* @__PURE__ */ new Set([
695
825
  ]);
696
826
  const MENTION_BODY = /^[\p{L}\p{N}][\p{L}\p{N}\-_]*$/u;
697
827
  function peerMentionSlug(title, id) {
698
- return (title ?? "").normalize("NFKC").replace(/[^\p{L}\p{N}]+/gu, "-").replace(/^-+|-+$/g, "").slice(0, 64).replace(/^-+|-+$/g, "") || id.slice(0, 8);
828
+ 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);
699
829
  }
700
830
  function peerMentionKey(body) {
701
831
  return body.normalize("NFKC").toLowerCase().replace(/[_\s]+/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
@@ -743,7 +873,9 @@ const BUILTIN_TOOL_TITLES = {
743
873
  peers_send: "Messaging a peer session",
744
874
  mcp__workerdeck__peers_list: "Listing peer sessions",
745
875
  mcp__workerdeck__peers_peek: "Peeking at a peer session",
746
- mcp__workerdeck__peers_send: "Messaging a peer session"
876
+ mcp__workerdeck__peers_send: "Messaging a peer session",
877
+ session_info: "Checking session info",
878
+ mcp__workerdeck__session_info: "Checking session info"
747
879
  };
748
880
  function toolTitle(name, titles) {
749
881
  return sanitizeToolTitle(titles?.[name] ?? BUILTIN_TOOL_TITLES[name], name);
@@ -949,6 +1081,8 @@ const ENGINE_CAPABILITIES = {
949
1081
  vfs: false,
950
1082
  hostCwd: true,
951
1083
  systemInstructions: true,
1084
+ engineSleep: true,
1085
+ backgroundTasks: true,
952
1086
  streaming: "token"
953
1087
  },
954
1088
  codex: {
@@ -985,6 +1119,7 @@ const ENGINE_CAPABILITIES = {
985
1119
  vfs: false,
986
1120
  hostCwd: true,
987
1121
  systemInstructions: true,
1122
+ engineSleep: true,
988
1123
  streaming: "token"
989
1124
  },
990
1125
  provider: {
@@ -1017,6 +1152,7 @@ const ENGINE_CAPABILITIES = {
1017
1152
  vfs: true,
1018
1153
  hostCwd: false,
1019
1154
  systemInstructions: true,
1155
+ engineSleep: false,
1020
1156
  streaming: "token"
1021
1157
  }
1022
1158
  };
@@ -1044,7 +1180,8 @@ const CREATE_SESSION_REQUEST_KEYS = Object.keys({
1044
1180
  questionBehavior: true,
1045
1181
  capabilities: true,
1046
1182
  meta: true,
1047
- scope: true
1183
+ scope: true,
1184
+ agentContextReset: true
1048
1185
  });
1049
1186
  function pickCreateSessionRequest(body) {
1050
1187
  const picked = {};
@@ -1133,12 +1270,15 @@ function replayCoalesceKey(body) {
1133
1270
  case "context_compacted": return `context_compacted:${body.uuid}`;
1134
1271
  case "user_message": return body.shell ? `shell:${body.shell.id}` : void 0;
1135
1272
  case "checklist": return "checklist";
1273
+ case "engine_sleep": return "engine_sleep";
1274
+ case "effort_changed": return "effort_changed";
1275
+ case "tool_output": return `tool_output:${body.toolUseId}`;
1136
1276
  case "sdk_event": return body.payload.type === "system" && body.payload.subtype === "status" ? "sdk_event:system:status" : void 0;
1137
1277
  default: return;
1138
1278
  }
1139
1279
  }
1140
1280
  function logCoalesceKey(body) {
1141
- return body.type === "user_message" && body.shell ? replayCoalesceKey(body) : void 0;
1281
+ return body.type === "user_message" && body.shell || body.type === "tool_output" ? replayCoalesceKey(body) : void 0;
1142
1282
  }
1143
1283
  function replayRetains(body) {
1144
1284
  if (body.type !== "stream_delta") return true;
@@ -1147,9 +1287,9 @@ function replayRetains(body) {
1147
1287
  return delta.delta?.type === "text_delta" || delta.delta?.type === "thinking_delta";
1148
1288
  }
1149
1289
  function snapshotRetains(body) {
1150
- return body.type !== "stream_delta";
1290
+ return body.type !== "stream_delta" && body.type !== "tool_output";
1151
1291
  }
1152
1292
  //#endregion
1153
- 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 };
1293
+ export { AGENT_SLEEP_AFTER_MS_DEFAULT, 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, agentRef, byModelTotalTokens, canonicalModel, clearFilters, contextReading, costOf, costOfByModel, displayCustomized, displayedTasks, emptyTokenUsage, errorMessage, facetFilterCount, filterRows, groupRows, hasFacetFilter, imagePartRef, inScope, isAgentRecord, isJobRun, isPeerMentionBody, isPeerSendTool, isTeamCollapsed, logCoalesceKey, mergeByModel, mergePricing, mergeUsage, meteredCost, moveCustomGroup, moveToCustomGroup, newCustomGroupId, normalizeViewConfig, orderUsageWindows, parseTodoWriteInput, parseUserQuestions, peerDeliveredPrefix, peerDeliveredTo, peerMentionKey, peerMentionSlug, peerShortId, pickCreateSessionRequest, pricingAgeDays, pricingAgeNote, projectAccent, 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, teamKey, teamReaches, teamRole, teamState, teamSummary, toggleTeamCollapsed, tokenUsageFromWire, toolTitle, totalTokens, transcriptActivity, transcriptContent, transcriptProse, unknownBasisModels, unpricedModels, unseenCount, usageInfos, usageIsStale, visibleShells, visibleSubagents, visibleTasks, watermarkKey, worseBasis };
1154
1294
 
1155
1295
  //# 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' | '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 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 })\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","// `#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\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 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/agents.ts","../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 type { PermissionMode, SessionInfo } from './index.ts'\n\nexport type AgentRef = {\n id: string\n name: string\n avatar?: string\n lead?: string\n team?: string\n leads?: true\n order?: number\n // Which conversation the agent is on, from 1: each restart (\"New conversation\") starts the next one.\n conversation?: number\n}\n\nexport type AgentConfig = {\n cwd?: string\n profile?: string\n model?: string\n reasoningEffort?: string\n permissionMode?: PermissionMode\n brief?: string\n agentContextReset?: boolean\n sleepAfterMs?: number\n}\n\nexport type AgentInfo = {\n id: string\n name: string\n createdAt: number\n updatedAt: number\n avatar?: string\n sessionId?: string\n pastSessions: string[]\n config: AgentConfig\n lead?: string\n order?: number\n}\n\nexport type CreateAgentRequest = {\n name?: string\n config?: AgentConfig\n prompt?: string\n lead?: string\n adopt?: string\n}\n\nexport type UpdateAgentRequest = {\n name?: string\n config?: AgentConfig\n lead?: string | null\n order?: number\n}\n\nexport type RetireAgentRequest = { members?: 'release' | 'retire' }\n\nexport type AgentsResponse = { agents: AgentInfo[] }\n\nexport type AgentResponse = { agent: AgentInfo; session?: SessionInfo }\n\nexport const AGENT_SLEEP_AFTER_MS_DEFAULT = 15 * 60_000\n\nexport function agentRef(agent: AgentInfo, team: { leadName?: string; leads?: boolean } = {}): AgentRef {\n const ref: AgentRef = { id: agent.id, name: agent.name }\n if (agent.avatar !== undefined) {\n ref.avatar = agent.avatar\n }\n if (agent.lead !== undefined) {\n ref.lead = agent.lead\n if (team.leadName !== undefined) {\n ref.team = team.leadName\n }\n }\n if (team.leads) {\n ref.leads = true\n }\n if (agent.pastSessions.length > 0) {\n ref.conversation = agent.pastSessions.length + 1\n }\n if (agent.order !== undefined) {\n ref.order = agent.order\n }\n return ref\n}\n\nexport function teamRole(agent: AgentRef | undefined): 'lead' | 'member' | undefined {\n return agent?.lead !== undefined ? 'member' : agent?.leads ? 'lead' : undefined\n}\n\n// The peers rule for teams: a member reaches its lead and teammates only, nobody outside a team reaches its members,\n// and everything top-level reaches everything top-level. Sessions with no agent are top-level.\nexport function teamReaches(from: AgentRef | undefined, to: AgentRef | undefined): boolean {\n if (to?.lead !== undefined) {\n return from !== undefined && (from.id === to.lead || from.lead === to.lead)\n }\n if (from?.lead !== undefined) {\n return to !== undefined && to.id === from.lead\n }\n return true\n}\n\nconst PROJECT_ACCENTS = ['#497eae', '#8a6bb8', '#3f8f6b', '#b0794a', '#a85a6e', '#4f8f96', '#7c8a3f', '#6b72b8'] as const\n\n// A stable colour per project key (a host and root, or any string), the same on every client and the gateway.\nexport function projectAccent(key: string): string {\n let hash = 0x811c9dc5\n for (let i = 0; i < key.length; i++) {\n hash = Math.imul(hash ^ key.charCodeAt(i), 0x01000193)\n }\n return PROJECT_ACCENTS[(hash >>> 0) % PROJECT_ACCENTS.length]!\n}\n","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 // `teamKey` values: the teams this client draws folded. A viewing preference, never sent to the gateway.\n collapsedTeams?: string[]\n earlierOpen?: boolean\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 // Set by `groupRows` on a lead: its members, in team order, drawn under it and never top-level.\n members?: SessionRow[]\n // Set by `groupRows` on a lead: the most urgent state across the lead and its members.\n teamState?: SessionState\n // A lead drawn only because a filter matched one of its members.\n context?: true\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 // The trailing fold of ended sessions that belong to no agent.\n earlier?: true\n}\n\n// `all` is the unfiltered list: a member matched by a filter pulls its lead in from there as a context row.\nexport type GroupOptions = { gatewayCount?: number; all?: readonly SessionRow[] }\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.agent?.name.toLowerCase().includes(needle) ?? false) ||\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) : unitState(row)\n}\n\nfunction unitState(row: SessionRow): SessionState {\n return row.teamState ?? 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[unitState(row)]\n}\n\nfunction facetRank(row: SessionRow, facet: Facet, multiGateway = false): string {\n if (facet === 'state') {\n return String(STATE_ORDER.indexOf(unitState(row)))\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 units = teamUnits(rows, options.all ?? rows).sort((a, b) => compare(a, b, config.sortBy))\n const foldsEarlier = config.groupBy !== 'state' && config.groupBy !== 'custom'\n const earlier = foldsEarlier ? units.filter(isEarlier) : []\n const sorted = earlier.length ? units.filter((row) => !isEarlier(row)) : units\n const trailing: SessionGroup[] = earlier.length ? [{ key: 'earlier', label: 'Earlier', rows: earlier, earlier: true }] : []\n if (config.groupBy === 'none') {\n return [...(sorted.length ? [{ key: 'all', rows: sorted }] : []), ...trailing]\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)!)), ...trailing]\n}\n\nexport function teamKey(row: Pick<SessionRow, 'hostId' | 'info'>): string | undefined {\n const agent = row.info.agent\n return agent ? `${row.hostId}:${agent.id}` : undefined\n}\n\nfunction leadKeyOf(row: SessionRow): string | undefined {\n const lead = row.info.agent?.lead\n return lead === undefined ? undefined : `${row.hostId}:${lead}`\n}\n\nfunction isEarlier(row: SessionRow): boolean {\n return row.info.agent === undefined && row.state === 'ended'\n}\n\n// A member whose lead is not in the list at all (its session gone) stays top-level rather than vanish.\nfunction teamUnits(rows: readonly SessionRow[], all: readonly SessionRow[]): SessionRow[] {\n const leads = new Map<string, SessionRow>()\n for (const row of all) {\n const key = teamKey(row)\n if (key !== undefined && row.info.agent?.lead === undefined) {\n leads.set(key, row)\n }\n }\n const shown = new Set(rows.map((row) => sessionKey(row)))\n const members = new Map<string, SessionRow[]>()\n const top: SessionRow[] = []\n for (const row of rows) {\n const lead = leadKeyOf(row)\n if (lead !== undefined && leads.has(lead)) {\n members.set(lead, [...(members.get(lead) ?? []), row])\n } else {\n top.push(row)\n }\n }\n for (const lead of members.keys()) {\n const leadRow = leads.get(lead)!\n if (!shown.has(sessionKey(leadRow))) {\n top.push({ ...leadRow, context: true })\n }\n }\n return top.map((row) => {\n const key = teamKey(row)\n const crew = key === undefined ? undefined : members.get(key)\n if (!crew) {\n return row\n }\n const ordered = [...crew].sort(byTeamOrder)\n return { ...row, members: ordered, teamState: teamState([row, ...ordered]) }\n })\n}\n\nfunction byTeamOrder(a: SessionRow, b: SessionRow): number {\n const ao = a.info.agent?.order ?? Number.MAX_SAFE_INTEGER\n const bo = b.info.agent?.order ?? Number.MAX_SAFE_INTEGER\n return ao - bo || a.info.createdAt - b.info.createdAt\n}\n\nexport function teamState(rows: readonly SessionRow[]): SessionState {\n let best = STATE_ORDER.length - 1\n for (const row of rows) {\n best = Math.min(best, STATE_ORDER.indexOf(row.state))\n }\n return STATE_ORDER[best]!\n}\n\nexport function isTeamCollapsed(config: ViewConfig, row: SessionRow): boolean {\n const key = teamKey(row)\n return key !== undefined && (config.collapsedTeams ?? []).includes(key)\n}\n\nexport function toggleTeamCollapsed(config: ViewConfig, row: SessionRow): ViewConfig {\n const key = teamKey(row)\n if (key === undefined) {\n return config\n }\n const held = config.collapsedTeams ?? []\n return { ...config, collapsedTeams: held.includes(key) ? held.filter((k) => k !== key) : [...held, key] }\n}\n\nexport type TeamSummary = { members: number; working: number; attention: number; unseen: number }\n\nexport function teamSummary(lead: SessionRow): TeamSummary {\n const members = lead.members ?? []\n return {\n members: members.length,\n working: members.filter((row) => row.state === 'working').length,\n attention: members.filter((row) => row.state === 'attention').length,\n unseen: members.reduce((sum, row) => sum + row.unseen, 0),\n }\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 agent?: string\n role?: 'lead' | 'member'\n team?: string\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 { AgentRef } from './agents.ts'\nimport 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 agent?: AgentRef\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 './agents.ts'\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.3.0",
3
+ "version": "3.5.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",