@cuongtran001/kanna 1.2.0 → 1.3.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.
Files changed (196) hide show
  1. package/dist/client/assets/{arc-BLk1CZKB.js → arc-DXtN3EWJ.js} +1 -1
  2. package/dist/client/assets/{architectureDiagram-3BPJPVTR-B01ZQYte.js → architectureDiagram-3BPJPVTR-CIGqW1z-.js} +1 -1
  3. package/dist/client/assets/{blockDiagram-GPEHLZMM-diL6a3cq.js → blockDiagram-GPEHLZMM-BafNS_H6.js} +1 -1
  4. package/dist/client/assets/{c4Diagram-AAUBKEIU-BY1verL8.js → c4Diagram-AAUBKEIU-YdAgRSis.js} +1 -1
  5. package/dist/client/assets/channel-BEYTrUAm.js +1 -0
  6. package/dist/client/assets/{chunk-2J33WTMH-psdZuajw.js → chunk-2J33WTMH-eiP5y5G-.js} +1 -1
  7. package/dist/client/assets/{chunk-4BX2VUAB-CrwQVBc5.js → chunk-4BX2VUAB-CvLGzPMF.js} +1 -1
  8. package/dist/client/assets/{chunk-55IACEB6-9-aj4jKO.js → chunk-55IACEB6-Y-S9Fb8A.js} +1 -1
  9. package/dist/client/assets/{chunk-727SXJPM-1FNK9_nB.js → chunk-727SXJPM-6sJH1RI9.js} +1 -1
  10. package/dist/client/assets/{chunk-AQP2D5EJ-DFhvd_Ek.js → chunk-AQP2D5EJ-hV1r_IXO.js} +1 -1
  11. package/dist/client/assets/{chunk-FMBD7UC4-B7MLrDa7.js → chunk-FMBD7UC4-CC3L28S5.js} +1 -1
  12. package/dist/client/assets/{chunk-ND2GUHAM-D4Df05QE.js → chunk-ND2GUHAM-BZ3czhdH.js} +1 -1
  13. package/dist/client/assets/{chunk-QZHKN3VN-Iq17Dznm.js → chunk-QZHKN3VN-Bjyd6Yr-.js} +1 -1
  14. package/dist/client/assets/classDiagram-4FO5ZUOK-CvnF5Ud6.js +1 -0
  15. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CvnF5Ud6.js +1 -0
  16. package/dist/client/assets/{cose-bilkent-S5V4N54A-BmaZhtXy.js → cose-bilkent-S5V4N54A-CfxdDghE.js} +1 -1
  17. package/dist/client/assets/{dagre-BM42HDAG-BCmpfnfP.js → dagre-BM42HDAG-B8CddsbB.js} +1 -1
  18. package/dist/client/assets/{diagram-2AECGRRQ-BIEcKowS.js → diagram-2AECGRRQ-F0yS0fVB.js} +1 -1
  19. package/dist/client/assets/{diagram-5GNKFQAL-CRBABBfv.js → diagram-5GNKFQAL-cW0i0qlh.js} +1 -1
  20. package/dist/client/assets/{diagram-KO2AKTUF-BRxUk16N.js → diagram-KO2AKTUF-BzAKMeJT.js} +1 -1
  21. package/dist/client/assets/{diagram-LMA3HP47-DPBs4xl1.js → diagram-LMA3HP47-qdC4XqIl.js} +1 -1
  22. package/dist/client/assets/{diagram-OG6HWLK6-BE9rgVv8.js → diagram-OG6HWLK6-CGcpi6Dh.js} +1 -1
  23. package/dist/client/assets/{erDiagram-TEJ5UH35-D3vgA1xJ.js → erDiagram-TEJ5UH35-CxNTDicM.js} +1 -1
  24. package/dist/client/assets/{flowDiagram-I6XJVG4X-Cgu-8XXC.js → flowDiagram-I6XJVG4X-qkGa5TqY.js} +1 -1
  25. package/dist/client/assets/{ganttDiagram-6RSMTGT7-CgjXVyTR.js → ganttDiagram-6RSMTGT7-D9mVPoQi.js} +1 -1
  26. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-zD5D8B-i.js → gitGraphDiagram-PVQCEYII-DA0grAXe.js} +1 -1
  27. package/dist/client/assets/{index-DBTdhMbJ.js → index-BqUY1Bm4.js} +1 -1
  28. package/dist/client/assets/index-CLsOWXff.css +32 -0
  29. package/dist/client/assets/{index-zQLLeAfl.js → index-TU1k6ov6.js} +253 -243
  30. package/dist/client/assets/{infoDiagram-5YYISTIA-BaFHqT4u.js → infoDiagram-5YYISTIA-CGljtLs3.js} +1 -1
  31. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-2yAC1br2.js → ishikawaDiagram-YF4QCWOH-CtC0xrmG.js} +1 -1
  32. package/dist/client/assets/{journeyDiagram-JHISSGLW-DacQ-ND5.js → journeyDiagram-JHISSGLW-URLnVZeN.js} +1 -1
  33. package/dist/client/assets/{kanban-definition-UN3LZRKU-Qlbwm3z4.js → kanban-definition-UN3LZRKU-C2Q6aqQh.js} +1 -1
  34. package/dist/client/assets/{linear-DeafqpgO.js → linear-ByKHtsIx.js} +1 -1
  35. package/dist/client/assets/{mermaid.core-KYiCPJDj.js → mermaid.core-Dl_f2KLc.js} +4 -4
  36. package/dist/client/assets/{mindmap-definition-RKZ34NQL-B1V-T6d3.js → mindmap-definition-RKZ34NQL-CaJ9IDLI.js} +1 -1
  37. package/dist/client/assets/{pieDiagram-4H26LBE5-DOF9OFRu.js → pieDiagram-4H26LBE5-mmYaf2Oa.js} +1 -1
  38. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-lH1mB7ko.js → quadrantDiagram-W4KKPZXB-B_PO6OCC.js} +1 -1
  39. package/dist/client/assets/{requirementDiagram-4Y6WPE33-BaTsJ_sS.js → requirementDiagram-4Y6WPE33-M4huwJt1.js} +1 -1
  40. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-Pfxib5iI.js → sankeyDiagram-5OEKKPKP-B0hb1sWh.js} +1 -1
  41. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-BQMEKkBC.js → sequenceDiagram-3UESZ5HK-BAqSptnA.js} +1 -1
  42. package/dist/client/assets/{stateDiagram-AJRCARHV-CuldNnzp.js → stateDiagram-AJRCARHV-DTNkvPi5.js} +1 -1
  43. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CVN3oGTF.js +1 -0
  44. package/dist/client/assets/{timeline-definition-PNZ67QCA-DP7u0YAg.js → timeline-definition-PNZ67QCA-MgAjHz8Q.js} +1 -1
  45. package/dist/client/assets/{vennDiagram-CIIHVFJN-QlrjpNeQ.js → vennDiagram-CIIHVFJN-DmKoO51W.js} +1 -1
  46. package/dist/client/assets/{wardley-L42UT6IY-BqdJ_sAM.js → wardley-L42UT6IY-CWcyHnYs.js} +1 -1
  47. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-Wi3kaQ5X.js → wardleyDiagram-YWT4CUSO-BGIGmFP9.js} +1 -1
  48. package/dist/client/assets/{xychartDiagram-2RQKCTM6-D-KXMyCG.js → xychartDiagram-2RQKCTM6-D20YIvEl.js} +1 -1
  49. package/dist/client/index.html +2 -2
  50. package/package.json +1 -1
  51. package/src/server/agent-coordinator-types.ts +158 -0
  52. package/src/server/agent-coordinator.ts +919 -0
  53. package/src/server/agent-deps-builders.ts +425 -0
  54. package/src/server/agent.oauth-rotation.test.ts +101 -0
  55. package/src/server/agent.test.ts +24 -8
  56. package/src/server/agent.ts +35 -4963
  57. package/src/server/auto-continue/read-model.test.ts +2 -2
  58. package/src/server/auto-continue/read-model.ts +4 -1
  59. package/src/server/claude-autocontinue-commands.test.ts +494 -0
  60. package/src/server/claude-autocontinue-commands.ts +256 -0
  61. package/src/server/claude-cancel-handler.test.ts +472 -0
  62. package/src/server/claude-cancel-handler.ts +241 -0
  63. package/src/server/claude-chat-management.test.ts +395 -0
  64. package/src/server/claude-chat-management.ts +251 -0
  65. package/src/server/claude-harness-stream.test.ts +273 -0
  66. package/src/server/claude-harness-stream.ts +158 -0
  67. package/src/server/claude-loop-orch-commands.test.ts +579 -0
  68. package/src/server/claude-loop-orch-commands.ts +466 -0
  69. package/src/server/claude-message-normalizer.test.ts +213 -0
  70. package/src/server/claude-message-normalizer.ts +436 -0
  71. package/src/server/claude-prompt-helpers.test.ts +248 -0
  72. package/src/server/claude-prompt-helpers.ts +139 -0
  73. package/src/server/claude-sdk-queue.test.ts +169 -0
  74. package/src/server/claude-sdk-queue.ts +82 -0
  75. package/src/server/claude-send-command.test.ts +414 -0
  76. package/src/server/claude-send-command.ts +420 -0
  77. package/src/server/claude-session-config-helpers.test.ts +279 -0
  78. package/src/server/claude-session-config-helpers.ts +151 -0
  79. package/src/server/claude-session-config.test.ts +250 -0
  80. package/src/server/claude-session-config.ts +159 -0
  81. package/src/server/claude-session-error-handler.test.ts +498 -0
  82. package/src/server/claude-session-error-handler.ts +361 -0
  83. package/src/server/claude-session-lifecycle.test.ts +669 -0
  84. package/src/server/claude-session-lifecycle.ts +283 -0
  85. package/src/server/claude-session-rebuild.test.ts +224 -0
  86. package/src/server/claude-session-rebuild.ts +101 -0
  87. package/src/server/claude-session-runner.test.ts +523 -0
  88. package/src/server/claude-session-runner.ts +521 -0
  89. package/src/server/claude-session-spawner.test.ts +401 -0
  90. package/src/server/claude-session-spawner.ts +401 -0
  91. package/src/server/claude-session-start.test.ts +205 -0
  92. package/src/server/claude-session-start.ts +277 -0
  93. package/src/server/claude-session-state-queries.test.ts +344 -0
  94. package/src/server/claude-session-state-queries.ts +160 -0
  95. package/src/server/claude-session-state.ts +104 -0
  96. package/src/server/claude-slash-commands.test.ts +277 -0
  97. package/src/server/claude-slash-commands.ts +234 -0
  98. package/src/server/claude-spawn-helpers.test.ts +221 -0
  99. package/src/server/claude-spawn-helpers.ts +179 -0
  100. package/src/server/claude-steer-log.test.ts +243 -0
  101. package/src/server/claude-steer-log.ts +58 -0
  102. package/src/server/claude-subagent-tool-response.test.ts +213 -0
  103. package/src/server/claude-subagent-tool-response.ts +165 -0
  104. package/src/server/claude-subagent-wiring.test.ts +263 -0
  105. package/src/server/claude-subagent-wiring.ts +324 -0
  106. package/src/server/claude-tool-respond.test.ts +321 -0
  107. package/src/server/claude-tool-respond.ts +142 -0
  108. package/src/server/claude-turn-runner.test.ts +310 -0
  109. package/src/server/claude-turn-runner.ts +228 -0
  110. package/src/server/claude-turn-starter.test.ts +266 -0
  111. package/src/server/claude-turn-starter.ts +566 -0
  112. package/src/server/claude-usage-math.test.ts +169 -0
  113. package/src/server/claude-usage-math.ts +132 -0
  114. package/src/server/diff-store-branch-ops.adapter.test.ts +332 -0
  115. package/src/server/diff-store-branch-ops.adapter.ts +602 -0
  116. package/src/server/diff-store-commit-ops.adapter.test.ts +358 -0
  117. package/src/server/diff-store-commit-ops.adapter.ts +258 -0
  118. package/src/server/diff-store-errors.ts +85 -0
  119. package/src/server/diff-store-file-ops.adapter.ts +212 -0
  120. package/src/server/diff-store-git-branch.adapter.ts +686 -0
  121. package/src/server/diff-store-io.adapter.ts +27 -0
  122. package/src/server/diff-store-parse.test.ts +212 -0
  123. package/src/server/diff-store-parse.ts +122 -0
  124. package/src/server/diff-store-state.ts +82 -0
  125. package/src/server/diff-store.ts +76 -1854
  126. package/src/server/event-store-apply.test.ts +280 -0
  127. package/src/server/event-store-apply.ts +132 -0
  128. package/src/server/event-store-chat-lifecycle.test.ts +408 -0
  129. package/src/server/event-store-chat-lifecycle.ts +441 -0
  130. package/src/server/event-store-entity-write.ts +356 -0
  131. package/src/server/event-store-helpers.test.ts +230 -0
  132. package/src/server/event-store-helpers.ts +235 -0
  133. package/src/server/event-store-init.ts +276 -0
  134. package/src/server/event-store-messages.adapter.test.ts +365 -0
  135. package/src/server/event-store-messages.adapter.ts +213 -0
  136. package/src/server/event-store-orch-subscription.ts +124 -0
  137. package/src/server/event-store-orch.test.ts +462 -0
  138. package/src/server/event-store-orch.ts +312 -0
  139. package/src/server/event-store-peripheral-events.adapter.test.ts +254 -0
  140. package/src/server/event-store-peripheral-events.adapter.ts +105 -0
  141. package/src/server/event-store-snapshot.test.ts +597 -0
  142. package/src/server/event-store-snapshot.ts +658 -0
  143. package/src/server/event-store-subagent.test.ts +408 -0
  144. package/src/server/event-store-subagent.ts +198 -0
  145. package/src/server/event-store-tool-requests.test.ts +210 -0
  146. package/src/server/event-store-tool-requests.ts +131 -0
  147. package/src/server/event-store-transcript-write.adapter.ts +285 -0
  148. package/src/server/event-store-write-ops.test.ts +554 -0
  149. package/src/server/event-store-write-ops.ts +529 -0
  150. package/src/server/event-store.test.ts +35 -0
  151. package/src/server/event-store.ts +251 -2284
  152. package/src/server/events.ts +3 -0
  153. package/src/server/harness-types.ts +15 -1
  154. package/src/server/oauth-errors.ts +19 -0
  155. package/src/server/read-models.ts +26 -1
  156. package/src/server/subagent-orchestrator.ts +3 -0
  157. package/src/server/ws-router-agent-ctrl.test.ts +187 -0
  158. package/src/server/ws-router-agent-ctrl.ts +137 -0
  159. package/src/server/ws-router-broadcast.ts +488 -0
  160. package/src/server/ws-router-chat.test.ts +461 -0
  161. package/src/server/ws-router-chat.ts +279 -0
  162. package/src/server/ws-router-defaults.test.ts +283 -0
  163. package/src/server/ws-router-defaults.ts +434 -0
  164. package/src/server/ws-router-diff.test.ts +167 -0
  165. package/src/server/ws-router-diff.ts +250 -0
  166. package/src/server/ws-router-envelope.ts +329 -0
  167. package/src/server/ws-router-misc.test.ts +422 -0
  168. package/src/server/ws-router-misc.ts +265 -0
  169. package/src/server/ws-router-orch.test.ts +190 -0
  170. package/src/server/ws-router-orch.ts +93 -0
  171. package/src/server/ws-router-project.test.ts +403 -0
  172. package/src/server/ws-router-project.ts +256 -0
  173. package/src/server/ws-router-push.test.ts +193 -0
  174. package/src/server/ws-router-push.ts +120 -0
  175. package/src/server/ws-router-settings.test.ts +173 -0
  176. package/src/server/ws-router-settings.ts +416 -0
  177. package/src/server/ws-router-skills.test.ts +194 -0
  178. package/src/server/ws-router-skills.ts +204 -0
  179. package/src/server/ws-router-utils.ts +224 -0
  180. package/src/server/ws-router.ts +339 -2254
  181. package/src/shared/app-settings-types.ts +365 -0
  182. package/src/shared/core-types.ts +27 -0
  183. package/src/shared/git-diff-types.ts +165 -0
  184. package/src/shared/loop-progress.test.ts +106 -0
  185. package/src/shared/loop-progress.ts +88 -0
  186. package/src/shared/mcp-types.ts +105 -0
  187. package/src/shared/provider-model-types.ts +437 -0
  188. package/src/shared/subagent-types.ts +198 -0
  189. package/src/shared/tool-call-types.ts +314 -0
  190. package/src/shared/transcript-types.ts +270 -0
  191. package/src/shared/types.ts +27 -1668
  192. package/dist/client/assets/channel-BMkhjiLI.js +0 -1
  193. package/dist/client/assets/classDiagram-4FO5ZUOK-C5Kg1XOD.js +0 -1
  194. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-C5Kg1XOD.js +0 -1
  195. package/dist/client/assets/index-H6C-f2Vp.css +0 -32
  196. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-Ca2U11af.js +0 -1
