返回 DeepSeek-Reasonix
types.ts
根目录 / desktop / frontend / src / lib / types.ts
1 import type { HistoryToolCall } from "./historyToolTypes";
2 export type { HistoryToolCall } from "./historyToolTypes";
3 export type { ProjectNode } from "./projectNodeTypes";
4 import type { TranscriptTurnMetadata } from "./transcriptProtocol";
5 import type { ConnectionAuthentication } from "./authenticationTypes";
6 import type { HistorySwitchPhases } from "./sessionDiagnostics";
7 import type { ProviderCatalog } from "./providerCatalogTypes";
8 export type { SettingsView } from "./settingsViewTypes";
9 export type { ProviderProtocolEndpoint, ProviderCatalog, ProviderPresetView } from "./providerCatalogTypes";
10 import type { WireReadStatus } from "./readStatus";
11 export type { WireReadStatus } from "./readStatus";
12 import type { RecoveryEventFields } from "./recoveryStatus";
13 // Wire contract: one discriminated event channel mirrors desktop/wire.go and internal/serve/wire.go.
14 import type { HistoryServerSearch } from "./searchSources";
15 import type { Todo } from "./tools";
16 import type { ContextBudgetInfo, ContextMaintenanceInfo, WireContextMaintenance } from "./contextMaintenanceTypes";
17 import type { WireApproval } from "./approvalTypes";
18 import type { RemoteSessionMetaFields, RemoteTabMetaFields } from "./remoteTypes";
19 import type { PinnedFileInfo } from "./pinnedContextBridge";
20 import type { RecoveryLineageView } from "./sessionRecoveryTypes";
21 import type { SessionRef, SessionRuntimeIssue } from "./sessionRef";
22 export * from "./remoteTypes";
23 export type { ContextBudgetInfo, ContextMaintenanceInfo, ContextMaintenanceReceipt, WireContextMaintenance } from "./contextMaintenanceTypes";
24 export type { HistoryContentChunk, HistoryContentRef, HistoryEntry, HistorySlice, HistorySliceRequest, HistoryWindowPageView, HistoryWindowRequestView, HistoryWindowStatus, MessageFieldView, SessionClearResult } from "./historyTypes";
25 export type { ProjectGroupsSnapshot, ProjectRuntimeTopic, ProjectTopicKey, ProjectTopicPage, ProjectTopicPageRequest, ProjectTreeChangedV2, ProjectTreeOrganizationBindings, ProjectTreeRuntimeSnapshot, ProjectTreeSnapshot, SessionCatalogBindings, SessionCatalogStatus, SessionGroup, SessionReference } from "./sessionCatalogTypes";
26 export type { SessionRef, SessionRuntimeIssue } from "./sessionRef";
27 export type EventKind =
28 | "user_message"
29 | "turn_started"
30 | "reasoning"
31 | "text"
32 | "message"
33 | "tool_dispatch"
34 | "tool_started"
35 | "tool_result"
36 | "tool_result_preview"
37 | "turn_status"
38 | "prompt_answered" | "session_changed"
39 | "mcp_interaction"
40 | "tool_progress"
41 | "usage"
42 | "notice"
43 | "phase"
44 | "approval_request"
45 | "ask_request"
46 | "turn_done"
47 | "compaction_started"
48 | "compaction_done"
49 | "mcp_surface_ready"
50 | "retrying"
51 | "steer"
52 | "guardian_assessment"
53 | "extension_surface"
54 | "extension_status"
55 | "stream_attempt"
56 | "context_maintenance"
57 | "workspace_changed"
58 | "turn_phase"
59 | "completion_summary"
60 | "read_status"
61 | "provider_unreachable";
62 export type StreamAttemptAction = "begin" | "discard" | "commit";
63 export type TurnStatus = "queued" | "in_progress" | "waiting_user" | "cancelling" | "completed" | "interrupted" | "failed" | "protocol_failed" | "recovery_required";
64 export interface TurnEventEnvelope {
65 sessionId?: string;
66 turnId: string;
67 seq: number;
68 status: TurnStatus | string;
69 runtimeEpoch?: string;
70 submissionId?: string;
71 transcriptRevision?: number;
72 transcriptDigest?: string;
73 event: WireEvent;
74 }
75 export interface TurnEventReplayView {
76 events: TurnEventEnvelope[];
77 floorSeq: number;
78 latestSeq: number;
79 nextAfterSeq: number;
80 hasMore: boolean;
81 resetRequired: boolean;
82 transcriptRevision?: number;
83 transcriptDigest?: string;
84 runtimeEpoch?: string;
85 }
86 export interface WireStreamAttempt {
87 id: string;
88 action: StreamAttemptAction;
89 attempt?: number;
90 max?: number;
91 /** Fixed enum only: connection_reset | premature_eof | idle_timeout */
92 reason?: string;
93 }
94 export interface WireCompaction {
95 trigger?: string; // "auto" | "manual"
96 messages?: number; // done: how many messages were folded into the summary
97 summary?: string; // done: the briefing (empty on an aborted pass)
98 archive?: string; // done: archive path, if any
99 }
100 export interface WireProfile {
101 model?: string;
102 effort?: string;
103 }
104
105 export interface WireShellExecution {
106 kind?: string;
107 shell?: string;
108 shellVersion?: string;
109 platform?: string;
110 supportsAndAnd?: boolean;
111 state?: string;
112 failurePhase?: string;
113 exitCode?: number;
114 outputTail?: string;
115 mutationRisk?: string;
116 verification?: string;
117 durationMs?: number;
118 }
119
120 export interface WireTool {
121 diagnostic?: import("./readStatus").OperationDiagnostic;
122 verifying?: boolean;
123 id?: string;
124 name: string;
125 args?: string;
126 todos?: Todo[];
127 todoWritten?: boolean;
128 resolvedName?: string;
129 capabilityId?: string;
130 output?: string;
131 err?: string;
132 readOnly: boolean;
133 truncated?: boolean;
134 durationMs?: number;
135 partial?: boolean; // an early dispatch (name only) — a full one with args follows
136 argChars?: number; // partial only: cumulative argument chars streamed so far
137 refreshed?: boolean; // same-ID full dispatch with a preview recomputed after an earlier write
138 parentId?: string; // set on a sub-agent's calls — the parent `task` call's id
139 /** Host-local stream_attempt id for speculative parent partials only. */
140 attemptId?: string;
141 diff?: string;
142 added?: number;
143 removed?: number; subagentRef?: string; subagentStatus?: string; subagentErrorCode?: string; subagentRetryable?: boolean;
144 profile?: WireProfile; // subagent model/effort resolved for this call
145 execution?: WireShellExecution; // local shell metadata; never provider-visible
146 presentedFiles?: PresentedFile[]; // trusted host-only deliverables from built-in present
147 }
148
149 export interface PresentedFile {
150 path: string;
151 description?: string;
152 }
153
154 export interface WireCacheDiagnostics {
155 prefixHash: string;
156 prefixChanged: boolean;
157 prefixChangeReasons?: string[];
158 systemHash: string;
159 toolsHash: string;
160 logRewriteVersion: number;
161 toolSchemaTokens: number;
162 cacheMissTokens: number;
163 cacheHitTokens: number;
164 sessionContext?: import("./sessionContextTypes").WireSessionContextDiagnostics;
165 }
166 export interface WireUsage {
167 promptTokens: number;
168 completionTokens: number;
169 totalTokens: number;
170 cacheHitTokens: number;
171 cacheMissTokens: number;
172 reasoningTokens?: number;
173 estimated?: boolean;
174 source?: string;
175 cacheDiagnostics?: WireCacheDiagnostics;
176 // Session-cumulative cache tokens — the status bar shows the aggregate
177 // hit-rate (Σhit/Σ(hit+miss)), steadier than the single-turn cacheHitTokens.
178 sessionCacheHitTokens: number;
179 sessionCacheMissTokens: number;
180 /** Latest single-request shape for context gauges; omit → use billable totals. */
181 contextPromptTokens?: number;
182 contextCompletionTokens?: number;
183 contextReasoningTokens?: number;
184 contextCacheHitTokens?: number;
185 contextCacheMissTokens?: number;
186 cost?: number;
187 currency?: string;
188 currencyCode?: string;
189 // Deprecated compatibility alias. Prefer cost + currencyCode / costQuote.
190 costUsd?: number;
191 costComplete?: boolean;
192 displayComplete?: boolean;
193 displayStatus?: string;
194 aggregateMode?: string;
195 originalTotals?: Money[];
196 /** Host-side structured quote; prefer over cost/currency aliases. */
197 costQuote?: CostQuote;
198 }
199
200 /** Display-only aggregate for one completed chat turn. */
201 export interface TurnUsage {
202 uncachedInputTokens: number;
203 outputTokens: number;
204 totalTokens: number;
205 cacheReadTokens?: number;
206 reasoningTokens?: number;
207 routes?: string[];
208 }
209
210 export interface Money {
211 amount: string;
212 currency: string;
213 }
214
215 export interface CostQuote {
216 original: Money;
217 originalTotals?: Money[];
218 valuations?: Record<string, {
219 money: Money;
220 basis: string;
221 source: string;
222 asOf: string;
223 rateSnapshot?: { base: string; quote: string; rate: number; source: string; asOf: string; stale?: boolean };
224 stale?: boolean;
225 }>;
226 selected?: Money;
227 billingMode?: string;
228 estimated: boolean;
229 costComplete?: boolean;
230 displayComplete?: boolean;
231 complete: boolean;
232 displayStatus?: "matched" | "fallback_original" | "bucketed" | "unavailable" | string;
233 aggregateMode?: "single_currency" | "common_valuation" | "currency_buckets" | string;
234 modelRef?: string;
235 usageSource?: string;
236 pricingFingerprint?: string;
237 rateDate?: string;
238 rateBand?: "peak" | "off_peak" | "mixed" | string;
239 ratedAt?: string;
240 incompleteReason?: string;
241 legacyEstimate?: boolean;
242 catalogSource?: string;
243 }
244
245 export interface WireRecoveryApproval {
246 source_agent?: string;
247 failed_tool?: string;
248 failed_summary?: string;
249 diagnosis?: string;
250 next_tool?: string;
251 next_action?: string;
252 change_kind?: string;
253 change_rationale?: string;
254 review_rationale?: string;
255 plan_before?: string;
256 plan_after?: string;
257 can_grant_task?: boolean;
258 task_grant_scope?: string;
259 }
260
261 export type { WireApproval, WireWriteAccessApproval } from "./approvalTypes";
262
263 export interface WireGuardian {
264 id: string;
265 tool: string;
266 subject: string;
267 outcome: string;
268 risk_level?: string;
269 user_authorization?: string;
270 rationale?: string;
271 duration_ms?: number;
272 usage?: WireUsage;
273 }
274
275 export interface WireDecisionReceipt {
276 id: string;
277 kind: string;
278 tool?: string;
279 subject?: string;
280 outcome: string;
281 }
282
283 export interface WireAskOption {
284 label: string;
285 description?: string;
286 }
287
288 export type PromptKind = "ask" | "approval" | "plan" | "recovery" | "mcp";
289 export interface PromptIdentity {
290 promptId: string;
291 turnId?: string;
292 runtimeEpoch?: string;
293 kind: PromptKind;
294 }
295 export type PromptLifecycle = "pending" | "submitting" | "resolved" | "expired";
296 export interface DecisionCardState {
297 identity: PromptIdentity;
298 lifecycle: PromptLifecycle;
299 failureNoticeShown?: boolean;
300 }
301
302 export interface WireAskQuestion {
303 id: string;
304 header?: string;
305 prompt: string;
306 options: WireAskOption[];
307 multi?: boolean;
308 }
309
310 export interface WireAsk {
311 id: string;
312 questions: WireAskQuestion[];
313 turnId?: string;
314 runtimeEpoch?: string;
315 }
316
317 export type { MCPAppInstanceView, MCPAppPresentation } from "./mcpAppProtocol";
318
319 // One server-initiated MCP elicitation awaiting accept/decline/cancel. Form
320 // mode carries a flat primitive JSON schema; url mode a credential-free target.
321 export interface WireMCPInteraction {
322 id: string;
323 server: string;
324 mode: "form" | "url";
325 message: string;
326 requestedSchema?: unknown;
327 url?: string;
328 elicitationId?: string;
329 turnId?: string;
330 runtimeEpoch?: string;
331 }
332
333 // Extension UI surfaces (stage 8a) — structured-only documents published by
334 // extension sidecars through the host UI hub. Exactly one sub-struct is set,
335 // selected by `kind`.
336 export interface WireExtensionStatus {
337 label: string;
338 detail?: string;
339 severity?: string; // "info" | "warn" | "error"
340 progress?: number;
341 }
342
343 export interface WireExtensionKeyValue {
344 key: string;
345 value: string;
346 }
347
348 export interface WireExtensionActionRef {
349 actionId: string;
350 label: string;
351 }
352
353 export interface WireExtensionCard {
354 title?: string;
355 markdown?: string;
356 text?: string;
357 fields?: WireExtensionKeyValue[];
358 progress?: number;
359 actions?: WireExtensionActionRef[];
360 }
361
362 export interface WireExtensionFormField {
363 key: string;
364 label?: string;
365 kind?: string; // "confirm" | "input" | "select" | "multiselect"
366 options?: string[];
367 default?: unknown;
368 required?: boolean;
369 }
370
371 export interface WireExtensionForm {
372 title?: string;
373 message?: string;
374 fields: WireExtensionFormField[];
375 }
376
377 export interface WireExtensionNotification {
378 title: string;
379 body?: string;
380 severity?: string; // "info" | "warn" | "error"
381 }
382
383 export interface WireExtensionSurface {
384 pluginId: string;
385 surfaceId: string;
386 sessionId?: string;
387 generation?: number;
388 formInstanceId?: string;
389 kind: string; // "status" | "card" | "form" | "notification"
390 status?: WireExtensionStatus;
391 card?: WireExtensionCard;
392 form?: WireExtensionForm;
393 notification?: WireExtensionNotification;
394 }
395
396 // ExtensionActionView is one handshake-declared extension UI action, the JSON
397 // twin of desktop's ExtensionActionView (stage 8b2). Slash is the public
398 // invocation name, "/<plugin>:<action>".
399 export interface ExtensionActionView {
400 plugin: string;
401 action: string;
402 slash: string;
403 description?: string;
404 }
405
406 // QuestionAnswer is the reply for one question, sent back via AnswerQuestion.
407 export interface QuestionAnswer {
408 questionId: string;
409 selected: string[];
410 }
411
412 export interface MemoryCitation {
413 id?: string;
414 source: string;
415 lineStart?: number;
416 lineEnd?: number;
417 note?: string;
418 kind?: string;
419 }
420
421 export interface WireEvent extends RecoveryEventFields {
422 sessionId?: string;
423 source?: string;
424 messageId?: string;
425 attemptId?: string;
426 receipt?: WireCompletionReceipt;
427 readPause?: import("./readPause").WireReadPause;
428 readCompletion?: import("../generated/desktopContract.generated").ReadCompletion;
429 kind: EventKind;
430 readStatus?: WireReadStatus;
431 /** session_changed: the transcript was replaced under the same path (head switch, clear). */
432 sessionReset?: boolean;
433 promptId?: string;
434 promptKind?: "ask" | "approval" | "plan" | "recovery" | "mcp" | string;
435 promptLegacy?: boolean;
436 turnId?: string;
437 seq?: number;
438 status?: TurnStatus;
439 text?: string;
440 detail?: string;
441 // Stable notice id for localization; empty/absent = localize by text match.
442 code?: string;
443 reasoning?: string;
444 memoryCitations?: MemoryCitation[];
445 level?: "info" | "warn";
446 tool?: WireTool;
447 usage?: WireUsage;
448 approval?: WireApproval;
449 ask?: WireAsk;
450 mcpInteraction?: WireMCPInteraction;
451 compaction?: WireCompaction;
452 maintenance?: WireContextMaintenance;
453 guardian?: WireGuardian;
454 decisionReceipt?: WireDecisionReceipt;
455 extension?: WireExtensionSurface;
456 err?: string;
457 checkpointTurn?: number; // Authoritative TurnDone rewind target; zero is valid.
458 submissionId?: string; // Opaque correlation for the exact optimistic user submission.
459 outcome?: "completed" | "partial" | "blocked" | "final_readiness" | "recovery_paused" | "completion_uncertain" | "incomplete_read";
460 readiness?: WireFinalReadiness;
461 protocolRecovery?: { id: string };
462 diagnostic?: { kind: string; status?: number; traceId?: string; providerId?: string; providerDisplayName?: string; protocol?: string; requestPath?: string };
463 /** Optional: "headers" | "stream". Older clients ignore unknown fields. */
464 retryScope?: "headers" | "stream" | "protocol";
465 streamAttempt?: WireStreamAttempt;
466 /** Durable session-inbox item id for steer / TurnDone correlation. */
467 itemId?: string;
468 sessionPath?: string; // Serve multi-session routing tag; absent locally.
469 workspace?: WireWorkspaceChanged;
470 /** turn_phase: working | checking | verifying | reviewing */
471 phase?: string;
472 /** completion_summary: content-free quality summary for role settings */
473 completion?: WireCompletionSummary;
474 tabId?: string; // Go's tabEventSink tags events for the correct per-tab reducer.
475 runtimeEpoch?: string; sessionGeneration?: number;
476 /** Unix milliseconds recorded by the desktop host when this turn began. */
477 turnStartedAt?: number;
478 sessionHitTokens?: number;
479 sessionMissTokens?: number;
480 sessionCost?: number;
481 sessionCurrency?: string;
482 // Deprecated compatibility alias. Prefer sessionCost + sessionCurrency.
483 sessionCostUsd?: number;
484 }
485
486 export interface WireCompletionSummary {
487 /** Local projection fields, preserved with the historical result card. */
488 receipt?: WireCompletionReceipt;
489 turnId?: string;
490 checkpointTurn?: number;
491 checking?: boolean;
492 liveChecks?: { toolCallId: string; command: string; output?: string }[];
493 preset: string;
494 verdict: string;
495 mutations: number;
496 changed_files?: number;
497 checks_passed: number;
498 checks_failed: number;
499 checks_suppressed: number;
500 review: string;
501 gap_kinds?: string[];
502 constraint_degraded: boolean;
503 /** Turn-time policy floor. Missing on historical events. */
504 floor?: "standard" | "delivery" | string;
505 /** Backend decision; authoritative when floor is present. */
506 attention?: boolean;
507 }
508
509 export type { TurnFileChange, TurnChanges, WireCompletionReceipt } from "./turnResultTypes";
510 import type { WireCompletionReceipt } from "./turnResultTypes";
511
512 export type WorkspaceWatchState = "active" | "degraded" | "unavailable";
513 export type WorkspaceChangeOp = "create" | "write" | "remove" | "rename" | "unknown";
514
515 export interface WorkspaceRevisions {
516 content: number;
517 tree: number;
518 workingTree: number;
519 gitMeta: number;
520 session: number;
521 }
522
523 export interface WorkspacePathChange {
524 path: string;
525 oldPath?: string;
526 op: WorkspaceChangeOp;
527 }
528
529 export interface WireWorkspaceChanged {
530 revisions: WorkspaceRevisions;
531 changes: WorkspacePathChange[];
532 allPaths: boolean;
533 source: "agent" | "filesystem" | "git" | "mixed" | "reconcile";
534 watchState: WorkspaceWatchState;
535 }
536
537 export type SessionRuntimePhase = "starting" | "ready" | "lease_blocked" | "failed" | "closing";
538
539 export interface SessionRuntimeView {
540 phase: SessionRuntimePhase;
541 epoch: string;
542 issue?: SessionRuntimeIssue;
543 }
544
545 /** Occupancy report for a session a local serve holds; drives the takeover dialog. */
546 export interface SessionTakeoverView {
547 available: boolean;
548 reason?: string;
549 sessionPath?: string;
550 holder?: "serve" | "external" | "other" | "free";
551 remoteAttached?: boolean;
552 running?: boolean;
553 mirrored?: boolean;
554 holderPid?: number;
555 holderHost?: string;
556 }
557
558 export interface WireFinalReadiness {
559 attempts?: number;
560 missing?: string[];
561 }
562
563 // Tab management types (desktop/tabs.go).
564 export interface TabMeta extends RemoteTabMetaFields {
565 historicalSource?: import("../generated/desktopContract.generated").SessionSourceRef;
566 id: string;
567 tabType?: "session" | "file";
568 scope: string;
569 workspaceRoot: string;
570 workspaceId?: string;
571 workspaceName: string;
572 workspacePath?: string;
573 gitBranch?: string;
574 isolatedWorktree?: boolean;
575 topicId: string;
576 topicTitle: string;
577 sessionPath?: string;
578 sessionId?: string; session?: SessionRef | null;
579 sessionRevision?: number;
580 sessionDigest?: string;
581 sessionGeneration?: number;
582 readOnly?: boolean;
583 /** Remote tab whose session a local runtime on the serve host took over. */
584 takenOver?: boolean;
585 filePath?: string;
586 projectColor?: string;
587 label: string;
588 ready: boolean;
589 runtime?: SessionRuntimeView;
590 running: boolean;
591 /** Unix milliseconds for the currently active foreground turn. */
592 turnStartedAt?: number;
593 pendingPrompt?: boolean;
594 backgroundJobs?: number;
595 cancelRequested?: boolean;
596 cancellable?: boolean;
597 turnId?: string;
598 turnStatus?: TurnStatus;
599 turnEventSeq?: number;
600 turnReplayAfterSeq?: number;
601 mode: Mode;
602 collaborationMode?: CollaborationMode;
603 toolApprovalMode?: ToolApprovalMode;
604 tokenMode?: TokenMode;
605 agentPreset?: AgentPreset; // retired compatibility field; current hosts emit standard
606 qualityFloor?: QualityFloor; // retired compatibility field; current hosts emit standard
607 floorInferred?: boolean; // retired compatibility field; current hosts emit false
608 goal?: string;
609 goalStatus?: GoalStatus;
610 goalView?: GoalLifecycleView;
611 recovered?: boolean;
612 recoveryReason?: string;
613 recoveryDigest?: string;
614 recoveryParentId?: string;
615 versionKind?: "normal" | "recovery" | "subagent" | string;
616 versionState?: "active" | "pending" | "resolved" | "trashed" | string;
617 parentVersionId?: string;
618 startupErr?: string;
619 authentication?: ConnectionAuthentication;
620 modelSettingsPending?: boolean;
621 active: boolean;
622 cwd: string;
623 }
624
625 export interface TerminalSessionView {
626 id: string;
627 title: string;
628 shell: string;
629 cwd: string;
630 createdAt: number;
631 exitCode?: number;
632 running: boolean;
633 }
634
635 export interface TerminalShellView {
636 id: string;
637 label: string;
638 }
639
640 export interface TerminalWorkspaceView {
641 available: boolean;
642 readOnly: boolean;
643 reason?: string;
644 sessions: TerminalSessionView[];
645 shells: TerminalShellView[];
646 }
647
648
649
650 export type { RecoveryLineageMember, RecoveryLineageView } from "./sessionRecoveryTypes";
651
652 export interface RecoveryCleanupRequest {
653 scope: string;
654 workspaceRoot?: string;
655 topicId: string;
656 apply: boolean;
657 }
658
659 export interface RecoveryPreferenceRequest {
660 scope: string;
661 workspaceRoot?: string;
662 topicId: string;
663 path: string;
664 /** Head inside a schema-2 log; empty for file-based recovery versions. */
665 headId?: string;
666 }
667
668 export interface RecoveryCleanupItem {
669 path: string;
670 status: "eligible" | "moved" | "busy" | "kept" | string;
671 error?: string;
672 }
673
674 export interface RecoveryCleanupResult {
675 eligible: number;
676 moved: number;
677 busy: number;
678 kept: number;
679 dryRun: boolean;
680 items: RecoveryCleanupItem[];
681 }
682
683 export interface DeliveryWorktreeAvailability {
684 available: boolean;
685 reason?: string;
686 repoRoot?: string;
687 branch?: string;
688 sourceDirty?: boolean;
689 }
690
691 export interface DeliveryWorktreeOpenResult {
692 workspaceRoot: string;
693 worktreeRoot: string;
694 sourceRoot: string;
695 branch: string;
696 sourceDirty: boolean;
697 sourceRevision?: string;
698 taskId?: string;
699 conversationId?: string;
700 tab: TabMeta;
701 }
702
703 export * from "./worktreeMergeTypes";
704
705 export type ProjectTopicStatus = "thinking" | "streaming" | "finishing" | "cancelling" | "unknown" | "waiting_confirmation" | "background_job" | "paused" | "awaiting_delivery" | "error" | "diverged_recovery";
706
707 export interface TopicMeta {
708 id: string;
709 title: string;
710 createdAt: number;
711 }
712
713 export interface SessionRecoveryEvent {
714 conversationId?: string;
715 activeVersionId?: string;
716 recoveryVersionId?: string;
717 originalPath?: string;
718 recoveryPath: string;
719 scope?: string;
720 workspaceRoot?: string;
721 topicId?: string;
722 topicTitle?: string;
723 recoveryReason?: string;
724 recoveryDigest?: string;
725 recoveryParentId?: string;
726 existing?: boolean;
727 baseRevision?: number;
728 diskRevision?: number;
729 canContinue?: boolean;
730 requiresChoice?: boolean;
731 }
732
733 export interface SessionVersionStateView {
734 conversationId?: string;
735 activeVersionId?: string;
736 activePath?: string;
737 recoveryVersionId?: string;
738 canContinue: boolean;
739 requiresChoice: boolean;
740 lineage: RecoveryLineageView;
741 }
742
743 export interface SessionRecoveryFailedEvent {
744 reason?: "lease_held" | "lease_unavailable" | string;
745 conversationId?: string;
746 topicId?: string;
747 canContinue?: boolean;
748 recoveryPending?: boolean;
749 recoveryPath?: string;
750 workspaceRoot?: string;
751 }
752
753 export interface ContextPanelInfo {
754 usedTokens: number;
755 windowTokens: number;
756 promptTokens: number;
757 completionTokens: number;
758 totalTokens: number;
759 reasoningTokens: number;
760 cacheHitTokens: number;
761 cacheMissTokens: number;
762 estimated?: boolean;
763 sessionCacheHitTokens: number;
764 sessionCacheMissTokens: number;
765 sessionCompletionTokens: number;
766 sessionEstimated?: boolean;
767 requestCount?: number;
768 elapsedMs?: number;
769 sessionCost?: number;
770 sessionCurrency?: string;
771 // Deprecated compatibility alias. Prefer sessionCost + sessionCurrency.
772 sessionCostUsd?: number;
773 sessionCostComplete?: boolean;
774 sessionCostEstimated?: boolean;
775 sessionBillingMode?: string;
776 sessionCostQuote?: CostQuote;
777 sources?: Record<string, UsageSourceStats>;
778 mock?: boolean;
779 readFiles: ReadFileRecord[];
780 changedFiles: ChangedFileInfo[];
781 contextBudget?: ContextBudgetInfo;
782 }
783
784 export interface UsageSourceStats {
785 promptTokens: number;
786 completionTokens: number;
787 totalTokens: number;
788 reasoningTokens: number;
789 cacheHitTokens: number;
790 cacheMissTokens: number;
791 estimated?: boolean;
792 requestCount: number;
793 sessionCost?: number;
794 sessionCurrency?: string;
795 sessionCostUsd?: number;
796 }
797
798 export interface ReadFileRecord {
799 path: string;
800 turn: number;
801 time: number;
802 offset?: number;
803 limit?: number;
804 truncated?: boolean;
805 }
806
807 export interface ChangedFileInfo {
808 path: string;
809 oldPath?: string;
810 sources: string[];
811 gitStatus?: string;
812 turns: number[];
813 latestPrompt?: string;
814 latestTime?: number;
815 }
816
817 // Bound-method payloads (desktop/app.go).
818 export interface HistoryMessage extends TranscriptTurnMetadata {
819 historyTurn?: number;
820 recordId?: string;
821 attemptId?: string;
822 submissionId?: string;
823 source?: string;
824 messageId?: string;
825 completionReceipt?: WireCompletionReceipt;
826 completionSummary?: WireCompletionSummary;
827 readCompletion?: import("../generated/desktopContract.generated").ReadCompletion;
828 turnId?: string;
829 readPause?: import("./readPause").WireReadPause;
830 role: string;
831 content: string;
832 detail?: string;
833 code?: string;
834 submitText?: string;
835 checkpointTurn?: number;
836 createdAt?: number;
837 reasoning?: string;
838 workDurationMs?: number;
839 turnDurationMs?: number;
840 turnUsage?: TurnUsage;
841 memoryCitations?: MemoryCitation[];
842 level?: "info" | "warn";
843 toolCalls?: HistoryToolCall[];
844 toolCallId?: string;
845 toolName?: string;
846 toolResultArchived?: boolean;
847 toolResultError?: string;
848 execution?: WireShellExecution;
849 presentedFiles?: PresentedFile[];
850 pending?: boolean;
851 trigger?: string;
852 messages?: number;
853 summary?: string;
854 archive?: string;
855 decisionReceipt?: WireDecisionReceipt;
856 readiness?: WireFinalReadiness;
857 protocolRecovery?: { id: string };
858 diagnostic?: { kind: string; status?: number; traceId?: string; providerId?: string; providerDisplayName?: string; protocol?: string; requestPath?: string };
859 serverSearch?: HistoryServerSearch[];
860 attachments?: Array<{ kind?: string; digest?: string; name?: string; mime?: string; width?: number; height?: number; bytes?: number }>;
861 }
862
863 export interface HistoryPage {
864 messages: HistoryMessage[];
865 startTurn: number;
866 endTurn: number;
867 totalTurns: number;
868 hasOlder: boolean;
869 revision?: number;
870 digest?: string;
871 /** Present only on a page a session switch built; carries the switch's
872 * content-free phase breakdown. */
873 switch?: HistorySwitchPhases | null;
874 }
875
876 // ── Two-phase topic activation (desktop/topic_activation.go) ────────────────
877
878 export interface TopicActivationRequest {
879 selector?: import("../generated/desktopContract.generated").SessionSelector;
880 scope: string;
881 workspaceRoot: string;
882 topicId: string;
883 sessionPath: string;
884 requestId?: string;
885 }
886
887 export interface TopicActivationTicket {
888 requestId: string;
889 tabId: string;
890 meta: TabMeta;
891 }
892
893 export type TopicActivationPhase = "starting" | "ready" | "failed" | "cancelled";
894
895 export interface TopicActivationEvent {
896 requestId: string;
897 tabId: string;
898 phase: TopicActivationPhase;
899 error?: string;
900 }
901
902 // tab:meta channel: a full refreshed Meta pushed after the background refresh
903 // of the expensive MetaForTab fields (git branch, image-input capability).
904 export interface TabMetaRefreshEvent {
905 tabId: string;
906 meta: Meta;
907 }
908
909 export interface PromptHistoryEntry {
910 text: string;
911 at: number; // unix ms
912 sessionPath: string;
913 turn: number;
914 }
915
916 export interface PromptHistoryResult {
917 entries: PromptHistoryEntry[] | null;
918 nonce: string;
919 olderCursor?: string;
920 hasOlder?: boolean;
921 }
922
923 // CheckpointMeta is one rewind point (a user turn) for the rewind UI.
924 export interface CheckpointMeta {
925 turn: number;
926 prompt: string;
927 files: string[];
928 fileCount?: number;
929 filesTruncated?: boolean;
930 turnFileCount?: number;
931 time: number; // unix ms
932 canCode?: boolean;
933 canConversation?: boolean;
934 coverage?: string;
935 coverageGaps?: string[];
936 expiredFilePayload?: boolean;
937 activeWriters?: number;
938 legacy?: boolean;
939 canUndoFiles?: boolean;
940 disabledReason?: string;
941 }
942
943 export type { RewindPlanView } from "./rewindTypes";
944
945 export interface RewindResultView {
946 ok?: boolean;
947 transactionId?: string;
948 undoAvailable?: boolean;
949 written?: string[];
950 deleted?: string[];
951 conversationOk?: boolean;
952 conversationForked?: boolean;
953 operationId?: string;
954 branch?: string;
955 partial?: boolean;
956 tabId?: string;
957 tab?: TabMeta;
958 error?: string;
959 conflicts?: string[];
960 coverage?: string;
961 }
962
963 export type { SessionMeta } from "./sessionMetaTypes";
964
965 export type { HistoryIndexStatus, HistorySearchContextLine, HistorySearchContextRequest, HistorySearchHit, HistorySearchPage, HistorySearchRequest, HistorySessionPage, HistorySessionPageRequest } from "./historyCatalogTypes";
966
967 export interface WorkspaceView {
968 path: string;
969 name: string;
970 current: boolean;
971 }
972
973 export interface ContextInfo {
974 used: number;
975 window: number;
976 sessionTokens: number;
977 compactRatio?: number;
978 sessionCost?: number;
979 sessionCurrency?: string;
980 cacheHitTokens?: number;
981 cacheMissTokens?: number;
982 estimated?: boolean;
983 sessionCostComplete?: boolean;
984 sessionCostQuote?: CostQuote;
985 sources?: Record<string, UsageSourceStats>;
986 maintenance?: ContextMaintenanceInfo;
987 contextBudget?: ContextBudgetInfo;
988 }
989
990 export interface Meta extends RemoteSessionMetaFields {
991 label: string;
992 ready: boolean;
993 runtime?: SessionRuntimeView;
994 startupErr?: string;
995 historicalSource?: import("../generated/desktopContract.generated").SessionSourceRef;
996 eventChannel: string;
997 sessionPath?: string;
998 sessionId?: string; session?: SessionRef | null;
999 sessionRevision?: number;
1000 sessionDigest?: string;
1001 sessionGeneration?: number;
1002 runtimeStateSnapshot?: import("./runtimeStateStore").RuntimeState;
1003 cwd: string;
1004 workspaceRoot?: string;
1005 workspaceName?: string;
1006 workspacePath?: string;
1007 gitBranch?: string;
1008 imageInputEnabled?: boolean;
1009 visionFallbackEnabled?: boolean;
1010 autoApproveTools?: boolean;
1011 bypass?: boolean; // legacy JSON key for YOLO/full-access tool auto-approval
1012 collaborationMode?: CollaborationMode;
1013 toolApprovalMode?: ToolApprovalMode;
1014 tokenMode?: TokenMode;
1015 agentPreset?: AgentPreset; // retired compatibility field; current hosts emit standard
1016 qualityFloor?: QualityFloor; // retired compatibility field; current hosts emit standard
1017 floorInferred?: boolean; // retired compatibility field; current hosts emit false
1018 goal?: string;
1019 goalStatus?: GoalStatus;
1020 goalView?: GoalLifecycleView;
1021 goalRuntime?: GoalRuntime;
1022 canonicalTodos?: Todo[]; pinnedFiles?: PinnedFileInfo[];
1023 }
1024 export type CollaborationMode = "normal" | "plan" | "goal";
1025 export type PermissionPreset = "read-only" | "workspace-write" | "danger-full-access";
1026 export type LegacyToolApprovalMode = "ask" | "auto" | "yolo";
1027 // Legacy values remain in the input union for old hosts and persisted fixtures;
1028 // normalizeToolApprovalMode is the only path into current UI/runtime state.
1029 export type ToolApprovalMode = PermissionPreset | LegacyToolApprovalMode;
1030 export interface SessionGrantSummary {
1031 scope: "tool" | "directory" | "command-prefix" | string;
1032 target: string;
1033 }
1034 export interface PermissionCapabilities {
1035 backend: string;
1036 enforcement: "full" | "partial" | "unavailable" | string;
1037 supportedPresets: PermissionPreset[];
1038 unavailableReason?: string;
1039 writeIsolation?: string;
1040 readIsolation?: string;
1041 networkIsolation?: string;
1042 }
1043 export interface PermissionSnapshot {
1044 sessionId: string;
1045 generation: number;
1046 revision: number;
1047 preset: PermissionPreset;
1048 workspaceRoot: string;
1049 grants: SessionGrantSummary[];
1050 capabilities: PermissionCapabilities;
1051 }
1052 // Retired wire vocabularies remain accepted so old sessions and remote hosts
1053 // can be decoded. Current local hosts emit full/balanced/standard.
1054 export type TokenMode = "full" | "economy" | "delivery" | "light" | "balanced";
1055 export type AgentPreset = "standard" | "light" | "balanced" | "delivery";
1056 export type QualityFloor = "standard" | "delivery";
1057 export type GoalStatus = "running" | "complete" | "blocked" | "stopped";
1058 export type GoalPhase = "active" | "paused" | "blocked" | "complete";
1059 export type GoalActivation = "armed" | "disarmed";
1060 export interface GoalLifecycleView {
1061 id: string;
1062 revision: number;
1063 objective: string;
1064 phase: GoalPhase;
1065 maxGoalRounds: number | null;
1066 roundsStarted: number;
1067 blockedReason?: { code: string; message: string };
1068 createdAt: string;
1069 updatedAt: string;
1070 activation: GoalActivation;
1071 stopReason?: string;
1072 }
1073 // Optional Goal runtime summary; absent for old hosts or when no goal is active.
1074 export interface GoalRuntime {
1075 turnsUsed: number;
1076 turnsLimit: number; // Deprecated: Goal exposes no turn limit and returns 0.
1077 tokensUsed: number;
1078 requestsUsed?: number;
1079 workDurationMs?: number;
1080 /** @deprecated Goal has no hard token limit; retained as 0 for old hosts/clients. */
1081 tokensLimit: number;
1082 noProgressTurns: number;
1083 /** @deprecated No longer enforced; retained for old hosts/clients. */
1084 noProgressLimit: number;
1085 lastReason?: string;
1086 stopCause?: string;
1087 budgetExtensions: number; // Deprecated: resumes no longer extend a numeric quota.
1088 }
1089 export function normalizeCollaborationMode(mode?: string, goal?: string, legacyMode?: Mode): CollaborationMode {
1090 if (mode === "plan" || mode === "goal" || mode === "normal") return mode;
1091 if (legacyMode && modeHasPlan(legacyMode)) return "plan";
1092 if ((goal ?? "").trim()) return "goal";
1093 return "normal";
1094 }
1095
1096 export function normalizeToolApprovalMode(
1097 mode?: string,
1098 legacyMode?: Mode,
1099 legacyAutoApproveTools?: boolean,
1100 fallbackMode?: ToolApprovalMode,
1101 ): PermissionPreset {
1102 const normalized = typeof mode === "string" ? mode.trim().toLowerCase() : "";
1103 if (normalized === "read-only" || normalized === "workspace-write" || normalized === "danger-full-access") return normalized as PermissionPreset;
1104 if (normalized === "ask") return "read-only";
1105 if (normalized === "auto" || normalized === "yolo") return "workspace-write";
1106 if (legacyAutoApproveTools || (legacyMode && modeHasAutoApproveTools(legacyMode))) return "workspace-write";
1107 if (fallbackMode && normalized === "") return normalizeToolApprovalMode(fallbackMode);
1108 return "read-only";
1109 }
1110
1111 export function normalizeTokenMode(mode?: string): TokenMode {
1112 void mode;
1113 return "full";
1114 }
1115
1116 /** Normalize the retired role vocabulary to the fixed compatibility value. */
1117 export function normalizeAgentPreset(mode?: string): AgentPreset {
1118 void mode;
1119 return "standard";
1120 }
1121
1122 export function tokenModeFromAgentPreset(preset: AgentPreset): TokenMode {
1123 void preset;
1124 return "full";
1125 }
1126
1127 // Mode is a compatibility string from older hosts. New permission state is
1128 // carried only by PermissionPreset and never derived from this display axis.
1129 export type Mode = "normal" | "plan" | "yolo" | "plan-yolo";
1130
1131 export function normalizeMode(mode?: string): Mode {
1132 if (mode === "plan" || mode === "yolo" || mode === "plan-yolo" || mode === "yolo-plan") {
1133 return mode === "yolo-plan" ? "plan-yolo" : mode;
1134 }
1135 return "normal";
1136 }
1137
1138 export function modeHasPlan(mode: Mode): boolean {
1139 return mode === "plan" || mode === "plan-yolo";
1140 }
1141
1142 export function modeHasAutoApproveTools(mode: Mode): boolean {
1143 return mode === "yolo" || mode === "plan-yolo";
1144 }
1145
1146 export function modeFromAxes(plan: boolean, autoApproveTools: boolean): Mode {
1147 if (plan && autoApproveTools) return "plan-yolo";
1148 if (plan) return "plan";
1149 if (autoApproveTools) return "yolo";
1150 return "normal";
1151 }
1152
1153 export function modeWithPlan(mode: Mode, plan: boolean): Mode {
1154 return modeFromAxes(plan, modeHasAutoApproveTools(mode));
1155 }
1156
1157 export function modeWithAutoApproveTools(mode: Mode, autoApproveTools: boolean): Mode {
1158 return modeFromAxes(modeHasPlan(mode), autoApproveTools);
1159 }
1160
1161 export interface CommandInfo {
1162 name: string; // without the leading slash
1163 description: string;
1164 hint?: string;
1165 kind: "builtin" | "custom" | "mcp" | "skill" | "subagent";
1166 group?: "actions" | "management" | "subagents" | "skills" | "integrations";
1167 plugin?: string;
1168 color?: string;
1169 draftBehavior?: "submit" | "setting" | "direct" | "unavailable";
1170 }
1171
1172 export interface DirEntry {
1173 name: string;
1174 path?: string;
1175 isDir: boolean;
1176 displayName?: string;
1177 displayPath?: string;
1178 }
1179
1180 export interface DroppedItem {
1181 kind: "workspace" | "attachment";
1182 path: string;
1183 isDir?: boolean;
1184 displayPath?: string;
1185 previewUrl?: string;
1186 }
1187
1188 export interface FilePreview {
1189 path: string;
1190 body: string;
1191 size: number;
1192 truncated: boolean;
1193 binary: boolean;
1194 version?: string;
1195 nextOffset?: number;
1196 kind?: "image" | "pdf" | "html" | "audio" | "video";
1197 mime?: string;
1198 url?: string;
1199 err?: string;
1200 }
1201
1202 export interface PresentedTextPage {
1203 path: string;
1204 body: string;
1205 offset: number;
1206 nextOffset: number;
1207 size: number;
1208 hasMore: boolean;
1209 version: string;
1210 }
1211
1212 export interface WorkspaceChangeView {
1213 path: string;
1214 oldPath?: string;
1215 sources: string[];
1216 gitStatus?: string;
1217 turns?: number[];
1218 latestPrompt?: string;
1219 latestTime?: number;
1220 canSessionRevert?: boolean;
1221 }
1222
1223 export interface WorkspaceChangesView {
1224 files: WorkspaceChangeView[];
1225 gitAvailable: boolean;
1226 gitErr?: string;
1227 gitBranch?: string;
1228 added?: number;
1229 removed?: number;
1230 incomplete?: boolean;
1231 }
1232
1233 export interface WorkspaceChangeDetailView {
1234 diff?: string;
1235 source?: "git" | "session";
1236 added?: number;
1237 removed?: number;
1238 binary?: boolean;
1239 truncated?: boolean;
1240 }
1241
1242 export interface GitCommitView {
1243 hash: string;
1244 author: string;
1245 date: string;
1246 message: string;
1247 }
1248
1249 export interface GitCommitDetailView {
1250 diff?: string;
1251 files?: string[];
1252 }
1253
1254 export interface ComposerInsertRequest {
1255 id: number;
1256 text: string;
1257 mode?: "insert" | "replace" | "prefix";
1258 }
1259
1260 // MCP & Skills drawer (desktop/app.go Capabilities) — the GUI counterpart to
1261 // /mcp + /skill: connected/failed servers and discoverable skills.
1262 export interface ServerView {
1263 name: string;
1264 transport: string;
1265 status: "connected" | "deferred" | "failed" | "initializing" | "disabled";
1266 /** @deprecated derived from enabled */
1267 startIntent?: "off" | "automatic" | string;
1268 runtimeState?: "idle" | "connecting" | "ready" | "issue" | string;
1269 protocolVersion?: string;
1270 sessionState?: "connecting" | "listening" | "ready" | "reconnecting" | "failed" | "closed" | string;
1271 reconnectAttempts?: number;
1272 errorKind?: "auth_required" | "session_missing" | "stream_closed" | "timeout" | "protocol" | "transport" | string;
1273 /** Product availability: available_on_demand | starting | connected | auth_required | project_auth_changed | start_failed | disabled */
1274 availability?: string;
1275 enabled?: boolean;
1276 installed?: boolean;
1277 action?: "none" | "authenticate" | "authorize" | "retry" | string;
1278 source?: "project" | "user" | "plugin" | "builtin" | string;
1279 configSource?: string;
1280 builtIn?: boolean;
1281 configured?: boolean;
1282 /** @deprecated same as enabled */
1283 autoStart: boolean;
1284 /** @deprecated ignored by runtime */
1285 tier?: "background" | "eager" | string;
1286 command?: string;
1287 args?: string[];
1288 url?: string;
1289 envKeys?: string[];
1290 headerKeys?: string[];
1291 tools: number;
1292 toolCount?: number;
1293 prompts: number;
1294 resources: number;
1295 hasTools?: boolean;
1296 error?: string;
1297 toolList?: MCPToolView[];
1298 callTimeoutSeconds?: number;
1299 toolTimeoutSeconds?: Record<string, number>;
1300 requiresLaunchApproval?: boolean;
1301 authStatus?: "none" | "possible" | "required" | string;
1302 authUrl?: string;
1303 authConfigured?: boolean;
1304 managedByPlugin?: string;
1305 }
1306 export interface MCPToolView {
1307 name: string;
1308 description: string;
1309 readOnlyHint?: boolean;
1310 destructiveHint?: boolean;
1311 schemaError?: string;
1312 }
1313 export interface SkillView {
1314 name: string;
1315 description: string;
1316 scope: string;
1317 sourceDir?: string;
1318 runAs: string;
1319 enabled: boolean;
1320 plugin?: string;
1321 model?: string;
1322 effort?: string;
1323 allowedTools?: string[];
1324 readOnly?: boolean;
1325 color?: string;
1326 invocation?: string;
1327 invocationMode?: string;
1328 body?: string;
1329 configuredModel?: string;
1330 configuredEffort?: string;
1331 }
1332 export interface SkillRootSkillView {
1333 name: string;
1334 description: string;
1335 scope: string;
1336 runAs: string;
1337 plugin?: string;
1338 model?: string;
1339 effort?: string;
1340 allowedTools?: string[];
1341 color?: string;
1342 invocation?: string;
1343 }
1344 export interface SkillRootView {
1345 dir: string;
1346 scope: string;
1347 priority: number;
1348 status: string;
1349 enabled: boolean;
1350 configured: boolean;
1351 removable: boolean;
1352 skills: number;
1353 skillItems?: SkillRootSkillView[];
1354 warning?: string;
1355 }
1356 export interface CapabilitiesView {
1357 servers: ServerView[];
1358 skills: SkillView[];
1359 skillRoots: SkillRootView[];
1360 plugins: PluginView[];
1361 allowImplicitInvocation?: boolean;
1362 }
1363 export interface SkillsSettingsView {
1364 skills: SkillView[];
1365 skillRoots: SkillRootView[];
1366 allowImplicitInvocation?: boolean;
1367 }
1368 export interface SubagentProfileInput {
1369 name: string;
1370 description: string;
1371 systemPrompt: string;
1372 color?: string;
1373 model?: string;
1374 effort?: string;
1375 allowedTools?: string[];
1376 readOnly?: boolean;
1377 scope?: "project" | "global";
1378 }
1379 export interface PluginView {
1380 name: string;
1381 version?: string;
1382 description?: string;
1383 source?: string;
1384 root: string;
1385 manifestKind?: string;
1386 enabled: boolean;
1387 skills: number;
1388 commands?: number;
1389 hooks: number;
1390 mcpServers: number;
1391 agents?: number;
1392 compatibility?: "full" | "partial" | "none" | string;
1393 mappedCapabilities?: string[];
1394 skippedCapabilities?: PluginCompatibilityIssue[];
1395 skillDetails?: PluginSkillView[];
1396 agentDetails?: PluginAgentView[];
1397 commandDetails?: PluginCommandView[];
1398 hookDetails?: PluginHookView[];
1399 mcpServerDetails?: PluginMCPServerView[];
1400 warnings?: string[];
1401 error?: string;
1402 }
1403 export interface PluginCompatibilityIssue {
1404 capability: string;
1405 path?: string;
1406 reason: string;
1407 }
1408 export interface PluginAgentView {
1409 name: string;
1410 description?: string;
1411 path?: string;
1412 invocation?: string;
1413 model?: string;
1414 allowedTools?: string[];
1415 }
1416 export interface PluginSkillView {
1417 name: string;
1418 description?: string;
1419 path?: string;
1420 invocation?: string;
1421 runAs?: string;
1422 }
1423 export interface PluginCommandView {
1424 name: string;
1425 description?: string;
1426 argHint?: string;
1427 path?: string;
1428 invocation?: string;
1429 shadowed?: boolean;
1430 shadowedByPlugin?: string;
1431 }
1432 export interface PluginHookView {
1433 event: string;
1434 match?: string;
1435 command?: string;
1436 contextFile?: string;
1437 description?: string;
1438 }
1439 export interface PluginMCPServerView {
1440 name: string;
1441 displayName?: string;
1442 description?: string;
1443 transport?: string;
1444 command?: string;
1445 url?: string;
1446 autoStart?: boolean;
1447 }
1448 export interface PluginInstallOptions {
1449 dryRun?: boolean;
1450 link?: boolean;
1451 replace?: boolean;
1452 name?: string;
1453 }
1454 export interface MCPServerInput {
1455 name: string;
1456 transport: string; // stdio | http | sse
1457 command: string;
1458 args: string[];
1459 url: string;
1460 env?: Record<string, string> | null;
1461 headers?: Record<string, string> | null;
1462 autoStart?: boolean | null;
1463 callTimeoutSeconds?: number | null;
1464 toolTimeoutSeconds?: Record<string, number> | null;
1465 }
1466
1467 export interface MCPInstallResult {
1468 name: string;
1469 state: "ready" | "action_required" | "issue";
1470 toolCount: number;
1471 action: "none" | "authenticate" | "authorize" | "retry";
1472 message: string;
1473 }
1474
1475 export interface MCPMarketplaceEntry {
1476 name: string;
1477 suggestedName: string;
1478 title?: string;
1479 description?: string;
1480 version?: string;
1481 repositoryUrl?: string;
1482 installable: boolean;
1483 unavailableReason?: string;
1484 transport?: "stdio" | "http" | "sse" | string;
1485 command?: string;
1486 args: string[];
1487 url?: string;
1488 }
1489
1490 export interface MCPMarketplaceView {
1491 servers: MCPMarketplaceEntry[];
1492 cached: boolean;
1493 warning?: string;
1494 }
1495
1496 export interface ModelInfo {
1497 displayName?: string;
1498 ref: string; // "provider/model" — pass to SetModel
1499 provider: string;
1500 model: string;
1501 current: boolean;
1502 contextWindow?: number;
1503 vision?: boolean;
1504 }
1505
1506 export interface EffortInfo {
1507 options?: { id: string; name: string; description?: string }[];
1508 supported: boolean;
1509 current: string; // adapter-owned ID; "auto" inherits the configured default
1510 default: string;
1511 levels: string[];
1512 }
1513
1514 // Slash sub-command / argument completion (desktop/app.go SlashArgs). Mirrors the
1515 // CLI's arg hints so the composer can suggest e.g. /skill → list/show/new/paths.
1516 export interface SlashArgItem {
1517 label: string;
1518 insert: string; // token to place at the current position
1519 hint: string;
1520 descend: boolean; // re-open the menu one level deeper after accepting
1521 }
1522 export interface SlashArgsResult {
1523 items: SlashArgItem[];
1524 from: number; // byte offset where the current token begins
1525 }
1526
1527 // Memory panel payloads (desktop/app.go MemoryView).
1528 export interface MemoryDoc {
1529 path: string;
1530 scope: string; // "user" | "ancestor" | "project" | "local"
1531 directory?: string;
1532 body: string;
1533 imports: Array<{ path: string; sourcePath: string }>;
1534 depth: number;
1535 order: number;
1536 precedence: number;
1537 }
1538
1539 export interface InstructionDiagnostic {
1540 code: string;
1541 path: string;
1542 sourcePath?: string;
1543 line?: number;
1544 message: string;
1545 }
1546
1547 export interface MemoryFact {
1548 id?: string;
1549 revision?: number;
1550 createdAt?: string;
1551 updatedAt?: string;
1552 name: string;
1553 title?: string;
1554 description: string;
1555 type: string; // "user" | "feedback" | "project" | "reference"
1556 scope: string; // "project" | "global"
1557 body: string;
1558 freshness: string; // "fresh" | "current" | "stale"
1559 }
1560
1561 export interface MemoryConflict {
1562 key: string;
1563 projectId: string;
1564 projectName: string;
1565 globalId: string;
1566 globalName: string;
1567 resolution: "project_over_global";
1568 }
1569
1570 export interface MemoryRecallHit {
1571 id: string;
1572 revision: number;
1573 name: string;
1574 title?: string;
1575 type: string;
1576 scope: string;
1577 score: number;
1578 freshness: string;
1579 reason: string;
1580 snippet: string;
1581 }
1582
1583 export interface MemoryRecallTrace {
1584 query: string;
1585 hits: MemoryRecallHit[];
1586 omitted: number;
1587 charBudget: number;
1588 usedChars: number;
1589 suppressed?: string;
1590 }
1591
1592 export interface MemoryArchive extends MemoryFact {
1593 path: string;
1594 archivedAt?: string;
1595 }
1596
1597 export interface MemoryScope {
1598 scope: string; // "user" | "project" | "local"
1599 path: string;
1600 }
1601
1602 export interface MemorySuggestion {
1603 id: string;
1604 name: string;
1605 title: string;
1606 description: string;
1607 type: string;
1608 scope: string; // "project" | "global"
1609 body: string;
1610 reason: string;
1611 evidence: string[];
1612 }
1613
1614 export interface SkillSuggestion {
1615 id: string;
1616 name: string;
1617 description: string;
1618 scope: string;
1619 body: string;
1620 reason: string;
1621 evidence: string[];
1622 }
1623
1624 export interface MemorySuggestionsView {
1625 memories: MemorySuggestion[];
1626 skills: SkillSuggestion[];
1627 generatedAt: string;
1628 available: boolean;
1629 source: string;
1630 }
1631
1632 export interface MemoryView {
1633 docs: MemoryDoc[];
1634 facts: MemoryFact[];
1635 archives: MemoryArchive[];
1636 scopes: MemoryScope[];
1637 instructionDiagnostics: InstructionDiagnostic[];
1638 conflicts: MemoryConflict[];
1639 lastRecall: MemoryRecallTrace;
1640 storeDir: string;
1641 storeGlobalDir?: string;
1642 available: boolean;
1643 }
1644
1645 // SettingsTab is the top-level navigation item in the Settings Centre modal.
1646 export type SettingsTab = "general" | "models" | "model-stats" | "providers" | "bots" | "mcp" | "remote" | "skills" | "subagents" | "plugins" | "memory" | "hooks" | "diagnostics" | "shortcuts" | "permissions" | "sandbox" | "network" | "browser" | "appearance" | "storage" | "updates";
1647
1648 export type { RuntimeDoctorReport } from "./runtimeDoctorTypes";
1649
1650 /** Capability diagnostics report from App.CapabilityDiagnostics (capdiag.Report). */
1651 export interface CapabilityDiagnosticsReport {
1652 schema_version: number;
1653 root: string;
1654 live: boolean;
1655 summary: {
1656 errors: number;
1657 warnings: number;
1658 infos: number;
1659 instructions: number;
1660 skills: number;
1661 commands: number;
1662 hooks: number;
1663 plugins: number;
1664 mcp_servers: number;
1665 };
1666 instructions: { docs: Array<{ path: string; scope: string; directory?: string; depth: number; order: number }> };
1667 skills: CapabilityAssetReport;
1668 commands: CapabilityAssetReport;
1669 hooks: {
1670 trusted_project: boolean;
1671 project_defines_hooks: boolean;
1672 sources: Array<{ scope: string; path: string; status: string; hook_count: number; parse_error?: string }>;
1673 entries: Array<{
1674 event: string;
1675 match?: string;
1676 command?: string;
1677 context_file?: string;
1678 description?: string;
1679 timeout_ms?: number;
1680 scope: string;
1681 source: string;
1682 blocking: boolean;
1683 }>;
1684 };
1685 plugins: {
1686 state_path?: string;
1687 packages: Array<{
1688 name: string;
1689 enabled: boolean;
1690 version?: string;
1691 root: string;
1692 manifest_kind?: string;
1693 skills: number;
1694 commands: number;
1695 hooks: number;
1696 mcp_servers: number;
1697 warnings?: string[];
1698 status: string;
1699 }>;
1700 };
1701 mcp: {
1702 servers: Array<{
1703 name: string;
1704 source?: string;
1705 package_owner?: string;
1706 transport: string;
1707 start_intent: string;
1708 command?: string;
1709 url_host?: string;
1710 env_keys?: string[];
1711 header_keys?: string[];
1712 runtime_status?: string;
1713 tool_count?: number;
1714 tools?: Array<{ name: string; read_only_hint?: boolean }>;
1715 error?: string;
1716 }>;
1717 };
1718 issues: CapabilityIssue[];
1719 }
1720
1721 export interface CredentialDiagnosticReport {
1722 home: string;
1723 credentialPath: string;
1724 pendingTransactions: number;
1725 checks: Array<{ id: string; status: "passed" | "failed" | "unknown" | "not_checked" | string; path?: string; message?: string }>;
1726 actions: string[];
1727 }
1728
1729 export interface CapabilityAssetReport {
1730 roots: Array<{ path: string; scope?: string; status: string }>;
1731 entries: Array<{
1732 name: string;
1733 description?: string;
1734 scope?: string;
1735 path: string;
1736 status: string;
1737 winner_path?: string;
1738 error?: string;
1739 run_as?: string;
1740 }>;
1741 winners: number;
1742 shadowed: number;
1743 disabled?: number;
1744 parse_errors?: number;
1745 }
1746
1747 export interface CapabilityIssue {
1748 severity: "error" | "warning" | "info" | string;
1749 code: string;
1750 subsystem: string;
1751 name?: string;
1752 source?: string;
1753 message: string;
1754 remediation?: string;
1755 settings_tab?: string;
1756 }
1757 // Settings panel payloads (desktop/settings_app.go).
1758 export interface ProviderView {
1759 displayName?: string;
1760 name: string;
1761 presetId?: string; // stable curated identity; read-only in the connection editor
1762 catalog?: ProviderCatalog; // protocol routes for this installed connection, including hidden legacy presets
1763 builtIn: boolean;
1764 added: boolean;
1765 kind: string;
1766 baseUrl: string;
1767 chatUrl?: string; // legacy OpenAI chat endpoint override; preserved for old-config compatibility
1768 requestUrl?: string; // exact provider request URL written by the current settings UI
1769 models: string[];
1770 visionModels: string[]; // legacy subset; new UI derives capability from modelOverrides
1771 visionModelsConfigured: boolean; // legacy explicit-list marker retained for old configs
1772 visionCapability?: "configurable" | "unsupported"; // backend authority; absent on older desktop payloads
1773 modelsUrl: string; // optional override for model discovery; empty derives from baseUrl
1774 default: string;
1775 apiKeyEnv: string;
1776 headers?: Record<string, string> | null; // optional extra request headers for compatible gateways
1777 extraBody?: Record<string, unknown> | null; // optional extra top-level request body fields for compatible gateways
1778 authHeader?: boolean; // Anthropic-compatible: send Authorization: Bearer instead of x-api-key
1779 noProxy?: boolean; // reach this provider's endpoint directly, bypassing the configured/system proxy
1780 keySet: boolean; // the env var currently resolves to a value
1781 requiresKey?: boolean; // false for explicit no-auth providers
1782 configured?: boolean; // selectable: key is set or no key is required
1783 keySource?: string;
1784 keySourcePath?: string;
1785 balanceUrl: string; // optional wallet-balance endpoint; "" disables the readout
1786 contextWindow: number;
1787 reasoningProtocol: string; // auto|deepseek|glm|kimi-k3|openai|none; empty = auto/model registry
1788 thinking: string; // provider-specific thinking override: ""|enabled|disabled|adaptive
1789 webSearch?: boolean; // expose a provider-executed web search tool when supported
1790 serverWebSearchCapability?: boolean; // backend-verified provider capability; absent on older desktop payloads
1791 supportedEfforts: string[]; // custom /effort levels; empty = use built-in Kind/BaseURL default
1792 defaultEffort: string; // /effort level when user picks "auto" or unset; "" = supportedEfforts[0]
1793 modelOverrides?: ProviderModelOverrideView[] | null;
1794 modelCapabilities?: ProviderModelCapabilityView[] | null;
1795 recommendedUpgradeAvailable?: boolean; // official legacy OpenAI entry can switch to recommended Anthropic access
1796 modelCatalogFingerprint?: string; // opaque compare-and-apply token for background model discovery
1797 }
1798
1799 export interface ProviderModelCatalogUpdate {
1800 name: string;
1801 expectedFingerprint: string;
1802 models: string[];
1803 default: string;
1804 visionModels: string[];
1805 modelCapabilities?: ProviderModelCapabilityUpdate[];
1806 }
1807
1808 import type { ProviderModelCapabilityView } from "./providerModelCapability";
1809 export type { ProviderModelCapabilityView } from "./providerModelCapability";
1810
1811 export interface ProviderModelCapabilityUpdate {
1812 model: string;
1813 inputModalities: string[];
1814 }
1815
1816
1817
1818 export interface ProviderModelOverrideView {
1819 model: string;
1820 reasoningProtocol: string;
1821 supportedEfforts: string[];
1822 defaultEffort: string;
1823 vision?: boolean | null;
1824 contextWindow?: number;
1825 maxOutputTokens?: number;
1826 }
1827
1828 // BalanceInfo is the wallet-balance readout (desktop/app.go Balance). available
1829 // is false when the provider declares no balanceUrl or a fetch failed; display is
1830 // the formatted amount in an original wallet currency; no implicit FX conversion.
1831 export interface BalanceInfo {
1832 available: boolean;
1833 display: string;
1834 detail?: string;
1835 complete?: boolean;
1836 rateDate?: string;
1837 approx?: boolean;
1838 currencies?: string[];
1839 primaryCurrency?: string;
1840 costDisplayCurrency?: string;
1841 multiCurrency?: boolean;
1842 err?: string;
1843 }
1844
1845 // ── Usage statistics (desktop/stats_app.go) ────────────────────────────────
1846
1847 // UsageStatsRequest selects the aggregation range and optional entry-point
1848 // filter for the usage statistics panel. Range is "7" | "14" | "30" | "90" |
1849 // "custom"; custom requires from/to as "2006-01-02" (inclusive, local dates).
1850 // Source "" or "all" aggregates every entry point; "desktop" | "cli" | "serve"
1851 // | "bot" | "remote" filters to that source's records.
1852 export interface UsageStatsRequest {
1853 range: string;
1854 from?: string;
1855 to?: string;
1856 source?: string;
1857 }
1858
1859 // DailyTokenUsage is one day's token total, per-model split and turn count in
1860 // the daily trend series.
1861 export interface DailyTokenUsage {
1862 day: string; // "2006-01-02"
1863 total: number;
1864 byModel: Record<string, number>; // model ref -> tokens
1865 byProvider: Record<string, number>; // provider name -> tokens
1866 requests: number; // API calls that day
1867 turns: number;
1868 cacheHit: number; // cached input tokens that day
1869 cacheMiss: number; // uncached input tokens that day
1870 }
1871
1872 // ModelTokenUsage is one model's aggregate within the range.
1873 export interface ModelTokenUsage {
1874 model: string; // canonical "provider/model"
1875 provider: string;
1876 tokens: number;
1877 percent: number; // 0..100
1878 }
1879
1880 // ProviderTokenUsage is one provider's aggregate within the range.
1881 export interface ProviderTokenUsage {
1882 provider: string;
1883 tokens: number;
1884 percent: number;
1885 }
1886
1887 // UsageStatsRange is the full aggregate the settings panel renders.
1888 export interface UsageStatsRange {
1889 from: string;
1890 to: string;
1891 tokens: number;
1892 requests: number; // API calls
1893 turns: number; // completed turns
1894 cacheHit: number;
1895 cacheMiss: number;
1896 activeDays: number;
1897 topModel: string;
1898 topProvider: string;
1899 daily: DailyTokenUsage[];
1900 models: ModelTokenUsage[];
1901 providers: ProviderTokenUsage[];
1902 }
1903
1904 // JobView is one running background job (desktop/app.go Jobs) for the status bar.
1905 export interface JobView {
1906 id: string;
1907 kind: string; // "bash" | "task"
1908 label: string;
1909 status: string; // "running"
1910 startedAt: number; // unix milliseconds
1911 }
1912
1913 export interface ActiveWorkView {
1914 running: boolean;
1915 pendingPrompt: boolean;
1916 cancellable: boolean;
1917 jobs: JobView[];
1918 }
1919
1920 export interface JobCancelBatchView {
1921 cancelled: string[];
1922 notRunning: string[];
1923 }
1924
1925 export interface BackgroundRuntimeView {
1926 tabId: string;
1927 title: string;
1928 detached: boolean;
1929 running: boolean;
1930 pendingPrompt: boolean;
1931 jobs: JobView[];
1932 }
1933
1934 export interface WorkspaceConflictView {
1935 state: "none" | "local" | "external";
1936 ownerTabId?: string; ownerTitle?: string;
1937 ownerScope?: string; ownerLabel?: string;
1938 ownerWork: ActiveWorkView;
1939 canReveal: boolean;
1940 canCreateWorktree: boolean;
1941 }
1942
1943 export interface PermissionsView {
1944 mode: string; // "ask" | "allow" | "deny"
1945 allow: string[];
1946 ask: string[];
1947 deny: string[];
1948 }
1949
1950 export interface SandboxView {
1951 bash: string; // "enforce" | "off"
1952 network: boolean;
1953 workspaceRoot: string;
1954 allowWrite: string[];
1955 effectiveWorkspaceRoot: string;
1956 effectiveWriteRoots: string[];
1957 shell: string; // "auto" | "bash" | "powershell" | "pwsh"
1958 effectiveShell?: string; // bound shell: "bash" | "zsh" | "sh" | "git-bash" | "powershell" | "pwsh"
1959 resolvedShell?: string; // shell a reload would pick now
1960 shellReloadRequired?: boolean;
1961 shellCapabilities: ShellCapabilityView[];
1962 gitCapability?: ShellCapabilityView | null;
1963 shellInstallAction?: ShellInstallActionView | null;
1964 shellRepairGuidance?: { manager: string; command?: string } | null;
1965 gitRepairGuidance?: { manager: string; command?: string } | null;
1966 }
1967 // One discovered interpreter: usable on this host, where, and why not.
1968 export interface ShellCapabilityView {
1969 id: string; // "bash" | "zsh" | "sh" | "git-bash" | "powershell" | "pwsh"
1970 variant?: string;
1971 available: boolean;
1972 path?: string;
1973 source?: string;
1974 reason?: string;
1975 }
1976 // Optional manual repair action the sandbox section may offer (Windows only).
1977 export interface ShellInstallActionView {
1978 id: string; // "git-for-windows"
1979 mode: string; // "manual"
1980 available: boolean;
1981 manualUrl?: string;
1982 }
1983 // Structured outcome of InstallShellSupport.
1984 export interface ShellInstallResult {
1985 status: string; // "manual_required" | "unsupported_platform"
1986 path?: string;
1987 reason?: string;
1988 manualUrl?: string;
1989 }
1990
1991 export interface NetworkProxyView {
1992 type: string;
1993 server: string;
1994 port: number;
1995 username: string;
1996 password: string;
1997 }
1998
1999 export interface NetworkView {
2000 proxyMode: string; // "auto" | "custom" | "off" (backend may still return legacy "env")
2001 proxyUrl: string;
2002 noProxy: string;
2003 proxy: NetworkProxyView;
2004 }
2005
2006 export interface AgentView {
2007 temperature: number;
2008 maxSteps: number;
2009 plannerMaxSteps: number;
2010 maxSubagentDepth: number;
2011 maxSubagentConcurrency: number;
2012 maxParallelWriters: number;
2013 systemPrompt: string;
2014 reasoningLanguage: string; // "auto" | "zh" | "en"
2015 compactRatio?: number; // Advanced global default; older backends omit it.
2016 effectiveCompactRatio?: number; // Active local session after project overrides.
2017 compactRatioOverridden?: boolean;
2018 }
2019
2020 export interface BotAllowlistView {
2021 enabled: boolean;
2022 allowAll: boolean;
2023 qqUsers: string[];
2024 feishuUsers: string[];
2025 weixinUsers: string[];
2026 qqApprovers: string[];
2027 feishuApprovers: string[];
2028 weixinApprovers: string[];
2029 qqAdmins: string[];
2030 feishuAdmins: string[];
2031 weixinAdmins: string[];
2032 qqGroups: string[];
2033 feishuGroups: string[];
2034 weixinGroups: string[];
2035 dingtalkUsers: string[];
2036 dingtalkApprovers: string[];
2037 dingtalkAdmins: string[];
2038 dingtalkGroups: string[];
2039 }
2040
2041 export interface BotAccessView {
2042 enabled: boolean;
2043 allowAll: boolean;
2044 pairingEnabled: boolean;
2045 users: string[];
2046 groups: string[];
2047 approvers: string[];
2048 admins: string[];
2049 }
2050
2051 export interface BotSelfUserIDsView {
2052 qq: string[];
2053 feishu: string[];
2054 weixin: string[];
2055 dingtalk: string[];
2056 }
2057
2058 export interface BotPairingView {
2059 enabled: boolean;
2060 requestTtlMinutes: number;
2061 maxPendingPerPlatform: number;
2062 }
2063
2064 export interface BotControlView {
2065 enabled: boolean;
2066 addr: string;
2067 tokenEnv: string;
2068 }
2069
2070 export interface BotRouteView {
2071 connectionId: string;
2072 platform: string;
2073 chatType: string;
2074 chatId: string;
2075 userId: string;
2076 threadId: string;
2077 model: string;
2078 toolApprovalMode: ToolApprovalMode | "" | string;
2079 workspaceRoot: string;
2080 }
2081
2082 export interface QQBotView {
2083 enabled: boolean;
2084 appId: string;
2085 appSecretEnv: string;
2086 secretSet: boolean;
2087 sandbox: boolean;
2088 model: string;
2089 toolApprovalMode: ToolApprovalMode | "" | string;
2090 workspaceRoot: string;
2091 access: BotAccessView;
2092 }
2093
2094 export interface FeishuBotView {
2095 enabled: boolean;
2096 domain: string;
2097 appId: string;
2098 appSecretEnv: string;
2099 secretSet: boolean;
2100 verificationToken: string;
2101 mode: string;
2102 webhookPort: number;
2103 requireMention: boolean;
2104 }
2105
2106 export interface WeixinBotView {
2107 enabled: boolean;
2108 accountId: string;
2109 tokenEnv: string;
2110 tokenSet: boolean;
2111 apiBase: string;
2112 }
2113
2114 export interface DingtalkBotView {
2115 enabled: boolean;
2116 clientId: string;
2117 clientSecretEnv: string;
2118 secretSet: boolean;
2119 botName: string;
2120 requireMention: boolean;
2121 model: string;
2122 toolApprovalMode: string;
2123 workspaceRoot: string;
2124 access: BotAccessView;
2125 }
2126
2127 export interface BotConnectionCredentialView {
2128 appId: string;
2129 appSecretEnv: string;
2130 accountId: string;
2131 tokenEnv: string;
2132 secretSet: boolean;
2133 }
2134
2135 export interface BotConnectionSessionMappingView {
2136 remoteId: string;
2137 sessionId: string;
2138 sessionSource: string;
2139 chatType: string;
2140 userId: string;
2141 threadId: string;
2142 scope: "global" | "project" | string;
2143 workspaceRoot: string;
2144 updatedAt: string;
2145 }
2146
2147 export interface BotConnectionView {
2148 id: string;
2149 provider: "qq" | "feishu" | "weixin" | string;
2150 domain: "qq" | "feishu" | "lark" | "weixin" | string;
2151 label: string;
2152 enabled: boolean;
2153 status: "disconnected" | "pending" | "connected" | "error" | string;
2154 model: string;
2155 toolApprovalMode: ToolApprovalMode | "" | string;
2156 workspaceRoot: string;
2157 access: BotAccessView;
2158 credential: BotConnectionCredentialView;
2159 sessionMappings: BotConnectionSessionMappingView[];
2160 lastError: string;
2161 createdAt: string;
2162 updatedAt: string;
2163 }
2164
2165 export interface BotSettingsView {
2166 enabled: boolean;
2167 model: string;
2168 toolApprovalMode: ToolApprovalMode | "" | string;
2169 maxSteps: number;
2170 debounceMs: number;
2171 queueMode: string;
2172 queueCap: number;
2173 queueDrop: string;
2174 ignoreSelfMessages: boolean;
2175 selfUserIds: BotSelfUserIDsView;
2176 control: BotControlView;
2177 pairing: BotPairingView;
2178 routes: BotRouteView[];
2179 allowlist: BotAllowlistView;
2180 qq: QQBotView;
2181 feishu: FeishuBotView;
2182 weixin: WeixinBotView;
2183 dingtalk: DingtalkBotView;
2184 connections: BotConnectionView[];
2185 }
2186
2187 export interface BotRuntimeStatusView {
2188 running: boolean;
2189 status: string;
2190 message: string;
2191 connections: number;
2192 startedAt: string;
2193 platforms: Record<string, string>;
2194 }
2195
2196 export interface BotInstallStartResult {
2197 ok: boolean;
2198 provider: string;
2199 domain: string;
2200 installId: string;
2201 url: string;
2202 deviceCode: string;
2203 userCode: string;
2204 interval: number;
2205 expireIn: number;
2206 message: string;
2207 }
2208
2209 export interface BotInstallPollResult {
2210 done: boolean;
2211 connection: BotConnectionView;
2212 status: string;
2213 message: string;
2214 error: string;
2215 }
2216
2217 export interface HookConfigView {
2218 event: string;
2219 match?: string;
2220 command: string;
2221 description?: string;
2222 timeout?: number;
2223 cwd?: string;
2224 }
2225
2226 export interface HooksSettingsView {
2227 scope: string;
2228 path: string;
2229 projectRoot: string;
2230 trusted: boolean;
2231 hooks: HookConfigView[];
2232 events: string[];
2233 }
2234
2235 export interface BotConnectionDiagnostic {
2236 id: string;
2237 label: string;
2238 status: string;
2239 message: string;
2240 messageId: string;
2241 phase: string;
2242 code: string;
2243 reportKind: string;
2244 reportDetail: string;
2245 occurredAt: string;
2246 }
2247
2248 export type { ModelSettingsChange, ModelSettingsResult } from "./modelSettingsTypes";
2249
2250 export interface DesktopStartupSettingsView {
2251 bot: BotSettingsView;
2252 desktopLanguage: string; // "" | "en" | "zh"; empty = auto
2253 desktopTheme: string; // "auto" | "dark" | "light"
2254 desktopThemeStyle: string;
2255 desktopTerminalTheme: string; // "auto" follows app | "dark" | "light"
2256 displayMode: string; sessionExperience?: "standard" | "deep"; reasoningDisplayMode: string; reasoningDisplayModeExplicit?: boolean;
2257 statusBarStyle: string; // "icon" | "text"
2258 statusBarItems: string[]; // ordered visible status bar item ids
2259 checkUpdates: boolean; // check for new versions on startup
2260 updaterEnabled?: boolean; // build capability; absent/unknown is disabled
2261 updateChannel: string; // compatibility field; always "stable"
2262 conversationWidth?: string; // "standard" | "full"; absent from older desktop payloads
2263 configWarnings?: string[]; configWarningsRevision?: number; // load recovery notices and async delivery barrier
2264 configPath?: string;
2265 }
2266
2267 export type ExternalOpenerKind = "file-manager" | "editor" | "terminal";
2268
2269 export interface ExternalOpenerView {
2270 id: string;
2271 name: string;
2272 kind: ExternalOpenerKind;
2273 iconDataUrl?: string;
2274 }
2275
2276 export interface ExternalOpenersView {
2277 openers: ExternalOpenerView[];
2278 preferred: string; workspaceOpenable?: boolean;
2279 }
2280
2281 // Auto-updater payloads (desktop/updater.go). UpdateInfo drives the update banner;
2282 // UpdateProgress streams on the "updater:progress" event during download/install.
2283 export interface UpdateInfo {
2284 available: boolean;
2285 current: string;
2286 latest: string;
2287 notes: string;
2288 channel: string;
2289 canSelfUpdate: boolean; // macOS true only for signed/notarized builds
2290 manualOnly?: boolean;
2291 manualReason?: string;
2292 installMode?: "portable" | "deb" | "manual" | string;
2293 requiresElevation?: boolean;
2294 downloaded: boolean;
2295 downloadUrl: string; // human-facing releases page (macOS path / fallback link)
2296 assetSize: number; // running platform's artifact size, for the progress bar
2297 err?: string; // set when the check itself failed (both endpoints down)
2298 }
2299
2300 export interface UpdateDownloadResult {
2301 requestId: string;
2302 version: string;
2303 channel: string;
2304 path: string;
2305 size: number;
2306 sha256: string;
2307 }
2308
2309 export interface UpdateProgress {
2310 requestId: string;
2311 version: string;
2312 channel: "stable" | "preview" | string;
2313 phase: "downloading" | "verifying" | "downloaded" | "authorizing" | "recovering" | "installing" | "relaunching" | "done" | "error";
2314 received: number;
2315 total: number;
2316 err?: string;
2317 }
2318
2319 // Task Monitor panel types (internal/taskmonitor).
2320
2321 export type TaskState =
2322 | "queued"
2323 | "running"
2324 | "waiting"
2325 | "succeeded"
2326 | "failed"
2327 | "cancelled"
2328 | "stale"
2329 | string; // forward-compat
2330
2331 export type RuntimeState = "unknown" | "alive" | "exited" | string;
2332
2333 export interface TaskSnapshot {
2334 schema_version: number;
2335 task_id: string;
2336 job_id?: string; // jobs.Manager-local runtime identifier
2337 session_id: string;
2338 state: TaskState;
2339 runtime_state?: RuntimeState; // absent in snapshots written before this field existed
2340 version: number;
2341 created_at: string; // ISO 8601
2342 updated_at: string; // ISO 8601
2343 error_code?: string;
2344 error_summary?: string;
2345 }
2346
2347 export type { TaskActionRequest, TaskCatalogItem, TaskCatalogStatus, TaskEventPage, TaskEventPageRequest, TaskPage, TaskPageRequest } from "./taskCatalogTypes";
2348
2349 export interface ControlResult {
2350 schema_version: number;
2351 command: string;
2352 task_id: string;
2353 session_id?: string;
2354 state?: TaskState;
2355 runtime_state?: RuntimeState;
2356 version?: number;
2357 accepted: boolean;
2358 idempotent: boolean;
2359 error?: { code: string; message: string };
2360 }
2361
2362 export interface TaskEvent {
2363 sequence: number;
2364 timestamp: string; // ISO 8601
2365 event_type: string;
2366 task_id: string;
2367 session_id: string;
2368 state: TaskState;
2369 runtime_state?: RuntimeState;
2370 error_code?: string;
2371 error_summary?: string;
2372 }
2373
2373 lines TYPESCRIPT