@workerdeck/protocol 3.5.0 → 3.6.1
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 +29 -1
- package/build/index.mjs +42 -2
- package/build/index.mjs.map +1 -1
- package/package.json +1 -1
package/build/index.d.mts
CHANGED
|
@@ -61,8 +61,23 @@ declare function agentRef(agent: AgentInfo, team?: {
|
|
|
61
61
|
}): AgentRef;
|
|
62
62
|
declare function teamRole(agent: AgentRef | undefined): 'lead' | 'member' | undefined;
|
|
63
63
|
declare function teamReaches(from: AgentRef | undefined, to: AgentRef | undefined): boolean;
|
|
64
|
+
declare const PROJECT_ACCENTS: readonly ["#497eae", "#8a6bb8", "#3f8f6b", "#b0794a", "#a85a6e", "#4f8f96", "#7c8a3f", "#6b72b8"];
|
|
64
65
|
declare function projectAccent(key: string): string;
|
|
65
66
|
//#endregion
|
|
67
|
+
//#region src/status-label.d.ts
|
|
68
|
+
type StatusLabel = {
|
|
69
|
+
text: string;
|
|
70
|
+
emoji?: string;
|
|
71
|
+
setAt: number;
|
|
72
|
+
};
|
|
73
|
+
type StatusLabelInput = {
|
|
74
|
+
text: string;
|
|
75
|
+
emoji?: string;
|
|
76
|
+
};
|
|
77
|
+
declare const STATUS_LABEL_TEXT_MAX = 80;
|
|
78
|
+
declare const STATUS_LABEL_EMOJI_MAX = 16;
|
|
79
|
+
declare function readStatusLabelInput(input: unknown): StatusLabelInput | null | string;
|
|
80
|
+
//#endregion
|
|
66
81
|
//#region src/pricing.d.ts
|
|
67
82
|
type CostBasis = 'list' | 'managed' | 'unknown';
|
|
68
83
|
type TokenUsage = {
|
|
@@ -157,7 +172,10 @@ type CustomGroup = {
|
|
|
157
172
|
id: string;
|
|
158
173
|
name: string;
|
|
159
174
|
members: string[];
|
|
175
|
+
color?: string;
|
|
176
|
+
icon?: string;
|
|
160
177
|
};
|
|
178
|
+
declare const CUSTOM_GROUP_ICON_MAX = 48000;
|
|
161
179
|
type StepDisplay = 'all' | 'active' | 'none';
|
|
162
180
|
type SubagentDisplay = StepDisplay;
|
|
163
181
|
type ViewConfig = {
|
|
@@ -246,6 +264,11 @@ declare function teamSummary(lead: SessionRow): TeamSummary;
|
|
|
246
264
|
declare function newCustomGroupId(): string;
|
|
247
265
|
declare function addCustomGroup(groups: readonly CustomGroup[], name: string, id?: string): CustomGroup[];
|
|
248
266
|
declare function renameCustomGroup(groups: readonly CustomGroup[], id: string, name: string): CustomGroup[];
|
|
267
|
+
declare function customGroupColor(group: Pick<CustomGroup, 'id' | 'color'>): string;
|
|
268
|
+
declare function styleCustomGroup(groups: readonly CustomGroup[], id: string, look: {
|
|
269
|
+
color?: string | null;
|
|
270
|
+
icon?: string | null;
|
|
271
|
+
}): CustomGroup[];
|
|
249
272
|
declare function removeCustomGroup(groups: readonly CustomGroup[], id: string): CustomGroup[];
|
|
250
273
|
declare function moveToCustomGroup(groups: readonly CustomGroup[], key: string, target: string | undefined, before?: string): CustomGroup[];
|
|
251
274
|
declare function moveCustomGroup(groups: readonly CustomGroup[], id: string, before: string | undefined): CustomGroup[];
|
|
@@ -576,6 +599,9 @@ type SessionEventBody = {
|
|
|
576
599
|
} | {
|
|
577
600
|
type: 'checklist';
|
|
578
601
|
items: ChecklistItem[];
|
|
602
|
+
} | {
|
|
603
|
+
type: 'status_label';
|
|
604
|
+
label: StatusLabel | null;
|
|
579
605
|
} | {
|
|
580
606
|
type: 'file_produced';
|
|
581
607
|
fileId: string;
|
|
@@ -1123,6 +1149,7 @@ type SessionInfo = {
|
|
|
1123
1149
|
engineAsleep?: true;
|
|
1124
1150
|
agentContextReset?: true;
|
|
1125
1151
|
agent?: AgentRef;
|
|
1152
|
+
statusLabel?: StatusLabel;
|
|
1126
1153
|
};
|
|
1127
1154
|
declare function contextReading(body: SessionEventBody): ContextReading | undefined;
|
|
1128
1155
|
declare function transcriptActivity(body: SessionEventBody): number;
|
|
@@ -1160,6 +1187,7 @@ type GetSessionResponse = {
|
|
|
1160
1187
|
};
|
|
1161
1188
|
type UpdateSessionRequest = {
|
|
1162
1189
|
title?: string | null;
|
|
1190
|
+
statusLabel?: StatusLabelInput | null;
|
|
1163
1191
|
};
|
|
1164
1192
|
type UpdateSessionResponse = {
|
|
1165
1193
|
session: SessionInfo;
|
|
@@ -1406,5 +1434,5 @@ type QueueStatsResponse = {
|
|
|
1406
1434
|
stats: QueueStats;
|
|
1407
1435
|
};
|
|
1408
1436
|
//#endregion
|
|
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 };
|
|
1437
|
+
export { AGENT_SLEEP_AFTER_MS_DEFAULT, AgentConfig, AgentInfo, AgentRef, AgentResponse, AgentsResponse, ApiMessage, AttachedFrame, BUILTIN_TOOL_TITLES, ByModel, CHECKLIST_TEXT_MAX, CREATE_SESSION_REQUEST_KEYS, CUSTOM_GROUP_ICON_MAX, 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, PROJECT_ACCENTS, 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, STATUS_LABEL_EMOJI_MAX, STATUS_LABEL_TEXT_MAX, 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, StatusLabel, StatusLabelInput, 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, customGroupColor, 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, readStatusLabelInput, removeCustomGroup, renameCustomGroup, replayCoalesceKey, replayRetains, resolvePosix, runningSubagents, sanitizeToolTitle, scanPeerMentions, scopeActive, sessionKey, sessionLabel, sessionState, sessionTasks, setPricingOverrides, snapshotRetains, styleCustomGroup, 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 };
|
|
1410
1438
|
//# sourceMappingURL=index.d.mts.map
|
package/build/index.mjs
CHANGED
|
@@ -83,6 +83,7 @@ const GROUP_BY = [
|
|
|
83
83
|
"project",
|
|
84
84
|
"custom"
|
|
85
85
|
];
|
|
86
|
+
const CUSTOM_GROUP_ICON_MAX = 48e3;
|
|
86
87
|
const DEFAULT_VIEW_CONFIG = {
|
|
87
88
|
search: "",
|
|
88
89
|
gateways: [],
|
|
@@ -369,6 +370,20 @@ function renameCustomGroup(groups, id, name) {
|
|
|
369
370
|
name
|
|
370
371
|
} : group);
|
|
371
372
|
}
|
|
373
|
+
function customGroupColor(group) {
|
|
374
|
+
return group.color ?? projectAccent(`group:${group.id}`);
|
|
375
|
+
}
|
|
376
|
+
function styleCustomGroup(groups, id, look) {
|
|
377
|
+
return groups.map((group) => {
|
|
378
|
+
if (group.id !== id) return group;
|
|
379
|
+
const next = { ...group };
|
|
380
|
+
if (look.color === null) delete next.color;
|
|
381
|
+
else if (look.color !== void 0) next.color = look.color;
|
|
382
|
+
if (look.icon === null) delete next.icon;
|
|
383
|
+
else if (look.icon !== void 0 && look.icon.startsWith("data:image/") && look.icon.length <= 48e3) next.icon = look.icon;
|
|
384
|
+
return next;
|
|
385
|
+
});
|
|
386
|
+
}
|
|
372
387
|
function removeCustomGroup(groups, id) {
|
|
373
388
|
return groups.filter((group) => group.id !== id);
|
|
374
389
|
}
|
|
@@ -852,6 +867,26 @@ function scanPeerMentions(text) {
|
|
|
852
867
|
return tokens;
|
|
853
868
|
}
|
|
854
869
|
//#endregion
|
|
870
|
+
//#region src/status-label.ts
|
|
871
|
+
const STATUS_LABEL_TEXT_MAX = 80;
|
|
872
|
+
const STATUS_LABEL_EMOJI_MAX = 16;
|
|
873
|
+
function readStatusLabelInput(input) {
|
|
874
|
+
if (input === null) return null;
|
|
875
|
+
if (typeof input !== "object" || input === void 0) return "statusLabel must be an object or null";
|
|
876
|
+
const { text, emoji } = input;
|
|
877
|
+
if (typeof text !== "string") return "statusLabel.text must be a string";
|
|
878
|
+
if (emoji !== void 0 && typeof emoji !== "string") return "statusLabel.emoji must be a string";
|
|
879
|
+
const line = text.replace(/\s+/g, " ").trim();
|
|
880
|
+
if (!line) return null;
|
|
881
|
+
if (line.length > 80) return `statusLabel.text is longer than 80 characters`;
|
|
882
|
+
const mark = emoji?.trim();
|
|
883
|
+
if (mark && mark.length > 16) return `statusLabel.emoji is longer than 16 characters`;
|
|
884
|
+
return mark ? {
|
|
885
|
+
text: line,
|
|
886
|
+
emoji: mark
|
|
887
|
+
} : { text: line };
|
|
888
|
+
}
|
|
889
|
+
//#endregion
|
|
855
890
|
//#region src/tool-titles.ts
|
|
856
891
|
const TOOL_TITLE_MAX_CHARS = 64;
|
|
857
892
|
const BUILTIN_TOOL_TITLES = {
|
|
@@ -875,7 +910,11 @@ const BUILTIN_TOOL_TITLES = {
|
|
|
875
910
|
mcp__workerdeck__peers_peek: "Peeking at a peer session",
|
|
876
911
|
mcp__workerdeck__peers_send: "Messaging a peer session",
|
|
877
912
|
session_info: "Checking session info",
|
|
878
|
-
mcp__workerdeck__session_info: "Checking session info"
|
|
913
|
+
mcp__workerdeck__session_info: "Checking session info",
|
|
914
|
+
set_status: "Setting status",
|
|
915
|
+
mcp__workerdeck__set_status: "Setting status",
|
|
916
|
+
change_avatar: "Changing avatar",
|
|
917
|
+
mcp__workerdeck__change_avatar: "Changing avatar"
|
|
879
918
|
};
|
|
880
919
|
function toolTitle(name, titles) {
|
|
881
920
|
return sanitizeToolTitle(titles?.[name] ?? BUILTIN_TOOL_TITLES[name], name);
|
|
@@ -1270,6 +1309,7 @@ function replayCoalesceKey(body) {
|
|
|
1270
1309
|
case "context_compacted": return `context_compacted:${body.uuid}`;
|
|
1271
1310
|
case "user_message": return body.shell ? `shell:${body.shell.id}` : void 0;
|
|
1272
1311
|
case "checklist": return "checklist";
|
|
1312
|
+
case "status_label": return "status_label";
|
|
1273
1313
|
case "engine_sleep": return "engine_sleep";
|
|
1274
1314
|
case "effort_changed": return "effort_changed";
|
|
1275
1315
|
case "tool_output": return `tool_output:${body.toolUseId}`;
|
|
@@ -1290,6 +1330,6 @@ function snapshotRetains(body) {
|
|
|
1290
1330
|
return body.type !== "stream_delta" && body.type !== "tool_output";
|
|
1291
1331
|
}
|
|
1292
1332
|
//#endregion
|
|
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 };
|
|
1333
|
+
export { AGENT_SLEEP_AFTER_MS_DEFAULT, BUILTIN_TOOL_TITLES, CHECKLIST_TEXT_MAX, CREATE_SESSION_REQUEST_KEYS, CUSTOM_GROUP_ICON_MAX, 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, PROJECT_ACCENTS, 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, STATUS_LABEL_EMOJI_MAX, STATUS_LABEL_TEXT_MAX, 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, customGroupColor, 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, readStatusLabelInput, removeCustomGroup, renameCustomGroup, replayCoalesceKey, replayRetains, resolvePosix, runningSubagents, sanitizeToolTitle, scanPeerMentions, scopeActive, sessionKey, sessionLabel, sessionState, sessionTasks, setPricingOverrides, snapshotRetains, styleCustomGroup, 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 };
|
|
1294
1334
|
|
|
1295
1335
|
//# sourceMappingURL=index.mjs.map
|
package/build/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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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"}
|
|
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/status-label.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\nexport const 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 { projectAccent } from './agents.ts'\nimport { 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. `color` is the badge colour (one of\n// `PROJECT_ACCENTS` from the pickers, any CSS colour accepted); `icon` an image the operator chose, as a small data URL,\n// drawn instead of the colour.\nexport type CustomGroup = { id: string; name: string; members: string[]; color?: string; icon?: string }\n\n// The largest `icon` data URL a client stores: a 64 px PNG fits many times over, a raw photo does not.\nexport const CUSTOM_GROUP_ICON_MAX = 48_000\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\n// The colour a group's badge draws: its own, else a stable one derived from its id.\nexport function customGroupColor(group: Pick<CustomGroup, 'id' | 'color'>): string {\n return group.color ?? projectAccent(`group:${group.id}`)\n}\n\n// `null` removes the field; an `icon` over `CUSTOM_GROUP_ICON_MAX` or not an image data URL is ignored.\nexport function styleCustomGroup(\n groups: readonly CustomGroup[],\n id: string,\n look: { color?: string | null; icon?: string | null },\n): CustomGroup[] {\n return groups.map((group) => {\n if (group.id !== id) {\n return group\n }\n const next = { ...group }\n if (look.color === null) {\n delete next.color\n } else if (look.color !== undefined) {\n next.color = look.color\n }\n if (look.icon === null) {\n delete next.icon\n } else if (look.icon !== undefined && look.icon.startsWith('data:image/') && look.icon.length <= CUSTOM_GROUP_ICON_MAX) {\n next.icon = look.icon\n }\n return next\n })\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","// A short line a session shows under its name, like a chat status: the agent sets and clears it through `set_status`,\n// an operator through `PATCH /sessions/:id`. It stays until changed and clears when the conversation resets.\nexport type StatusLabel = { text: string; emoji?: string; setAt: number }\n\nexport type StatusLabelInput = { text: string; emoji?: string }\n\nexport const STATUS_LABEL_TEXT_MAX = 80\nexport const STATUS_LABEL_EMOJI_MAX = 16\n\n// Trimmed and capped; an empty text clears. Returns an error string for input a caller must refuse.\nexport function readStatusLabelInput(input: unknown): StatusLabelInput | null | string {\n if (input === null) {\n return null\n }\n if (typeof input !== 'object' || input === undefined) {\n return 'statusLabel must be an object or null'\n }\n const { text, emoji } = input as { text?: unknown; emoji?: unknown }\n if (typeof text !== 'string') {\n return 'statusLabel.text must be a string'\n }\n if (emoji !== undefined && typeof emoji !== 'string') {\n return 'statusLabel.emoji must be a string'\n }\n const line = text.replace(/\\s+/g, ' ').trim()\n if (!line) {\n return null\n }\n if (line.length > STATUS_LABEL_TEXT_MAX) {\n return `statusLabel.text is longer than ${STATUS_LABEL_TEXT_MAX} characters`\n }\n const mark = emoji?.trim()\n if (mark && mark.length > STATUS_LABEL_EMOJI_MAX) {\n return `statusLabel.emoji is longer than ${STATUS_LABEL_EMOJI_MAX} characters`\n }\n return mark ? { text: line, emoji: mark } : { text: line }\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 set_status: 'Setting status',\n mcp__workerdeck__set_status: 'Setting status',\n change_avatar: 'Changing avatar',\n mcp__workerdeck__change_avatar: 'Changing avatar',\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 { StatusLabel, StatusLabelInput } from './status-label.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 | { type: 'status_label'; label: StatusLabel | null }\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 statusLabel?: StatusLabel\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 'status_label': {\n return 'status_label'\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; statusLabel?: StatusLabelInput | 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 './status-label.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
|
+
"version": "3.6.1",
|
|
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",
|