@@ -1,34 +1,29 @@
1
- import type { ChatPermissionPolicyOverride, ToolRequestDecision, ToolRequestStatus } from "./permission-policy"
1
+ import type { ChatPermissionPolicyOverride } from "./permission-policy"
2
+
3
+ // Re-export domain-specific type modules — extracted to keep this barrel lean.
4
+ // All external consumers importing from "../shared/types" continue to work unchanged.
5
+ export * from "./core-types"
6
+ export * from "./provider-model-types"
7
+ export * from "./tool-call-types"
8
+ export * from "./transcript-types"
9
+ export * from "./mcp-types"
10
+ export * from "./subagent-types"
11
+ export * from "./app-settings-types"
12
+ export * from "./git-diff-types"
13
+
14
+ // Import the re-exported names we reference in the body of this file.
15
+ // (export * makes them available to importers, but not within this file itself.)
16
+ import type { AgentProvider, KannaStatus, AttachmentKind, LlmProviderKind } from "./core-types"
2
17
  import type {
3
- OAuthTokens,
4
- OAuthClientInformationFull,
5
- AuthorizationServerMetadata,
6
- } from "@modelcontextprotocol/sdk/shared/auth.js"
7
-
8
- export const STORE_VERSION = 3 as const
9
- export const PROTOCOL_VERSION = 1 as const
10
-
11
- export type AgentProvider = "claude" | "codex" | "openrouter"
12
- export type LlmProviderKind = "openai" | "openrouter" | "custom"
13
- export type AppThemePreference = "light" | "dark" | "system"
14
- export type ChatSoundPreference = "never" | "unfocused" | "always"
15
- export type ChatSoundId = "blow" | "bottle" | "frog" | "funk" | "glass" | "ping" | "pop" | "purr" | "tink"
16
- export type DefaultProviderPreference = "last_used" | AgentProvider
17
- export type EditorPreset = "cursor" | "vscode" | "xcode" | "windsurf" | "custom"
18
- export const DEFAULT_OPENAI_SDK_MODEL = "gpt-5.4-mini"
19
- export const DEFAULT_OPENROUTER_SDK_MODEL = "moonshotai/kimi-k2.5:nitro"
20
-
21
- export const OPENROUTER_BASE_URL = "https://openrouter.ai/api"
22
- export const OPENROUTER_MODELS_URL = "https://openrouter.ai/api/v1/models"
23
-
24
- export interface OpenRouterModel {
25
- id: string
26
- label: string
27
- contextLength: number
28
- pricing?: { promptPerTok: number; completionPerTok: number }
29
- }
30
-
31
- export type AttachmentKind = "image" | "file" | "mention"
18
+ ModelOptions,
19
+ ProviderCatalogEntry,
20
+ } from "./provider-model-types"
21
+ import type { TranscriptEntry } from "./transcript-types"
22
+ import type {
23
+ ClaudeSessionLifecycleStatus,
24
+ CloudflareTunnelRecord,
25
+ } from "./app-settings-types"
26
+ import type { SubagentRunSnapshot, LoopProgressSnapshot } from "./subagent-types"
32
27
 
33
28
  export interface SkillSearchResult {
34
29
  id: string
@@ -119,572 +114,6 @@ export interface InternalUserAttachmentsData {
119
114
  llmHintText: string
120
115
  }
121
116
 
122
- export interface ProviderModelOption {
123
- id: string
124
- label: string
125
- supportsEffort: boolean
126
- aliases?: readonly string[]
127
- contextWindowOptions?: readonly ProviderContextWindowOption[]
128
- supportsMaxReasoningEffort?: boolean
129
- }
130
-
131
- export interface ProviderEffortOption {
132
- id: string
133
- label: string
134
- }
135
-
136
- export interface ProviderContextWindowOption {
137
- id: ClaudeContextWindow
138
- label: string
139
- }
140
-
141
- export const CLAUDE_REASONING_OPTIONS = [
142
- { id: "low", label: "Low" },
143
- { id: "medium", label: "Medium" },
144
- { id: "high", label: "High" },
145
- { id: "max", label: "Max" },
146
- ] as const satisfies readonly ProviderEffortOption[]
147
-
148
- export const CODEX_REASONING_OPTIONS = [
149
- { id: "minimal", label: "Minimal" },
150
- { id: "low", label: "Low" },
151
- { id: "medium", label: "Medium" },
152
- { id: "high", label: "High" },
153
- { id: "xhigh", label: "XHigh" },
154
- ] as const satisfies readonly ProviderEffortOption[]
155
-
156
- export type ClaudeReasoningEffort = (typeof CLAUDE_REASONING_OPTIONS)[number]["id"]
157
- export type CodexReasoningEffort = (typeof CODEX_REASONING_OPTIONS)[number]["id"]
158
- export type ClaudeContextWindow = "200k" | "1m"
159
- export type ServiceTier = "fast"
160
-
161
- export interface ClaudeModelOptions {
162
- reasoningEffort: ClaudeReasoningEffort
163
- contextWindow: ClaudeContextWindow
164
- }
165
-
166
- export interface CodexModelOptions {
167
- reasoningEffort: CodexReasoningEffort
168
- fastMode: boolean
169
- }
170
-
171
- export type OpenRouterModelOptions = Record<string, never>
172
-
173
- export interface ProviderModelOptionsByProvider {
174
- claude: ClaudeModelOptions
175
- codex: CodexModelOptions
176
- openrouter: OpenRouterModelOptions
177
- }
178
-
179
- export interface ProviderPreference<TModelOptions> {
180
- model: string
181
- modelOptions: TModelOptions
182
- planMode: boolean
183
- }
184
-
185
- export type ChatProviderPreferences = {
186
- claude: ProviderPreference<ClaudeModelOptions>
187
- codex: ProviderPreference<CodexModelOptions>
188
- openrouter: ProviderPreference<OpenRouterModelOptions>
189
- }
190
-
191
- export type SubagentContextScope = "previous-assistant-reply" | "full-transcript"
192
-
193
- export type SubagentTriggerMode = "auto" | "manual"
194
-
195
- export interface SubagentRestriction {
196
- workingDir?: string
197
- allowedPaths?: string[]
198
- }
199
-
200
- export interface Subagent {
201
- id: string
202
- name: string
203
- description?: string
204
- provider: AgentProvider
205
- model: string
206
- modelOptions: ClaudeModelOptions | CodexModelOptions
207
- systemPrompt: string
208
- contextScope: SubagentContextScope
209
- triggerMode: SubagentTriggerMode
210
- workingDir?: string
211
- allowedPaths?: string[]
212
- // Per-subagent agentic-turn bound — the analog of Claude Code's agent
213
- // frontmatter `maxTurns`. Unset = unbounded (Claude Code's default).
214
- // Claude-SDK runs pass it natively to query() (graceful stop, output kept);
215
- // PTY/Codex runs get a host-side tool-call-count backstop (hard abort).
216
- maxTurns?: number
217
- createdAt: number
218
- updatedAt: number
219
- }
220
-
221
- export interface SubagentInput {
222
- name: string
223
- description?: string
224
- provider: AgentProvider
225
- model: string
226
- modelOptions: ClaudeModelOptions | CodexModelOptions
227
- systemPrompt: string
228
- contextScope: SubagentContextScope
229
- triggerMode?: SubagentTriggerMode
230
- workingDir?: string
231
- allowedPaths?: string[]
232
- maxTurns?: number
233
- }
234
-
235
- export interface SubagentPatch {
236
- name?: string
237
- description?: string | null
238
- provider?: AgentProvider
239
- model?: string
240
- modelOptions?: Partial<ClaudeModelOptions> | Partial<CodexModelOptions>
241
- systemPrompt?: string
242
- contextScope?: SubagentContextScope
243
- triggerMode?: SubagentTriggerMode
244
- workingDir?: string | null
245
- allowedPaths?: string[] | null
246
- maxTurns?: number | null
247
- }
248
-
249
- export type SubagentValidationErrorCode =
250
- | "EMPTY_NAME"
251
- | "INVALID_CHAR"
252
- | "RESERVED_NAME"
253
- | "DUPLICATE_NAME"
254
- | "TOO_LONG"
255
- | "NOT_FOUND"
256
- | "RESTRICTION_NOT_SUPPORTED"
257
- | "INVALID_PATH"
258
- | "PATH_ESCAPE"
259
- | "EMPTY_ALLOWED_PATHS"
260
-
261
- export interface SubagentValidationError {
262
- code: SubagentValidationErrorCode
263
- message: string
264
- }
265
-
266
- export type McpServerTransport = "stdio" | "http" | "sse" | "ws"
267
-
268
- export type McpServerTestResult =
269
- | { status: "untested" }
270
- | { status: "pending"; startedAt: string }
271
- | { status: "ok"; testedAt: string; toolCount: number }
272
- | { status: "error"; testedAt: string; message: string }
273
-
274
- export interface McpOAuthFlowState {
275
- codeVerifier: string
276
- state: string
277
- issuer: string
278
- authorizationUrl: string
279
- // AS metadata cached between start and complete (avoids re-discovery)
280
- metadata: AuthorizationServerMetadata
281
- }
282
-
283
- export interface McpOAuthState {
284
- enabled: boolean
285
- status: "unauthenticated" | "authenticated" | "error"
286
- errorMessage?: string
287
- // resolved AS issuer (set on complete; used by refresh without re-discovery)
288
- issuer?: string
289
- // cached AS metadata (token_endpoint, etc.) persisted at complete so refresh
290
- // uses it directly instead of re-discovering from issuer (which may be a
291
- // non-resolvable resource URL, e.g. claude.ai design MCP)
292
- metadata?: AuthorizationServerMetadata
293
- // DCR result keyed by AS issuer (SEP-2352)
294
- clientByIssuer?: Record<string, OAuthClientInformationFull>
295
- tokens?: OAuthTokens
296
- obtainedAt?: number
297
- // present only mid-flow; cleared on complete/cancel
298
- flow?: McpOAuthFlowState
299
- }
300
-
301
- interface McpServerBase {
302
- id: string
303
- name: string
304
- enabled: boolean
305
- createdAt: string
306
- updatedAt: string
307
- lastTest: McpServerTestResult
308
- }
309
-
310
- export interface McpServerStdioFields {
311
- transport: "stdio"
312
- command: string
313
- args: string[]
314
- env: Record<string, string>
315
- cwd?: string
316
- }
317
-
318
- export interface McpServerNetworkFields {
319
- transport: "http" | "sse" | "ws"
320
- url: string
321
- headers: Record<string, string>
322
- oauth?: McpOAuthState
323
- }
324
-
325
- export type McpServerConfig =
326
- | (McpServerBase & McpServerStdioFields)
327
- | (McpServerBase & McpServerNetworkFields)
328
-
329
- export type McpServerInput =
330
- | (McpServerStdioFields & { name: string; enabled?: boolean })
331
- | (McpServerNetworkFields & { name: string; enabled?: boolean })
332
-
333
- export type McpServerPatch = Partial<{
334
- name: string
335
- enabled: boolean
336
- transport: McpServerTransport
337
- command: string
338
- args: string[]
339
- env: Record<string, string>
340
- cwd: string | undefined
341
- url: string
342
- headers: Record<string, string>
343
- oauth: McpOAuthState
344
- }>
345
-
346
- export interface McpValidationError {
347
- code:
348
- | "INVALID_NAME"
349
- | "DUPLICATE_NAME"
350
- | "RESERVED_NAME"
351
- | "INVALID_TRANSPORT"
352
- | "MISSING_COMMAND"
353
- | "INVALID_URL"
354
- | "INVALID_HEADER_KEY"
355
- | "INVALID_ENV_KEY"
356
- | "NOT_FOUND"
357
- | "INVALID_OAUTH_TRANSPORT"
358
- field?: string
359
- message: string
360
- }
361
-
362
- export type ModelOptions = Partial<{
363
- [K in AgentProvider]: Partial<ProviderModelOptionsByProvider[K]>
364
- }>
365
-
366
- export const DEFAULT_CLAUDE_MODEL_OPTIONS = {
367
- reasoningEffort: "high",
368
- contextWindow: "200k",
369
- } as const satisfies ClaudeModelOptions
370
-
371
- export const DEFAULT_CODEX_MODEL_OPTIONS = {
372
- reasoningEffort: "high",
373
- fastMode: false,
374
- } as const satisfies CodexModelOptions
375
-
376
- export function isClaudeReasoningEffort(value: string | null | undefined): value is ClaudeReasoningEffort {
377
- return CLAUDE_REASONING_OPTIONS.some((option) => option.id === value)
378
- }
379
-
380
- export function isCodexReasoningEffort(value: string | null | undefined): value is CodexReasoningEffort {
381
- return CODEX_REASONING_OPTIONS.some((option) => option.id === value)
382
- }
383
-
384
- export const CLAUDE_CONTEXT_WINDOW_OPTIONS = [
385
- { id: "200k", label: "200k" },
386
- { id: "1m", label: "1M" },
387
- ] as const satisfies readonly ProviderContextWindowOption[]
388
-
389
- export function isClaudeContextWindow(value: string | null | undefined): value is ClaudeContextWindow {
390
- return CLAUDE_CONTEXT_WINDOW_OPTIONS.some((option) => option.id === value)
391
- }
392
-
393
- export interface ProviderCatalogEntry {
394
- id: AgentProvider
395
- label: string
396
- defaultModel: string
397
- defaultEffort?: string
398
- supportsPlanMode: boolean
399
- models: ProviderModelOption[]
400
- efforts: ProviderEffortOption[]
401
- }
402
-
403
- export const PROVIDERS: ProviderCatalogEntry[] = [
404
- {
405
- id: "claude",
406
- label: "Claude",
407
- defaultModel: "claude-sonnet-4-6",
408
- defaultEffort: "high",
409
- supportsPlanMode: true,
410
- models: [
411
- {
412
- id: "claude-fable-5",
413
- label: "Fable 5",
414
- supportsEffort: true,
415
- aliases: ["fable"],
416
- contextWindowOptions: [...CLAUDE_CONTEXT_WINDOW_OPTIONS],
417
- supportsMaxReasoningEffort: true,
418
- },
419
- {
420
- id: "claude-opus-4-7",
421
- label: "Opus 4.7",
422
- supportsEffort: true,
423
- aliases: ["opus"],
424
- contextWindowOptions: [...CLAUDE_CONTEXT_WINDOW_OPTIONS],
425
- supportsMaxReasoningEffort: true,
426
- },
427
- {
428
- id: "claude-sonnet-4-6",
429
- label: "Sonnet 4.6",
430
- supportsEffort: true,
431
- aliases: ["sonnet"],
432
- contextWindowOptions: [...CLAUDE_CONTEXT_WINDOW_OPTIONS],
433
- },
434
- {
435
- id: "claude-haiku-4-5-20251001",
436
- label: "Haiku 4.5",
437
- supportsEffort: true,
438
- aliases: ["haiku"],
439
- },
440
- {
441
- id: "claude-opus-4-8",
442
- label: "Opus 4.8",
443
- supportsEffort: true,
444
- aliases: ["opus-4-8"],
445
- contextWindowOptions: [...CLAUDE_CONTEXT_WINDOW_OPTIONS],
446
- supportsMaxReasoningEffort: true,
447
- },
448
- ],
449
- efforts: [...CLAUDE_REASONING_OPTIONS],
450
- },
451
- {
452
- id: "codex",
453
- label: "Codex",
454
- defaultModel: "gpt-5.5",
455
- supportsPlanMode: true,
456
- models: [
457
- { id: "gpt-5.5", label: "GPT-5.5", supportsEffort: false },
458
- { id: "gpt-5.4", label: "GPT-5.4", supportsEffort: false },
459
- { id: "gpt-5.3-codex", label: "GPT-5.3 Codex", supportsEffort: false, aliases: ["gpt-5-codex"] },
460
- { id: "gpt-5.3-codex-spark", label: "GPT-5.3 Codex Spark", supportsEffort: false },
461
- ],
462
- efforts: [],
463
- },
464
- {
465
- id: "openrouter",
466
- label: "OpenRouter",
467
- defaultModel: DEFAULT_OPENROUTER_SDK_MODEL,
468
- supportsPlanMode: true,
469
- models: [],
470
- efforts: [],
471
- },
472
- ]
473
-
474
- export function getProviderCatalog(provider: AgentProvider): ProviderCatalogEntry {
475
- const entry = PROVIDERS.find((candidate) => candidate.id === provider)
476
- if (!entry) {
477
- throw new Error(`Unknown provider: ${provider}`)
478
- }
479
- return entry
480
- }
481
-
482
- export interface CustomModelEntry {
483
- id: string
484
- label: string
485
- provider: "claude" | "codex"
486
- supportsEffort: boolean
487
- aliases?: readonly string[]
488
- contextWindowOptions?: readonly ProviderContextWindowOption[]
489
- supportsMaxReasoningEffort?: boolean
490
- createdAt: number
491
- updatedAt: number
492
- }
493
-
494
- export interface CustomModelInput {
495
- id: string
496
- label: string
497
- provider: "claude" | "codex"
498
- supportsEffort: boolean
499
- aliases?: readonly string[]
500
- contextWindowOptions?: readonly ProviderContextWindowOption[]
501
- supportsMaxReasoningEffort?: boolean
502
- }
503
-
504
- export interface CustomModelPatch {
505
- label?: string
506
- supportsEffort?: boolean
507
- aliases?: readonly string[] | null
508
- contextWindowOptions?: readonly ProviderContextWindowOption[] | null
509
- supportsMaxReasoningEffort?: boolean
510
- }
511
-
512
- export interface TextSnippet {
513
- id: string
514
- shortcut: string
515
- expansion: string
516
- createdAt: number
517
- updatedAt: number
518
- }
519
-
520
- export interface TextSnippetInput {
521
- shortcut: string
522
- expansion: string
523
- }
524
-
525
- export interface TextSnippetPatch {
526
- shortcut?: string
527
- expansion?: string
528
- }
529
-
530
- function customEntryToModelOption(entry: CustomModelEntry): ProviderModelOption {
531
- return {
532
- id: entry.id,
533
- label: entry.label,
534
- supportsEffort: entry.supportsEffort,
535
- ...(entry.aliases ? { aliases: entry.aliases } : {}),
536
- ...(entry.contextWindowOptions ? { contextWindowOptions: entry.contextWindowOptions } : {}),
537
- ...(entry.supportsMaxReasoningEffort !== undefined ? { supportsMaxReasoningEffort: entry.supportsMaxReasoningEffort } : {}),
538
- }
539
- }
540
-
541
- export function mergeCustomModels(
542
- base: ProviderCatalogEntry[],
543
- customModels: readonly CustomModelEntry[],
544
- ): ProviderCatalogEntry[] {
545
- return base.map((entry) => {
546
- if (entry.id !== "claude" && entry.id !== "codex") return { ...entry, models: [...entry.models] }
547
- const forProvider = customModels.filter((m) => m.provider === entry.id)
548
- if (forProvider.length === 0) return { ...entry, models: [...entry.models] }
549
- const models = [...entry.models]
550
- for (const custom of forProvider) {
551
- const option = customEntryToModelOption(custom)
552
- const idx = models.findIndex((m) => m.id === option.id)
553
- if (idx >= 0) models[idx] = option
554
- else models.push(option)
555
- }
556
- return { ...entry, models }
557
- })
558
- }
559
-
560
- /**
561
- * True when the provider's turns run through the Claude SDK session transport
562
- * (a live `claudeSessions` entry consumed by `runClaudeSession`, prompts
563
- * delivered via `session.sendPrompt`) rather than the generic harness-turn
564
- * transport (`runTurn` over `active.turn.stream`).
565
- *
566
- * `claude` and `openrouter` both ride the SDK session — openrouter just points
567
- * the SDK at OpenRouter's Anthropic-compatible endpoint. Branching on
568
- * `provider === "claude"` where the real intent is "uses the SDK session" is
569
- * what silently dropped openrouter's prompt delivery; use this predicate so a
570
- * new SDK-backed provider can never be forgotten by an `if`-chain again.
571
- */
572
- export function providerUsesSdkSession(provider: AgentProvider): boolean {
573
- return provider === "claude" || provider === "openrouter"
574
- }
575
-
576
- function catalogModelsFor(
577
- provider: AgentProvider,
578
- customModels?: readonly CustomModelEntry[],
579
- ): readonly ProviderModelOption[] {
580
- const catalog = getProviderCatalog(provider)
581
- if (!customModels || customModels.length === 0) return catalog.models
582
- const [merged] = mergeCustomModels([{ ...catalog, models: [...catalog.models] }], customModels)
583
- return merged.models
584
- }
585
-
586
- function getProviderModelMatch(
587
- provider: AgentProvider,
588
- modelId?: string,
589
- customModels?: readonly CustomModelEntry[],
590
- ): ProviderModelOption | undefined {
591
- if (!modelId) return undefined
592
-
593
- return catalogModelsFor(provider, customModels).find((candidate) =>
594
- candidate.id === modelId || candidate.aliases?.includes(modelId)
595
- )
596
- }
597
-
598
- export function normalizeProviderModelId(
599
- provider: AgentProvider,
600
- modelId?: string,
601
- fallbackModelId?: string,
602
- customModels?: readonly CustomModelEntry[],
603
- ): string {
604
- return getProviderModelMatch(provider, modelId, customModels)?.id
605
- ?? fallbackModelId
606
- ?? getProviderCatalog(provider).defaultModel
607
- }
608
-
609
- export function normalizeClaudeModelId(
610
- modelId?: string,
611
- fallbackModelId = "claude-opus-4-7",
612
- customModels?: readonly CustomModelEntry[],
613
- ): string {
614
- return normalizeProviderModelId("claude", modelId, fallbackModelId, customModels)
615
- }
616
-
617
- export function normalizeCodexModelId(
618
- modelId?: string,
619
- fallbackModelId = "gpt-5.5",
620
- customModels?: readonly CustomModelEntry[],
621
- ): string {
622
- return normalizeProviderModelId("codex", modelId, fallbackModelId, customModels)
623
- }
624
-
625
- export function getProviderModelOption(
626
- provider: AgentProvider,
627
- modelId: string,
628
- customModels?: readonly CustomModelEntry[],
629
- ): ProviderModelOption | undefined {
630
- const normalizedModelId = normalizeProviderModelId(provider, modelId, undefined, customModels)
631
- return catalogModelsFor(provider, customModels).find((candidate) => candidate.id === normalizedModelId)
632
- }
633
-
634
- export function getClaudeModelOption(
635
- modelId: string,
636
- customModels?: readonly CustomModelEntry[],
637
- ): ProviderModelOption | undefined {
638
- return getProviderModelOption("claude", modelId, customModels)
639
- }
640
-
641
- export function supportsClaudeMaxReasoningEffort(
642
- modelId: string,
643
- customModels?: readonly CustomModelEntry[],
644
- ): boolean {
645
- return Boolean(getClaudeModelOption(modelId, customModels)?.supportsMaxReasoningEffort)
646
- }
647
-
648
- export function getClaudeContextWindowOptions(
649
- modelId: string,
650
- customModels?: readonly CustomModelEntry[],
651
- ): readonly ProviderContextWindowOption[] {
652
- return getClaudeModelOption(modelId, customModels)?.contextWindowOptions ?? []
653
- }
654
-
655
- export function normalizeClaudeContextWindow(
656
- modelId: string,
657
- contextWindow?: string,
658
- customModels?: readonly CustomModelEntry[],
659
- ): ClaudeContextWindow {
660
- const options = getClaudeContextWindowOptions(modelId, customModels)
661
- if (options.length === 0) return DEFAULT_CLAUDE_MODEL_OPTIONS.contextWindow
662
- return isClaudeContextWindow(contextWindow) && options.some((option) => option.id === contextWindow)
663
- ? contextWindow
664
- : DEFAULT_CLAUDE_MODEL_OPTIONS.contextWindow
665
- }
666
-
667
- export function resolveClaudeApiModelId(modelId: string, contextWindow?: ClaudeContextWindow): string {
668
- return contextWindow === "1m" ? `${modelId}[1m]` : modelId
669
- }
670
-
671
- export function resolveClaudeContextWindowTokens(contextWindow: ClaudeContextWindow): number {
672
- switch (contextWindow) {
673
- case "1m":
674
- return 1_000_000
675
- case "200k":
676
- default:
677
- return 200_000
678
- }
679
- }
680
-
681
- export type KannaStatus =
682
- | "idle"
683
- | "starting"
684
- | "running"
685
- | "waiting_for_user"
686
- | "failed"
687
-
688
117
  export type PushTransitionKind = "waiting_for_user" | "failed" | "completed"
689
118
 
690
119
  export interface PushSubscriptionRecord {
@@ -819,208 +248,6 @@ export interface LocalProjectsSnapshot {
819
248
  projects: LocalProjectSummary[]
820
249
  }
821
250
 
822
- export interface AuthSettings {
823
- sessionMaxAgeDays: number
824
- }
825
-
826
- export const AUTH_DEFAULTS: AuthSettings = {
827
- sessionMaxAgeDays: 30,
828
- }
829
-
830
- export const AUTH_SESSION_MAX_AGE_DAYS_MIN = 1
831
- export const AUTH_SESSION_MAX_AGE_DAYS_MAX = 365
832
-
833
- export type OAuthTokenStatus = "active" | "limited" | "error" | "disabled"
834
-
835
- export interface OAuthTokenEntry {
836
- id: string
837
- label: string
838
- token: string
839
- status: OAuthTokenStatus
840
- limitedUntil: number | null
841
- lastUsedAt: number | null
842
- lastErrorAt: number | null
843
- lastErrorMessage: string | null
844
- addedAt: number
845
- // Per-token concurrent-chat cap. When omitted, the pool falls back to
846
- // ClaudeAuthSettings.concurrencyDefault. Default 1 preserves the
847
- // historical 1-token-per-chat invariant. Range
848
- // [OAUTH_TOKEN_MAX_CONCURRENT_MIN, OAUTH_TOKEN_MAX_CONCURRENT_MAX].
849
- maxConcurrent?: number
850
- }
851
-
852
- export interface ClaudeAuthSettings {
853
- tokens: OAuthTokenEntry[]
854
- // Pool-wide default applied to tokens whose maxConcurrent is omitted.
855
- concurrencyDefault: number
856
- }
857
-
858
- export const OAUTH_TOKEN_MAX_CONCURRENT_MIN = 1
859
- export const OAUTH_TOKEN_MAX_CONCURRENT_MAX = 5
860
- export const OAUTH_TOKEN_CONCURRENCY_DEFAULT = 1
861
-
862
- export const CLAUDE_AUTH_DEFAULTS: ClaudeAuthSettings = {
863
- tokens: [],
864
- concurrencyDefault: OAUTH_TOKEN_CONCURRENCY_DEFAULT,
865
- }
866
-
867
- export const OAUTH_TOKEN_LABEL_MAX = 64
868
- export const OAUTH_TOKEN_VALUE_MAX = 1024
869
-
870
- export interface UploadSettings {
871
- maxFileSizeMb: number
872
- }
873
-
874
- export const UPLOAD_DEFAULTS: UploadSettings = {
875
- maxFileSizeMb: 100,
876
- }
877
-
878
- export const UPLOAD_MAX_FILE_SIZE_MB_MIN = 1
879
- export const UPLOAD_MAX_FILE_SIZE_MB_MAX = 2048
880
-
881
- export const GLOBAL_PROMPT_APPEND_MAX_CHARS = 8_000
882
-
883
- export type ClaudeDriverPreference = "sdk" | "pty"
884
-
885
- export const CLAUDE_DRIVER_VALUES: readonly ClaudeDriverPreference[] = ["sdk", "pty"]
886
-
887
- export function isClaudeDriverPreference(value: string | null | undefined): value is ClaudeDriverPreference {
888
- return value === "sdk" || value === "pty"
889
- }
890
-
891
- export interface ClaudePtyLifecycleSettings {
892
- idleTimeoutMs: number
893
- maxConcurrent: number
894
- }
895
-
896
- export const CLAUDE_PTY_LIFECYCLE_DEFAULTS: ClaudePtyLifecycleSettings = {
897
- idleTimeoutMs: 600_000,
898
- maxConcurrent: 4,
899
- }
900
-
901
- export const CLAUDE_PTY_IDLE_TIMEOUT_MS_MIN = 60_000
902
- export const CLAUDE_PTY_IDLE_TIMEOUT_MS_MAX = 3_600_000
903
- export const CLAUDE_PTY_MAX_CONCURRENT_MIN = 1
904
- export const CLAUDE_PTY_MAX_CONCURRENT_MAX = 16
905
-
906
- export interface ClaudeDriverSettings {
907
- preference: ClaudeDriverPreference
908
- lifecycle: ClaudePtyLifecycleSettings
909
- }
910
-
911
- export const CLAUDE_DRIVER_DEFAULTS: ClaudeDriverSettings = {
912
- preference: "sdk",
913
- lifecycle: { ...CLAUDE_PTY_LIFECYCLE_DEFAULTS },
914
- }
915
-
916
- export type ClaudeSessionLifecycleStatus = "cold" | "warming" | "active" | "idle" | "cooling"
917
-
918
- export interface ChatSessionStateSnapshot {
919
- chatId: string
920
- state: ClaudeSessionLifecycleStatus
921
- updatedAt: number
922
- }
923
-
924
- export interface AppSettingsSnapshot {
925
- analyticsEnabled: boolean
926
- browserSettingsMigrated: boolean
927
- theme: AppThemePreference
928
- chatSoundPreference: ChatSoundPreference
929
- chatSoundId: ChatSoundId
930
- terminal: {
931
- scrollbackLines: number
932
- minColumnWidth: number
933
- }
934
- editor: {
935
- preset: EditorPreset
936
- commandTemplate: string
937
- }
938
- defaultProvider: DefaultProviderPreference
939
- providerDefaults: ChatProviderPreferences
940
- warning: string | null
941
- filePathDisplay: string
942
- cloudflareTunnel: CloudflareTunnelSettings
943
- auth: AuthSettings
944
- claudeAuth: ClaudeAuthSettings
945
- uploads: UploadSettings
946
- subagents: Subagent[]
947
- customMcpServers: McpServerConfig[]
948
- customModels: CustomModelEntry[]
949
- textSnippets: TextSnippet[]
950
- claudeDriver: ClaudeDriverSettings
951
- globalPromptAppend: string
952
- shareDefaultTtlHours: number
953
- subagentRuntime: SubagentRuntimeSettings
954
- }
955
-
956
- /**
957
- * Runtime knobs for delegated subagent runs (delegate_subagent) and the
958
- * autonomous loop (setup_loop). `runTimeoutMs` is the stall/idle watchdog
959
- * window — a run is aborted only after this long with NO streamed activity,
960
- * not a total wall-clock cap. `defaultLoopSubagentId` is the subagent
961
- * setup_loop delegates to when the caller omits an explicit id.
962
- */
963
- export interface SubagentRuntimeSettings {
964
- runTimeoutMs: number
965
- defaultLoopSubagentId: string | null
966
- /**
967
- * Subagent an orchestration run (orch_run) delegates each phase to when the
968
- * caller omits an explicit id. Optional: absent = no default (the caller must
969
- * pass `subagentId`). Full settings CRUD/UI is a later phase.
970
- */
971
- defaultOrchSubagentId?: string | null
972
- }
973
-
974
- export interface AppSettingsPatch {
975
- analyticsEnabled?: boolean
976
- browserSettingsMigrated?: boolean
977
- theme?: AppThemePreference
978
- chatSoundPreference?: ChatSoundPreference
979
- chatSoundId?: ChatSoundId
980
- terminal?: Partial<AppSettingsSnapshot["terminal"]>
981
- editor?: Partial<AppSettingsSnapshot["editor"]>
982
- defaultProvider?: DefaultProviderPreference
983
- providerDefaults?: {
984
- claude?: Partial<ProviderPreference<ClaudeModelOptions>>
985
- codex?: Partial<ProviderPreference<CodexModelOptions>>
986
- openrouter?: Partial<ProviderPreference<OpenRouterModelOptions>>
987
- }
988
- cloudflareTunnel?: Partial<CloudflareTunnelSettings>
989
- auth?: Partial<AuthSettings>
990
- claudeAuth?: Partial<ClaudeAuthSettings>
991
- uploads?: Partial<UploadSettings>
992
- subagents?: {
993
- create?: SubagentInput
994
- update?: { id: string; patch: SubagentPatch }
995
- delete?: { id: string }
996
- }
997
- customMcpServers?: {
998
- create?: McpServerInput
999
- update?: { id: string; patch: McpServerPatch }
1000
- delete?: { id: string }
1001
- setEnabled?: { id: string; enabled: boolean }
1002
- setTestResult?: { id: string; result: McpServerTestResult }
1003
- setOAuthState?: { id: string; oauth: McpOAuthState }
1004
- }
1005
- customModels?: {
1006
- create?: CustomModelInput
1007
- update?: { id: string; patch: CustomModelPatch }
1008
- delete?: { id: string }
1009
- }
1010
- textSnippets?: {
1011
- create?: TextSnippetInput
1012
- update?: { id: string; patch: TextSnippetPatch }
1013
- delete?: { id: string }
1014
- }
1015
- claudeDriver?: {
1016
- preference?: ClaudeDriverPreference
1017
- lifecycle?: Partial<ClaudePtyLifecycleSettings>
1018
- }
1019
- globalPromptAppend?: string
1020
- shareDefaultTtlHours?: number
1021
- subagentRuntime?: Partial<SubagentRuntimeSettings>
1022
- }
1023
-
1024
251
  export interface LlmProviderFile {
1025
252
  provider?: LlmProviderKind
1026
253
  apiKey?: string
@@ -1077,723 +304,6 @@ export interface UpdateInstallResult {
1077
304
  userMessage: string | null
1078
305
  }
1079
306
 
1080
- export type KeybindingAction =
1081
- | "toggleEmbeddedTerminal"
1082
- | "toggleRightSidebar"
1083
- | "openInFinder"
1084
- | "openInEditor"
1085
- | "addSplitTerminal"
1086
- | "jumpToSidebarChat"
1087
- | "createChatInCurrentProject"
1088
- | "openAddProject"
1089
- | "newStack"
1090
- | "newStackChat"
1091
- | "jumpToStacks"
1092
-
1093
- export const DEFAULT_KEYBINDINGS: Record<KeybindingAction, string[]> = {
1094
- toggleEmbeddedTerminal: ["cmd+j", "ctrl+`"],
1095
- toggleRightSidebar: ["cmd+b", "ctrl+b"],
1096
- openInFinder: ["cmd+alt+f", "ctrl+alt+f"],
1097
- openInEditor: ["cmd+shift+o", "ctrl+shift+o"],
1098
- addSplitTerminal: ["cmd+/", "ctrl+/"],
1099
- jumpToSidebarChat: ["cmd+alt"],
1100
- createChatInCurrentProject: ["cmd+alt+n"],
1101
- openAddProject: ["cmd+alt+o"],
1102
- newStack: ["cmd+alt+w"],
1103
- newStackChat: ["cmd+alt+shift+n"],
1104
- jumpToStacks: ["g s"],
1105
- }
1106
-
1107
- export const KEYBINDING_ACTIONS: readonly KeybindingAction[] = [
1108
- "toggleEmbeddedTerminal",
1109
- "toggleRightSidebar",
1110
- "openInFinder",
1111
- "openInEditor",
1112
- "addSplitTerminal",
1113
- "jumpToSidebarChat",
1114
- "createChatInCurrentProject",
1115
- "openAddProject",
1116
- "newStack",
1117
- "newStackChat",
1118
- "jumpToStacks",
1119
- ] satisfies KeybindingAction[]
1120
-
1121
- export interface KeybindingsSnapshot {
1122
- bindings: Record<KeybindingAction, string[]>
1123
- warning: string | null
1124
- filePathDisplay: string
1125
- }
1126
-
1127
- export interface McpServerInfo {
1128
- name: string
1129
- status: string
1130
- error?: string
1131
- }
1132
-
1133
- export interface AccountInfo {
1134
- email?: string
1135
- organization?: string
1136
- subscriptionType?: string
1137
- tokenSource?: string
1138
- apiKeySource?: string
1139
- oauthKeyMasked?: string
1140
- }
1141
-
1142
- export interface AskUserQuestionOption {
1143
- label: string
1144
- description?: string
1145
- }
1146
-
1147
- export interface AskUserQuestionItem {
1148
- id?: string
1149
- question: string
1150
- header?: string
1151
- options?: AskUserQuestionOption[]
1152
- multiSelect?: boolean
1153
- }
1154
-
1155
- export type AskUserQuestionAnswerMap = Record<string, string[]>
1156
-
1157
- export interface TodoItem {
1158
- content: string
1159
- status: "pending" | "in_progress" | "completed"
1160
- activeForm: string
1161
- }
1162
-
1163
- interface TranscriptEntryBase {
1164
- _id: string
1165
- messageId?: string
1166
- createdAt: number
1167
- hidden?: boolean
1168
- debugRaw?: string
1169
- }
1170
-
1171
- interface ToolCallBase<TKind extends string, TInput> {
1172
- kind: "tool"
1173
- toolKind: TKind
1174
- toolName: string
1175
- toolId: string
1176
- input: TInput
1177
- rawInput?: Record<string, unknown>
1178
- }
1179
-
1180
- export interface AskUserQuestionToolCall
1181
- extends ToolCallBase<"ask_user_question", { questions: AskUserQuestionItem[] }> { }
1182
-
1183
- export interface ExitPlanModeToolCall
1184
- extends ToolCallBase<"exit_plan_mode", { plan?: string; summary?: string }> { }
1185
-
1186
- export interface TodoWriteToolCall
1187
- extends ToolCallBase<"todo_write", { todos: TodoItem[] }> { }
1188
-
1189
- export interface SkillToolCall
1190
- extends ToolCallBase<"skill", { skill: string }> { }
1191
-
1192
- export interface GlobToolCall
1193
- extends ToolCallBase<"glob", { pattern: string }> { }
1194
-
1195
- export interface GrepToolCall
1196
- extends ToolCallBase<"grep", { pattern: string; outputMode?: string }> { }
1197
-
1198
- export interface BashToolCall
1199
- extends ToolCallBase<"bash", { command: string; description?: string; timeoutMs?: number; runInBackground?: boolean }> { }
1200
-
1201
- export interface WebSearchToolCall
1202
- extends ToolCallBase<"web_search", { query: string }> { }
1203
-
1204
- export interface ReadFileToolCall
1205
- extends ToolCallBase<"read_file", { filePath: string }> { }
1206
-
1207
- export interface WriteFileToolCall
1208
- extends ToolCallBase<"write_file", { filePath: string; content: string }> { }
1209
-
1210
- export interface EditFileToolCall
1211
- extends ToolCallBase<"edit_file", { filePath: string; oldString: string; newString: string }> { }
1212
-
1213
- export interface DeleteFileToolCall
1214
- extends ToolCallBase<"delete_file", { filePath: string; content: string }> { }
1215
-
1216
- export interface SubagentTaskToolCall
1217
- extends ToolCallBase<"subagent_task", { subagentType?: string }> { }
1218
-
1219
- export interface McpGenericToolCall
1220
- extends ToolCallBase<"mcp_generic", { server: string; tool: string; payload: Record<string, unknown> }> { }
1221
-
1222
- export interface OfferDownloadToolCall
1223
- extends ToolCallBase<"offer_download", { path: string; label?: string }> { }
1224
-
1225
- export interface OfferDownloadToolResult {
1226
- contentUrl: string
1227
- relativePath: string
1228
- fileName: string
1229
- displayName: string
1230
- size: number
1231
- mimeType?: string
1232
- }
1233
-
1234
- export interface PreviewFileToolCall
1235
- extends ToolCallBase<"preview_file", { path: string; label?: string }> { }
1236
-
1237
- export interface PreviewFileToolResult {
1238
- contentUrl: string
1239
- relativePath: string
1240
- fileName: string
1241
- displayName: string
1242
- size: number
1243
- mimeType: string
1244
- }
1245
-
1246
- export type ImageGenerationStatus = "in_progress" | "completed" | "failed"
1247
-
1248
- export interface ImageGenerationToolCall
1249
- extends ToolCallBase<"image_generation", { revisedPrompt: string | null; status: ImageGenerationStatus }> { }
1250
-
1251
- export interface ImageGenerationToolResult {
1252
- contentUrl: string
1253
- relativePath: string
1254
- fileName: string
1255
- }
1256
-
1257
- export interface UnknownToolCall
1258
- extends ToolCallBase<"unknown_tool", { payload: Record<string, unknown> }> { }
1259
-
1260
- export interface WorkflowToolCall
1261
- extends ToolCallBase<"workflow", { name?: string; description?: string; scriptPath?: string }> { }
1262
-
1263
- export type NormalizedToolCall =
1264
- | AskUserQuestionToolCall
1265
- | ExitPlanModeToolCall
1266
- | TodoWriteToolCall
1267
- | SkillToolCall
1268
- | GlobToolCall
1269
- | GrepToolCall
1270
- | BashToolCall
1271
- | WebSearchToolCall
1272
- | ReadFileToolCall
1273
- | WriteFileToolCall
1274
- | EditFileToolCall
1275
- | DeleteFileToolCall
1276
- | SubagentTaskToolCall
1277
- | McpGenericToolCall
1278
- | OfferDownloadToolCall
1279
- | PreviewFileToolCall
1280
- | ImageGenerationToolCall
1281
- | WorkflowToolCall
1282
- | UnknownToolCall
1283
-
1284
- export interface ToolResultEntry extends TranscriptEntryBase {
1285
- kind: "tool_result"
1286
- toolId: string
1287
- content: string | Record<string, unknown> | readonly unknown[] | null
1288
- isError?: boolean
1289
- /**
1290
- * Set when the original content exceeded the subagent payload cap
1291
- * (50 KB) and the full content was written to disk. `content` then
1292
- * carries only a 2 KB preview wrapped in <persisted-output> tags.
1293
- */
1294
- persisted?: {
1295
- filePath: string
1296
- originalSize: number
1297
- isJson: boolean
1298
- truncated: true
1299
- }
1300
- }
1301
-
1302
- export interface UserPromptEntry extends TranscriptEntryBase {
1303
- kind: "user_prompt"
1304
- content: string
1305
- attachments?: ChatAttachment[]
1306
- steered?: boolean
1307
- autoContinue?: { scheduleId: string }
1308
- subagentMentions?: Array<{ subagentId: string; raw: string }>
1309
- unknownSubagentMentions?: Array<{ name: string; raw: string }>
1310
- }
1311
-
1312
- export interface SystemInitEntry extends TranscriptEntryBase {
1313
- kind: "system_init"
1314
- provider: AgentProvider
1315
- model: string
1316
- tools: string[]
1317
- agents: string[]
1318
- slashCommands: string[]
1319
- mcpServers: McpServerInfo[]
1320
- }
1321
-
1322
- export interface AccountInfoEntry extends TranscriptEntryBase {
1323
- kind: "account_info"
1324
- accountInfo: AccountInfo
1325
- }
1326
-
1327
- export interface AssistantTextEntry extends TranscriptEntryBase {
1328
- kind: "assistant_text"
1329
- text: string
1330
- }
1331
-
1332
- export interface AssistantThinkingEntry extends TranscriptEntryBase {
1333
- kind: "assistant_thinking"
1334
- text: string
1335
- signature?: string
1336
- }
1337
-
1338
- export interface ApiErrorEntry extends TranscriptEntryBase {
1339
- kind: "api_error"
1340
- status: number
1341
- text: string
1342
- requestId?: string
1343
- }
1344
-
1345
- // A deliberate model refusal (Claude CLI returns stop_reason "refusal" /
1346
- // Usage-Policy block text) — distinct from a transport/overload api_error.
1347
- // Surfaced as its own kind so the UI can label it "Blocked — Usage Policy"
1348
- // instead of a generic red API-error card.
1349
- // See adr-20260607-surface-policy-refusal-entry.
1350
- export interface PolicyRefusalEntry extends TranscriptEntryBase {
1351
- kind: "policy_refusal"
1352
- text: string
1353
- requestId?: string
1354
- }
1355
-
1356
- export interface ToolCallEntry extends TranscriptEntryBase {
1357
- kind: "tool_call"
1358
- tool: NormalizedToolCall
1359
- }
1360
-
1361
- export interface ResultEntry extends TranscriptEntryBase {
1362
- kind: "result"
1363
- subtype: "success" | "error" | "cancelled"
1364
- isError: boolean
1365
- durationMs: number
1366
- result: string
1367
- costUsd?: number
1368
- usage?: ProviderUsage
1369
- /**
1370
- * Number of background Workflow tasks still running when this turn ended
1371
- * (from claude-code's `turn_duration` frame). When > 0 the coordinator arms
1372
- * a pending-workflow wake so the agent re-enters to harvest results instead
1373
- * of going idle. Absent/0 on normal turns.
1374
- * See adr-20260603-agent-self-scheduled-wake.
1375
- */
1376
- pendingWorkflowCount?: number
1377
- }
1378
-
1379
- export interface StatusEntry extends TranscriptEntryBase {
1380
- kind: "status"
1381
- status: string
1382
- backgroundTaskId?: string
1383
- }
1384
-
1385
- export interface ContextWindowUsageSnapshot {
1386
- usedTokens: number
1387
- totalProcessedTokens?: number
1388
- maxTokens?: number
1389
- inputTokens?: number
1390
- cachedInputTokens?: number
1391
- outputTokens?: number
1392
- reasoningOutputTokens?: number
1393
- lastUsedTokens?: number
1394
- lastInputTokens?: number
1395
- lastCachedInputTokens?: number
1396
- lastOutputTokens?: number
1397
- lastReasoningOutputTokens?: number
1398
- toolUses?: number
1399
- durationMs?: number
1400
- /** USD cost for this turn. Provider-reported (Claude) or computed (others). */
1401
- costUsd?: number
1402
- compactsAutomatically: boolean
1403
- }
1404
-
1405
- export interface ChatDiffFile {
1406
- path: string
1407
- changeType: "added" | "deleted" | "modified" | "renamed"
1408
- isUntracked: boolean
1409
- additions: number
1410
- deletions: number
1411
- patchDigest: string
1412
- mimeType?: string
1413
- size?: number
1414
- }
1415
-
1416
- export interface ChatBranchHistoryEntry {
1417
- sha: string
1418
- summary: string
1419
- description: string
1420
- authorName?: string
1421
- authoredAt: string
1422
- tags: string[]
1423
- githubUrl?: string
1424
- }
1425
-
1426
- export interface ChatBranchHistorySnapshot {
1427
- entries: ChatBranchHistoryEntry[]
1428
- }
1429
-
1430
- export type ChatBranchListEntryKind = "local" | "remote" | "pull_request"
1431
-
1432
- export interface ChatBranchListEntry {
1433
- id: string
1434
- kind: ChatBranchListEntryKind
1435
- name: string
1436
- displayName: string
1437
- updatedAt?: string
1438
- description?: string
1439
- remoteRef?: string
1440
- prNumber?: number
1441
- prTitle?: string
1442
- headRefName?: string
1443
- headLabel?: string
1444
- headRepoCloneUrl?: string
1445
- isCrossRepository?: boolean
1446
- }
1447
-
1448
- export interface ChatBranchListResult {
1449
- currentBranchName?: string
1450
- defaultBranchName?: string
1451
- recent: ChatBranchListEntry[]
1452
- local: ChatBranchListEntry[]
1453
- remote: ChatBranchListEntry[]
1454
- pullRequests: ChatBranchListEntry[]
1455
- pullRequestsStatus: "available" | "unavailable" | "error"
1456
- pullRequestsError?: string
1457
- }
1458
-
1459
- export interface GitHubPublishInfo {
1460
- ghInstalled: boolean
1461
- authenticated: boolean
1462
- activeAccountLogin?: string
1463
- owners: string[]
1464
- suggestedRepoName: string
1465
- }
1466
-
1467
- export interface GitHubRepoAvailabilityResult {
1468
- available: boolean
1469
- message: string
1470
- }
1471
-
1472
- export interface BranchMetadata {
1473
- branchName?: string
1474
- defaultBranchName?: string
1475
- hasOriginRemote?: boolean
1476
- originRepoSlug?: string
1477
- hasUpstream?: boolean
1478
- }
1479
-
1480
- export interface UpstreamStatus {
1481
- aheadCount?: number
1482
- behindCount?: number
1483
- lastFetchedAt?: string
1484
- }
1485
-
1486
- export interface ChatDiffSnapshot extends BranchMetadata, UpstreamStatus {
1487
- status: "unknown" | "ready" | "no_repo"
1488
- files: ChatDiffFile[]
1489
- branchHistory?: ChatBranchHistorySnapshot
1490
- }
1491
-
1492
- export interface BranchActionSuccess {
1493
- ok: true
1494
- branchName?: string
1495
- snapshotChanged: boolean
1496
- }
1497
-
1498
- export interface BranchActionFailure {
1499
- ok: false
1500
- title: string
1501
- message: string
1502
- detail?: string
1503
- cancelled?: boolean
1504
- snapshotChanged?: boolean
1505
- }
1506
-
1507
- export type ChatSyncSuccess = BranchActionSuccess & {
1508
- action: "fetch" | "pull" | "push" | "publish"
1509
- aheadCount?: number
1510
- behindCount?: number
1511
- }
1512
-
1513
- export type ChatSyncFailure = BranchActionFailure & {
1514
- action: "fetch" | "pull" | "push" | "publish"
1515
- }
1516
-
1517
- export type ChatSyncResult = ChatSyncSuccess | ChatSyncFailure
1518
-
1519
- export type DiffCommitMode = "commit_and_push" | "commit_only"
1520
-
1521
- export type ChatCheckoutBranchSuccess = BranchActionSuccess
1522
- export type ChatCheckoutBranchFailure = BranchActionFailure
1523
- export type ChatCheckoutBranchResult = ChatCheckoutBranchSuccess | ChatCheckoutBranchFailure
1524
-
1525
- export type ChatCreateBranchSuccess = BranchActionSuccess & { branchName: string }
1526
- export type ChatCreateBranchFailure = BranchActionFailure
1527
- export type ChatCreateBranchResult = ChatCreateBranchSuccess | ChatCreateBranchFailure
1528
-
1529
- export type ChatMergePreviewStatus = "up_to_date" | "mergeable" | "conflicts" | "error"
1530
-
1531
- export interface ChatMergePreviewResult {
1532
- currentBranchName?: string
1533
- targetBranchName: string
1534
- targetDisplayName: string
1535
- status: ChatMergePreviewStatus
1536
- commitCount: number
1537
- hasConflicts: boolean
1538
- message: string
1539
- detail?: string
1540
- }
1541
-
1542
- export type ChatMergeBranchSuccess = BranchActionSuccess
1543
- export type ChatMergeBranchFailure = BranchActionFailure
1544
- export type ChatMergeBranchResult = ChatMergeBranchSuccess | ChatMergeBranchFailure
1545
-
1546
- export type DiffCommitSuccess = BranchActionSuccess & {
1547
- mode: DiffCommitMode
1548
- pushed: boolean
1549
- }
1550
-
1551
- export type DiffCommitFailure = BranchActionFailure & {
1552
- mode: DiffCommitMode
1553
- phase: "commit" | "push"
1554
- localCommitCreated?: boolean
1555
- }
1556
-
1557
- export type DiffCommitResult = DiffCommitSuccess | DiffCommitFailure
1558
-
1559
- export interface ContextWindowUpdatedEntry extends TranscriptEntryBase {
1560
- kind: "context_window_updated"
1561
- usage: ContextWindowUsageSnapshot
1562
- }
1563
-
1564
- export interface CompactBoundaryEntry extends TranscriptEntryBase {
1565
- kind: "compact_boundary"
1566
- }
1567
-
1568
- export interface CompactSummaryEntry extends TranscriptEntryBase {
1569
- kind: "compact_summary"
1570
- summary: string
1571
- }
1572
-
1573
- export interface ContextClearedEntry extends TranscriptEntryBase {
1574
- kind: "context_cleared"
1575
- }
1576
-
1577
- export interface InterruptedEntry extends TranscriptEntryBase {
1578
- kind: "interrupted"
1579
- }
1580
-
1581
- /**
1582
- * A Claude Code memory/rule file auto-loaded into context (CLAUDE.md, nested
1583
- * CLAUDE.md, `.claude/rules/*.md`). PTY mode surfaces these from the
1584
- * transcript's `type:"nested_memory"` lines. Path only — file content is
1585
- * intentionally not carried (keeps the persisted/replayed event log light).
1586
- */
1587
- export interface MemoryLoadedEntry extends TranscriptEntryBase {
1588
- kind: "memory_loaded"
1589
- path: string
1590
- }
1591
-
1592
- export type TranscriptEntry =
1593
- | UserPromptEntry
1594
- | SystemInitEntry
1595
- | AccountInfoEntry
1596
- | AssistantTextEntry
1597
- | AssistantThinkingEntry
1598
- | ApiErrorEntry
1599
- | PolicyRefusalEntry
1600
- | ToolCallEntry
1601
- | ToolResultEntry
1602
- | ResultEntry
1603
- | StatusEntry
1604
- | ContextWindowUpdatedEntry
1605
- | CompactBoundaryEntry
1606
- | CompactSummaryEntry
1607
- | ContextClearedEntry
1608
- | InterruptedEntry
1609
- | MemoryLoadedEntry
1610
- | AutoContinuePromptEntry
1611
- | PendingToolRequestEntry
1612
- | ToolRequestResolvedEntry
1613
-
1614
- export interface HydratedToolCallBase<TKind extends string, TInput, TResult> {
1615
- id: string
1616
- messageId?: string
1617
- hidden?: boolean
1618
- kind: "tool"
1619
- toolKind: TKind
1620
- toolName: string
1621
- toolId: string
1622
- input: TInput
1623
- result?: TResult
1624
- rawResult?: string | Record<string, unknown> | readonly unknown[] | null
1625
- isError?: boolean
1626
- /**
1627
- * Set when the underlying tool_result entry was persisted to disk
1628
- * via the subagent payload cap. Mirrored from
1629
- * ToolResultEntry.persisted during hydration.
1630
- */
1631
- persisted?: {
1632
- filePath: string
1633
- originalSize: number
1634
- isJson: boolean
1635
- truncated: true
1636
- }
1637
- timestamp: string
1638
- }
1639
-
1640
- export interface AskUserQuestionToolResult {
1641
- answers: AskUserQuestionAnswerMap
1642
- discarded?: boolean
1643
- }
1644
-
1645
- export interface ExitPlanModeToolResult {
1646
- confirmed?: boolean
1647
- clearContext?: boolean
1648
- message?: string
1649
- discarded?: boolean
1650
- }
1651
-
1652
- export type HydratedAskUserQuestionToolCall =
1653
- HydratedToolCallBase<"ask_user_question", AskUserQuestionToolCall["input"], AskUserQuestionToolResult>
1654
-
1655
- export type HydratedExitPlanModeToolCall =
1656
- HydratedToolCallBase<"exit_plan_mode", ExitPlanModeToolCall["input"], ExitPlanModeToolResult>
1657
-
1658
- export type HydratedTodoWriteToolCall =
1659
- HydratedToolCallBase<"todo_write", TodoWriteToolCall["input"], unknown>
1660
-
1661
- export type HydratedSkillToolCall =
1662
- HydratedToolCallBase<"skill", SkillToolCall["input"], unknown>
1663
-
1664
- export type HydratedGlobToolCall =
1665
- HydratedToolCallBase<"glob", GlobToolCall["input"], unknown>
1666
-
1667
- export type HydratedGrepToolCall =
1668
- HydratedToolCallBase<"grep", GrepToolCall["input"], unknown>
1669
-
1670
- export type HydratedBashToolCall =
1671
- HydratedToolCallBase<"bash", BashToolCall["input"], unknown>
1672
-
1673
- export type HydratedWebSearchToolCall =
1674
- HydratedToolCallBase<"web_search", WebSearchToolCall["input"], unknown>
1675
-
1676
- export interface ReadFileTextBlock {
1677
- type: "text"
1678
- text: string
1679
- }
1680
-
1681
- export interface ReadFileImageBlock {
1682
- type: "image"
1683
- data: string
1684
- mimeType?: string
1685
- }
1686
-
1687
- export interface ReadFileToolResult {
1688
- content: string
1689
- blocks?: Array<ReadFileTextBlock | ReadFileImageBlock>
1690
- }
1691
-
1692
- export type HydratedReadFileToolCall =
1693
- HydratedToolCallBase<"read_file", ReadFileToolCall["input"], ReadFileToolResult | string>
1694
-
1695
- export type HydratedWriteFileToolCall =
1696
- HydratedToolCallBase<"write_file", WriteFileToolCall["input"], unknown>
1697
-
1698
- export type HydratedEditFileToolCall =
1699
- HydratedToolCallBase<"edit_file", EditFileToolCall["input"], unknown>
1700
-
1701
- export type HydratedDeleteFileToolCall =
1702
- HydratedToolCallBase<"delete_file", DeleteFileToolCall["input"], unknown>
1703
-
1704
- export interface SubagentToolStats {
1705
- readCount?: number
1706
- searchCount?: number
1707
- bashCount?: number
1708
- editFileCount?: number
1709
- linesAdded?: number
1710
- linesRemoved?: number
1711
- otherToolCount?: number
1712
- }
1713
-
1714
- // Parsed from the `Agent`/`Task` tool_result's top-level `toolUseResult`
1715
- // sidecar (camelCase, written by claude-code into the transcript JSONL and
1716
- // preserved on the tool_result entry's debugRaw). All fields optional — the
1717
- // SDK driver / older transcripts / in-flight calls may omit it entirely.
1718
- export interface SubagentTaskResult {
1719
- agentId?: string
1720
- agentType?: string
1721
- status?: string
1722
- totalTokens?: number
1723
- totalDurationMs?: number
1724
- totalToolUseCount?: number
1725
- toolStats?: SubagentToolStats
1726
- content?: string
1727
- }
1728
-
1729
- export type HydratedSubagentTaskToolCall =
1730
- HydratedToolCallBase<"subagent_task", SubagentTaskToolCall["input"], SubagentTaskResult>
1731
-
1732
- export type HydratedMcpGenericToolCall =
1733
- HydratedToolCallBase<"mcp_generic", McpGenericToolCall["input"], unknown>
1734
-
1735
- export type HydratedOfferDownloadToolCall =
1736
- HydratedToolCallBase<"offer_download", OfferDownloadToolCall["input"], OfferDownloadToolResult>
1737
-
1738
- export type HydratedPreviewFileToolCall =
1739
- HydratedToolCallBase<"preview_file", PreviewFileToolCall["input"], PreviewFileToolResult>
1740
-
1741
- export type HydratedImageGenerationToolCall =
1742
- HydratedToolCallBase<"image_generation", ImageGenerationToolCall["input"], ImageGenerationToolResult>
1743
-
1744
- export interface WorkflowToolResult {
1745
- taskId?: string
1746
- text: string
1747
- }
1748
-
1749
- export type HydratedWorkflowToolCall =
1750
- HydratedToolCallBase<"workflow", WorkflowToolCall["input"], WorkflowToolResult>
1751
-
1752
- export type HydratedUnknownToolCall =
1753
- HydratedToolCallBase<"unknown_tool", UnknownToolCall["input"], unknown>
1754
-
1755
- export type HydratedToolCall =
1756
- | HydratedAskUserQuestionToolCall
1757
- | HydratedExitPlanModeToolCall
1758
- | HydratedTodoWriteToolCall
1759
- | HydratedSkillToolCall
1760
- | HydratedGlobToolCall
1761
- | HydratedGrepToolCall
1762
- | HydratedBashToolCall
1763
- | HydratedWebSearchToolCall
1764
- | HydratedReadFileToolCall
1765
- | HydratedWriteFileToolCall
1766
- | HydratedEditFileToolCall
1767
- | HydratedDeleteFileToolCall
1768
- | HydratedSubagentTaskToolCall
1769
- | HydratedMcpGenericToolCall
1770
- | HydratedOfferDownloadToolCall
1771
- | HydratedPreviewFileToolCall
1772
- | HydratedImageGenerationToolCall
1773
- | HydratedWorkflowToolCall
1774
- | HydratedUnknownToolCall
1775
-
1776
- export type HydratedTranscriptMessage =
1777
- | ({ kind: "user_prompt"; content: string; attachments?: ChatAttachment[]; steered?: boolean; autoContinue?: { scheduleId: string }; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1778
- | ({ kind: "system_init"; model: string; tools: string[]; agents: string[]; slashCommands: string[]; mcpServers: McpServerInfo[]; provider: AgentProvider; id: string; messageId?: string; timestamp: string; hidden?: boolean; debugRaw?: string })
1779
- | ({ kind: "account_info"; accountInfo: AccountInfo; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1780
- | ({ kind: "assistant_text"; text: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1781
- | ({ kind: "assistant_thinking"; text: string; signature?: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1782
- | ({ kind: "api_error"; status: number; text: string; requestId?: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1783
- | ({ kind: "policy_refusal"; text: string; requestId?: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1784
- | ({ kind: "result"; success: boolean; cancelled?: boolean; result: string; durationMs: number; costUsd?: number; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1785
- | ({ kind: "status"; status: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1786
- | ({ kind: "context_window_updated"; usage: ContextWindowUsageSnapshot; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1787
- | ({ kind: "compact_boundary"; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1788
- | ({ kind: "compact_summary"; summary: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1789
- | ({ kind: "context_cleared"; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1790
- | ({ kind: "interrupted"; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1791
- | ({ kind: "memory_loaded"; path: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1792
- | ({ kind: "unknown"; json: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1793
- | ({ kind: "auto_continue_prompt"; scheduleId: string; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1794
- | ({ kind: "pending_tool_request"; toolRequestId: string; toolName: string; arguments: Record<string, unknown>; id: string; messageId?: string; timestamp: string; hidden?: boolean })
1795
- | ({ id: string; messageId?: string; hidden?: boolean } & HydratedToolCall)
1796
-
1797
307
  export interface ChatTimingCumulativeMs {
1798
308
  idle: number
1799
309
  starting: number
@@ -1854,69 +364,6 @@ export interface ResolvedStackBinding {
1854
364
  projectStatus: "active" | "missing"
1855
365
  }
1856
366
 
1857
- export type SubagentErrorCode =
1858
- | "AUTH_REQUIRED"
1859
- | "UNKNOWN_SUBAGENT"
1860
- | "MANUAL_ONLY"
1861
- | "LOOP_DETECTED"
1862
- | "DEPTH_EXCEEDED"
1863
- | "TIMEOUT"
1864
- | "MAX_TURNS"
1865
- | "PROVIDER_ERROR"
1866
- | "INTERRUPTED"
1867
- | "USER_CANCELLED"
1868
- | "CAP_EXCEEDED"
1869
- | "NO_LIVE_SESSION"
1870
-
1871
- export type SubagentRunStatus = "running" | "completed" | "failed" | "cancelled"
1872
-
1873
- export interface ProviderUsage {
1874
- inputTokens?: number
1875
- outputTokens?: number
1876
- cachedInputTokens?: number
1877
- costUsd?: number
1878
- }
1879
-
1880
- export interface SubagentPendingTool {
1881
- toolUseId: string
1882
- toolKind: "ask_user_question" | "exit_plan_mode"
1883
- input: Record<string, unknown>
1884
- requestedAt: number
1885
- }
1886
-
1887
- export interface SubagentRunSnapshot {
1888
- runId: string
1889
- chatId: string
1890
- subagentId: string | null
1891
- subagentName: string
1892
- provider: AgentProvider
1893
- model: string
1894
- status: SubagentRunStatus
1895
- parentUserMessageId: string
1896
- parentRunId: string | null
1897
- depth: number
1898
- startedAt: number
1899
- finishedAt: number | null
1900
- finalText: string | null
1901
- error: { code: SubagentErrorCode; message: string } | null
1902
- usage: ProviderUsage | null
1903
- /**
1904
- * Every TranscriptEntry the subagent produced, in arrival order. Includes
1905
- * tool_call, tool_result, system_init, account_info, result. assistant_text
1906
- * entries also live here in addition to being concatenated into finalText
1907
- * via subagent_message_delta — clients should prefer entries[] for rich
1908
- * rendering, finalText only as a quick text-only summary.
1909
- */
1910
- entries: TranscriptEntry[]
1911
- /**
1912
- * Set while the subagent is awaiting a user response to an
1913
- * interactive tool call (AskUserQuestion / ExitPlanMode). Null
1914
- * otherwise. The orchestrator's wall-clock timeout is paused while
1915
- * this is non-null.
1916
- */
1917
- pendingTool: SubagentPendingTool | null
1918
- }
1919
-
1920
367
  export interface ChatSnapshot {
1921
368
  runtime: ChatRuntime
1922
369
  queuedMessages: QueuedChatMessage[]
@@ -1931,6 +378,8 @@ export interface ChatSnapshot {
1931
378
  liveTunnelId: string | null
1932
379
  resolvedBindings?: ResolvedStackBinding[]
1933
380
  subagentRuns: Record<string, SubagentRunSnapshot>
381
+ /** Loop Progress panel view — armed state, per-round rows, rate-limit resume. */
382
+ loopProgress: LoopProgressSnapshot
1934
383
  }
1935
384
 
1936
385
  export interface ChatHistoryPage {
@@ -1965,99 +414,9 @@ export interface AutoContinueSchedule {
1965
414
  prompt?: string
1966
415
  }
1967
416
 
1968
- export interface AutoContinuePromptEntry extends TranscriptEntryBase {
1969
- kind: "auto_continue_prompt"
1970
- scheduleId: string
1971
- }
1972
-
1973
- export interface PendingToolRequestEntry extends TranscriptEntryBase {
1974
- kind: "pending_tool_request"
1975
- toolRequestId: string
1976
- toolName: string
1977
- arguments: Record<string, unknown>
1978
- }
1979
-
1980
- export interface ToolRequestResolvedEntry extends TranscriptEntryBase {
1981
- kind: "tool_request_resolved"
1982
- toolRequestId: string
1983
- status: ToolRequestStatus
1984
- decision?: ToolRequestDecision
1985
- }
1986
-
1987
- export type CloudflareTunnelMode = "always-ask" | "auto-expose"
1988
-
1989
- export interface CloudflareTunnelSettings {
1990
- enabled: boolean
1991
- cloudflaredPath: string
1992
- mode: CloudflareTunnelMode
1993
- }
1994
-
1995
- export const CLOUDFLARE_TUNNEL_DEFAULTS: CloudflareTunnelSettings = {
1996
- enabled: false,
1997
- cloudflaredPath: "cloudflared",
1998
- mode: "always-ask",
1999
- }
2000
-
2001
- export type CloudflareTunnelState = "proposed" | "active" | "stopped" | "failed"
2002
-
2003
- export interface CloudflareTunnelRecord {
2004
- tunnelId: string
2005
- chatId: string
2006
- port: number
2007
- state: CloudflareTunnelState
2008
- url: string | null
2009
- error: string | null
2010
- proposedAt: number
2011
- activatedAt: number | null
2012
- stoppedAt: number | null
2013
- }
2014
-
2015
- export interface GitWorktree {
2016
- path: string // absolute
2017
- branch: string // e.g. "main", "feat/x", "(detached)"
2018
- sha: string // HEAD commit sha
2019
- isPrimary: boolean
2020
- isLocked: boolean // git has flagged this worktree as locked (pruning inhibited)
2021
- }
2022
-
2023
417
  // Type guards for string literal unions — used by Select/SegmentedControl callbacks
2024
418
  // (Radix Select passes `string`; these guards narrow without an `as` cast)
2025
419
 
2026
- export function isEditorPreset(value: string): value is EditorPreset {
2027
- return value === "cursor" || value === "vscode" || value === "xcode" || value === "windsurf" || value === "custom"
2028
- }
2029
-
2030
- export function isChatSoundPreference(value: string): value is ChatSoundPreference {
2031
- return value === "never" || value === "unfocused" || value === "always"
2032
- }
2033
-
2034
- export function isChatSoundId(value: string): value is ChatSoundId {
2035
- return (
2036
- value === "blow" || value === "bottle" || value === "frog" || value === "funk" ||
2037
- value === "glass" || value === "ping" || value === "pop" || value === "purr" || value === "tink"
2038
- )
2039
- }
2040
-
2041
- export function isCloudFlareTunnelMode(value: string): value is CloudflareTunnelMode {
2042
- return value === "always-ask" || value === "auto-expose"
2043
- }
2044
-
2045
- export function isLlmProviderKind(value: string): value is LlmProviderKind {
2046
- return value === "openai" || value === "openrouter" || value === "custom"
2047
- }
2048
-
2049
420
  export function isAgentProvider(value: string): value is AgentProvider {
2050
421
  return value === "claude" || value === "codex" || value === "openrouter"
2051
422
  }
2052
-
2053
- export function isSubagentContextScope(value: string): value is SubagentContextScope {
2054
- return value === "previous-assistant-reply" || value === "full-transcript"
2055
- }
2056
-
2057
- export function isSubagentTriggerMode(value: string): value is SubagentTriggerMode {
2058
- return value === "auto" || value === "manual"
2059
- }
2060
-
2061
- export function isAppThemePreference(value: string): value is AppThemePreference {
2062
- return value === "light" || value === "dark" || value === "system"
2063
- }