@prismshadow/penguin-server 0.2.9 → 0.2.11

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 (37) hide show
  1. package/README.md +1 -0
  2. package/dist/api/types.d.ts +426 -87
  3. package/dist/auth-token.js +4 -2
  4. package/dist/auth-token.js.map +1 -1
  5. package/dist/{chunk-WL5FUO3A.js → chunk-ADZJYDNC.js} +201 -140
  6. package/dist/chunk-ADZJYDNC.js.map +1 -0
  7. package/dist/{chunk-OMBFPEGQ.js → chunk-GOO5VUAB.js} +10 -8
  8. package/dist/chunk-GOO5VUAB.js.map +1 -0
  9. package/dist/chunk-HMTT2PX4.js +93 -0
  10. package/dist/chunk-HMTT2PX4.js.map +1 -0
  11. package/dist/chunk-HOS3W3UP.js +127 -0
  12. package/dist/chunk-HOS3W3UP.js.map +1 -0
  13. package/dist/{chunk-OTYHSDV7.js → chunk-Q65VPAQS.js} +2 -2
  14. package/dist/chunk-Q65VPAQS.js.map +1 -0
  15. package/dist/index.js +5587 -2922
  16. package/dist/index.js.map +1 -1
  17. package/dist/lock.d.ts +9 -1
  18. package/dist/lock.js +3 -1
  19. package/dist/machine-status.d.ts +18 -0
  20. package/dist/machine-status.js +37 -0
  21. package/dist/machine-status.js.map +1 -0
  22. package/dist/reset-admin-password.js +6 -4
  23. package/dist/reset-admin-password.js.map +1 -1
  24. package/package.json +6 -3
  25. package/web-dist/assets/addon-clipboard-1cARCaK9.js +1 -0
  26. package/web-dist/assets/{addon-fit-BjXzaLkS.js → addon-fit-BWdzl8Er.js} +1 -1
  27. package/web-dist/assets/{addon-web-links-D4HvCIde.js → addon-web-links-DjXuvn4Z.js} +1 -1
  28. package/web-dist/assets/{highlighter-Di8euoN5.js → highlighter-Cu43iYr8.js} +1 -1
  29. package/web-dist/assets/index-Bm9n7ZV-.js +457 -0
  30. package/web-dist/assets/index-DR4PrRzS.css +1 -0
  31. package/web-dist/assets/{xterm-XhYBaOEK.js → xterm-DKcY6q-I.js} +1 -1
  32. package/web-dist/index.html +2 -2
  33. package/dist/chunk-OMBFPEGQ.js.map +0 -1
  34. package/dist/chunk-OTYHSDV7.js.map +0 -1
  35. package/dist/chunk-WL5FUO3A.js.map +0 -1
  36. package/web-dist/assets/index-C6i84Esu.js +0 -451
  37. package/web-dist/assets/index-DW00p4Ny.css +0 -1
@@ -370,7 +370,7 @@ interface ModelInfo {
370
370
  interface ModelsResponse {
371
371
  /** Paired reference to the default Model. */
372
372
  defaultModel?: ModelRefDto;
373
- /** Vision model used as a proxy reader for read_image (describes images when the session model has vision=false). */
373
+ /** Vision model used as a proxy reader for read_file (describes images when the session model has vision=false). */
374
374
  visionModel?: ModelRefDto;
375
375
  /**
376
376
  * When the Project's model/credential config last changed (ISO; the config file's mtime,
@@ -416,7 +416,7 @@ interface ModelUpdateEntry {
416
416
  interface ModelsUpdateRequest {
417
417
  /** Must be included in models (matched by paired reference). */
418
418
  defaultModel?: ModelRefDto;
419
- /** Vision model used as a proxy reader for read_image: must be included in models and not annotated vision=false; omitted keeps the existing value. */
419
+ /** Vision model used as a proxy reader for read_file: must be included in models and not annotated vision=false; omitted keeps the existing value. */
420
420
  visionModel?: ModelRefDto;
421
421
  models: ModelUpdateEntry[];
422
422
  }
@@ -708,12 +708,12 @@ interface VaultEntryUpdate {
708
708
  interface VaultUpdateRequest {
709
709
  entries: VaultEntryUpdate[];
710
710
  }
711
- /** One installed Skill the library carries a higher version of (see {@link AgentSummary.skillUpdates}). */
712
- interface SkillUpdateRef {
713
- /** Skill directory name — the identity install / uninstall address it by. */
711
+ /** One installed plugin (a skill or a hook package) the library carries a higher version of (see {@link AgentSummary.pluginUpdates}). */
712
+ interface PluginUpdateRef {
713
+ /** Plugin name — what `POST …/plugins` reinstalls to bring the Agent up to date. */
714
714
  name: string;
715
- /** The LIBRARY's version, i.e. what installing again would bring, not what is on disk. */
716
- version: number;
715
+ /** The LIBRARY's version (`YYYY.MM.DD.N`), i.e. what installing again would bring, not what is on disk. */
716
+ version: string;
717
717
  }
718
718
  interface AgentSummary {
719
719
  agentId: string;
@@ -740,14 +740,17 @@ interface AgentSummary {
740
740
  scheduleCount: number;
741
741
  /** Installed Skill count (number of agent_state/skills/<name>/ directories with a SKILL.md). */
742
742
  skillCount: number;
743
- /**
744
- * Installed Skills the built-in library has moved past, each with the library version on
745
- * offer — the Skill-library update gate, riding along on the Agent list so a badge over
746
- * that page costs no request of its own. Empty when nothing is behind. Skills that are not
747
- * in the library (installed from a zip or a picked directory) are never listed: there is no
743
+ /** Installed hook-package count (number of agent_state/hooks/<name>/ directories with a hooks.json). */
744
+ hookCount: number;
745
+ /**
746
+ * Installed plugins the built-in library has moved past — a skill or a hook package whose
747
+ * on-disk version is behind the library plugin that ships it — each with the library version
748
+ * on offer: the plugin-library update gate, riding along on the Agent list so a badge over
749
+ * that page costs no request of its own. Empty when nothing is behind. Skills the library
750
+ * does not carry (installed from a zip or a picked directory) are never listed: there is no
748
751
  * library version for them to be behind.
749
752
  */
750
- skillUpdates: SkillUpdateRef[];
753
+ pluginUpdates: PluginUpdateRef[];
751
754
  /** Memory count (topic files summed over the scope directories under agent_state/memory/, independent of the memory switch). */
752
755
  memoryCount: number;
753
756
  }
@@ -761,11 +764,12 @@ interface AgentCreateRequest {
761
764
  name?: string;
762
765
  description?: string;
763
766
  /**
764
- * Library Skill names installed into the new Agent, seeding it at creation. Every name must
765
- * exist in the library (404 `unknown_skill` otherwise, before anything is created); omitted or
766
- * empty leaves the Agent with no Skills, which is what a plain Agent gets by default.
767
+ * Library plugin names installed into the new Agent, seeding it at creation — each plugin's
768
+ * skills and hook package. Every name must exist in the library (404 `unknown_plugin`
769
+ * otherwise, before anything is created); omitted or empty leaves the Agent with nothing
770
+ * installed, which is what a plain Agent gets by default.
767
771
  */
768
- skills?: string[];
772
+ plugins?: string[];
769
773
  /**
770
774
  * Skills imported from a directory on disk instead of the library. `skillsDirectory` is the
771
775
  * absolute path the user picked and `directorySkills` are the names to install from it, read
@@ -778,7 +782,7 @@ interface AgentCreateRequest {
778
782
  /**
779
783
  * Base64 of an exported Agent State snapshot package (`.tar.gz`): the new Agent is
780
784
  * initialized from the package instead of the default template. Mutually exclusive with
781
- * skill seeding (`skills` / `skillsDirectory`) — the package carries its own skills.
785
+ * seeding (`plugins` / `skillsDirectory`) — the package carries its own skills and hooks.
782
786
  * Explicit `name` / `description` override the package's values; absent ones keep them.
783
787
  */
784
788
  dataBase64?: string;
@@ -840,6 +844,16 @@ interface AgentSchedulesConfigDto {
840
844
  /** Whether the stored template carries `{{SCHEDULES}}`; POST …/schedules/template-placeholder inserts it explicitly. */
841
845
  templateHasPlaceholder: boolean;
842
846
  }
847
+ /**
848
+ * Hook config, edited on the Hooks tab. One Agent-level switch and no prompt: hook packages
849
+ * are scripts run at the loop's hook points, not text injected into the context. `enabled`
850
+ * reports the effective value (a config with no `hooks` section reads as enabled, matching
851
+ * core).
852
+ */
853
+ interface AgentHooksConfigDto {
854
+ /** Whether a Session created from now on runs the installed hook packages (they stay installed either way). */
855
+ enabled: boolean;
856
+ }
843
857
  /** Structured view of system_config.yaml (for the edit form). */
844
858
  interface AgentConfigDto {
845
859
  name?: string;
@@ -860,6 +874,7 @@ interface AgentConfigDto {
860
874
  vault: AgentVaultConfigDto;
861
875
  skills: AgentSkillsConfigDto;
862
876
  schedules: AgentSchedulesConfigDto;
877
+ hooks: AgentHooksConfigDto;
863
878
  toolsBuiltin: ToolDefinitionConfig[];
864
879
  mcpServers: MCPServerConfig[];
865
880
  }
@@ -919,6 +934,10 @@ interface AgentConfigUpdateRequest {
919
934
  enabled?: boolean;
920
935
  prompt?: string;
921
936
  };
937
+ /** The Agent-level hook switch; it has no prompt half. */
938
+ hooks?: {
939
+ enabled?: boolean;
940
+ };
922
941
  toolsBuiltin?: ToolDefinitionConfig[];
923
942
  mcpServers?: MCPServerConfig[];
924
943
  };
@@ -1044,10 +1063,12 @@ interface SessionInfo {
1044
1063
  approvalMode: ApprovalMode;
1045
1064
  /**
1046
1065
  * Thinking level pinned for this Session (set via PATCH; the Web App's in-chat picker).
1047
- * Unset = never pinned: runs that carry no level of their own fall back to the Agent
1048
- * config's `model.thinking_level`, so config edits keep taking effect. Once pinned it
1049
- * survives reloads and applies to every later run of this Session, and an Agent-config
1050
- * change no longer moves it.
1066
+ * Unset = never pinned: each model context the Session opens reads the Agent config's
1067
+ * `model.thinking_level`, so config edits keep taking effect. Once pinned it survives
1068
+ * reloads and applies from the Session's very next LLM request — the thinking level is
1069
+ * the soft-limited runtime parameter, changeable mid-context at the cost of the
1070
+ * provider's cached context (the picker advises compacting first) — and every later
1071
+ * context opens at it; an Agent-config change no longer moves it.
1051
1072
  */
1052
1073
  thinkingLevel?: ThinkingLevelName;
1053
1074
  /** Short title auto-generated by the model after the first turn; unset until generated (frontend shows "New Chat"). */
@@ -1090,6 +1111,23 @@ interface SessionInfo {
1090
1111
  tracePath?: string;
1091
1112
  /** Present when the Session has an ENABLED messaging binding: its channel (the sidebar row's per-channel indicator). */
1092
1113
  messagingChannel?: MessagingChannel;
1114
+ /**
1115
+ * Background work the Session's loaded runtime still owns: command sessions running past
1116
+ * their yield window (`exec_command` promotions and `run_in_background` launches) and
1117
+ * background subagent sessions mid-round. Read from the runtime's in-memory registries —
1118
+ * no Trace is consulted — and present only while at least one count is non-zero, so a
1119
+ * Session that is not loaded (a resumed entry starts with empty registries) and one with
1120
+ * nothing running both omit it. Changes are pushed as `session_background` on the user
1121
+ * channel; list rows and the single-session GET carry the same field.
1122
+ */
1123
+ backgroundTasks?: SessionBackgroundTasks;
1124
+ }
1125
+ /** The background-task counts of one Session (see SessionInfo.backgroundTasks). */
1126
+ interface SessionBackgroundTasks {
1127
+ /** Background command sessions whose process is still running. */
1128
+ processes: number;
1129
+ /** Background subagent sessions (promoted to a `subagent_id`) currently mid-round. */
1130
+ subagents: number;
1093
1131
  }
1094
1132
  /**
1095
1133
  * Session list category, the sidebar's four-way split applied server-side: archived wins
@@ -1110,6 +1148,13 @@ interface SessionsResponse {
1110
1148
  * content that lives in other Workspaces.
1111
1149
  */
1112
1150
  workspaceCounts?: Record<string, SessionCategoryCounts>;
1151
+ /**
1152
+ * Present with `counts`: each Workspace path's newest Session (any category), as its
1153
+ * `createdAt`. With `workspaceCounts` this is what lets the sidebar list every Workspace
1154
+ * that holds Sessions and place the groups by recency before — or without — loading any
1155
+ * of their rows.
1156
+ */
1157
+ workspaceLatest?: Record<string, string>;
1113
1158
  }
1114
1159
  /** Server directory browsing (advanced new-Workspace picker): starts from the home directory by default, can navigate up to the root. */
1115
1160
  interface DirEntryInfo {
@@ -1184,9 +1229,10 @@ interface SessionPatchRequest {
1184
1229
  approvalMode?: ApprovalMode;
1185
1230
  /**
1186
1231
  * Pin this Session's thinking level (`none | low | medium | high | xhigh | max`, anything else
1187
- * is a 400). It applies to every later run of the Session that doesn't carry its own
1188
- * level, and replaces the Agent-config fallback for this Session. There is no unpin:
1189
- * the picker only offers concrete levels.
1232
+ * is a 400). It replaces the Agent-config fallback for this Session and applies from the
1233
+ * very next LLM request — soft-limited: a mid-context change is allowed, at the cost of
1234
+ * the provider's cached context, which is why the picker advises compacting first. There
1235
+ * is no unpin: the picker only offers concrete levels.
1190
1236
  */
1191
1237
  thinkingLevel?: ThinkingLevelName;
1192
1238
  /** Archive / unarchive (default list hides archived). */
@@ -1250,6 +1296,14 @@ interface MessagesPageInfo {
1250
1296
  prior: {
1251
1297
  subagentTokens: number;
1252
1298
  elapsedMs: number;
1299
+ /**
1300
+ * Model-API time and tool wall time accrued before this window, the breakdown of
1301
+ * `elapsedMs` the chat header shows under it. Seeded together with their total: seeding
1302
+ * one alone would put a full elapsed time beside components covering only the window.
1303
+ * The two may overlap and do not partition `elapsedMs` (see `TraceTaskStats.toolMs`).
1304
+ */
1305
+ apiMs: number;
1306
+ toolMs: number;
1253
1307
  sessionTokens: number;
1254
1308
  contextTokens: number;
1255
1309
  };
@@ -1307,14 +1361,6 @@ type TaskInputPart = {
1307
1361
  };
1308
1362
  interface TaskCreateRequest {
1309
1363
  input: TaskInputPart[];
1310
- /**
1311
- * Thinking level for this Task's LLM requests (a per-turn parameter; one of
1312
- * `none | low | medium | high | xhigh | max`, anything else is a 400). Omitted = falls back to
1313
- * the Session's pinned level (`SessionInfo.thinkingLevel`) and, when that is unset too,
1314
- * to the Agent config's `model.thinking_level`. A queued follow-up (`queueIfBusy`) keeps
1315
- * its level and applies it when it auto-starts.
1316
- */
1317
- thinkingLevel?: ThinkingLevelName;
1318
1364
  /**
1319
1365
  * Queue instead of 409 when a Task/compaction is already in progress: the input is held
1320
1366
  * server-side and auto-starts as an ordinary next task once the session returns to idle
@@ -1324,14 +1370,16 @@ interface TaskCreateRequest {
1324
1370
  /**
1325
1371
  * Present = goal mode: the input's text becomes the objective (leading `[use_skills]`
1326
1372
  * blocks and the like are stripped from the recorded objective; the round-1 message keeps
1327
- * them) and the server loops the Session until the goal reaches a terminal state.
1328
- * `budget` is the token budget (uncached input + output); omitted or -1 = unlimited.
1373
+ * them) and the Session's installed `goal` hook package drives round after round until the
1374
+ * goal reaches a terminal state. `budget` is the token budget (uncached input + output);
1375
+ * omitted or -1 = unlimited. Requires the goal plugin installed on the Agent — 409
1376
+ * `goal_plugin_not_installed` otherwise.
1329
1377
  */
1330
1378
  goal?: {
1331
1379
  budget?: number;
1332
1380
  };
1333
1381
  }
1334
- /** Goal-mode run state (from goal_state; the chat page's banner restores from the latest row). */
1382
+ /** Goal-mode run state, read from the Session's GOAL.json — the goal plugin's file (the chat page's banner restores from it; a live status on an idle Session reads as `aborted`). */
1335
1383
  interface GoalStateView {
1336
1384
  objective: string;
1337
1385
  status: "active" | "complete" | "blocked" | "budget_limited" | "aborted";
@@ -1339,7 +1387,6 @@ interface GoalStateView {
1339
1387
  budget: number;
1340
1388
  used: number;
1341
1389
  rounds: number;
1342
- updatedAt: string;
1343
1390
  }
1344
1391
  interface GoalResponse {
1345
1392
  /** The Session's most recent goal run; null if it never ran one. */
@@ -1455,8 +1502,6 @@ interface RecalledMessageResponse {
1455
1502
  fileName: string;
1456
1503
  dataUrl: string;
1457
1504
  }[];
1458
- /** Follow-up recall only: the per-turn thinking level the entry was queued with, when one was. */
1459
- thinkingLevel?: ThinkingLevelName;
1460
1505
  }
1461
1506
  interface ApprovalDecisionRequest {
1462
1507
  decision: "allow" | "deny";
@@ -2002,6 +2047,13 @@ type ServerEvent =
2002
2047
  queued?: number;
2003
2048
  /** Steering messages queued but not yet delivered (absent = none): lets the composer's hint and its content survive reloads. */
2004
2049
  pendingSteering?: PendingSteeringInfo[];
2050
+ /**
2051
+ * Steering the run ended without delivering (absent = none) — an interrupt while a tool
2052
+ * was running is the ordinary way to produce one. Handed back rather than discarded: the
2053
+ * composer recalls each by the same handle and restores it into the draft, so the typed
2054
+ * message returns to the input box instead of being lost.
2055
+ */
2056
+ returnedSteering?: PendingSteeringInfo[];
2005
2057
  /** Queued follow-up tasks awaiting auto-start (absent = none): per-entry content + recall handle, alongside the `queued` count. */
2006
2058
  pendingFollowUps?: PendingFollowUpInfo[];
2007
2059
  /**
@@ -2043,6 +2095,19 @@ type ServerEvent =
2043
2095
  lastActiveAt: string;
2044
2096
  hasTrace: boolean;
2045
2097
  }
2098
+ /**
2099
+ * A Session's background-task counts changed: a command promoted to the background, a
2100
+ * process that exited or was stopped, a background subagent starting or settling a round,
2101
+ * a released session. The counts are the row's `backgroundTasks` as they stand after the
2102
+ * change — zeros included, so a list can clear its mark without refetching. Published to
2103
+ * the user channels of the Project's owner and members, like `session_state`.
2104
+ */
2105
+ | {
2106
+ type: "session_background";
2107
+ sessionId: string;
2108
+ processes: number;
2109
+ subagents: number;
2110
+ }
2046
2111
  /** Last-Event-ID has been evicted from the buffer: the frontend should re-fetch the history endpoint before continuing to consume this connection. */
2047
2112
  | {
2048
2113
  type: "resync_required";
@@ -2133,6 +2198,24 @@ interface ContextToolShare {
2133
2198
  name: string;
2134
2199
  tokens: number;
2135
2200
  }
2201
+ /**
2202
+ * One file's share of the context: its `read_file` / `edit_file` / `write_file` calls plus their
2203
+ * results, keyed by the file each call named.
2204
+ */
2205
+ interface ContextFileShare {
2206
+ /**
2207
+ * Workspace-relative when the file is inside the Session's Workspace; otherwise absolute, with
2208
+ * the home directory shortened to `~`. Spellings that resolve to the same file are one row.
2209
+ */
2210
+ path: string;
2211
+ tokens: number;
2212
+ /** How many calls of each file tool named the file in this context. */
2213
+ ops: {
2214
+ read: number;
2215
+ edit: number;
2216
+ write: number;
2217
+ };
2218
+ }
2136
2219
  /**
2137
2220
  * What the Session's current model context is made of — the part derived from its messages.
2138
2221
  *
@@ -2143,7 +2226,8 @@ interface ContextToolShare {
2143
2226
  *
2144
2227
  * The six parts partition the context and sum to `total`; `topTools` is a ranking inside
2145
2228
  * `toolRequests + toolResults` and can sum to less than those two (a result whose call was not
2146
- * recorded in the same Trace shard has no tool to be attributed to).
2229
+ * recorded in the same Trace shard has no tool to be attributed to). `topFiles` is the same
2230
+ * ranking narrowed to the three file tools and keyed by the file each call named.
2147
2231
  */
2148
2232
  interface SessionContextParts {
2149
2233
  systemPrompt: number;
@@ -2156,6 +2240,8 @@ interface SessionContextParts {
2156
2240
  total: number;
2157
2241
  /** Tools ranked by the context their traffic occupies, descending; at most five. */
2158
2242
  topTools: ContextToolShare[];
2243
+ /** Files ranked by the context their file-tool traffic occupies, descending; at most five. */
2244
+ topFiles: ContextFileShare[];
2159
2245
  /**
2160
2246
  * A completed compaction closed the context these figures describe, and the next one has not
2161
2247
  * been written yet: the composition is of what was compacted away, not of what the model now
@@ -2275,6 +2361,16 @@ interface TraceTaskStats {
2275
2361
  cacheWrite: number;
2276
2362
  output: number;
2277
2363
  };
2364
+ /**
2365
+ * This turn's cost in USD: each Request's three buckets at the Project's current rates for
2366
+ * the file's model, at the tier that Request's own timestamp fell in — the rule and the
2367
+ * price lookup the cost center applies to the usage row the same `token_usage` produced,
2368
+ * so this figure, the toolbar's and the cost center's agree on what a request cost. Present
2369
+ * on every turn of a priced file (a turn with no Request reads 0); absent when the model has
2370
+ * no pricing or the file's head names no provider, and then absent from the response's
2371
+ * total as well.
2372
+ */
2373
+ cost?: number;
2278
2374
  /**
2279
2375
  * Total LLM generation duration for this turn (the denominator for output TPS; human
2280
2376
  * approval wait already deducted). The numerator is simply `tokens.output`: since
@@ -2282,6 +2378,21 @@ interface TraceTaskStats {
2282
2378
  * output — there's no second figure to reconcile.
2283
2379
  */
2284
2380
  llmMs: number;
2381
+ /**
2382
+ * Wall-clock time this turn spent executing tools: the **union** of its tool spans'
2383
+ * execution intervals (`approvalTs ?? callTs` to `outputTs`), so tools running in parallel
2384
+ * are counted once instead of summed. Two exclusions, both deliberate: the human approval
2385
+ * wait (`callTs` to `approvalTs`) is not tool work, and the argument-generation segment is
2386
+ * the model streaming arguments, already counted in `llmMs`. A span with no `outputTs` —
2387
+ * still running when the file ended, or interrupted — contributes nothing rather than being
2388
+ * extrapolated to now.
2389
+ *
2390
+ * This and `llmMs` may **overlap**: a tool started in the background keeps running while the
2391
+ * model decodes. They are two measured components of the turn's duration, not a partition of
2392
+ * it, and they need not add up to the turn's span (approval waits and harness overhead belong
2393
+ * to neither). Never derive one by subtracting the other from the duration.
2394
+ */
2395
+ toolMs: number;
2285
2396
  }
2286
2397
  /** Duration span of a single tool call (complete tool_call message → paired tool_call_output). */
2287
2398
  interface ToolCallSpan {
@@ -2304,6 +2415,21 @@ interface WorkspaceFilesResponse {
2304
2415
  path: string;
2305
2416
  entries: WorkspaceFileEntry[];
2306
2417
  }
2418
+ /** Write one Workspace file whole (the Upload button, a drop, and the Files panel's editor). */
2419
+ interface FilesWriteRequest {
2420
+ /** The entire file, base64-encoded (≤14MB decoded). */
2421
+ dataBase64: string;
2422
+ /**
2423
+ * Write precondition: the version marker the caller read off this file's `ETag` on
2424
+ * `GET files/content`. The server compares it against the file's state immediately
2425
+ * before writing and answers 409 `file_changed` — having written nothing — when they
2426
+ * differ, which is what stops the editor's save from quietly dropping what the Agent
2427
+ * wrote during the turn. Omitted by a caller that read no version (an upload creates or
2428
+ * replaces unconditionally); that absence, not a sentinel value, is what says there was
2429
+ * no prior version to match.
2430
+ */
2431
+ ifVersion?: string;
2432
+ }
2307
2433
  /** Batch file existence check (message file cards only list files that actually exist). */
2308
2434
  interface FilesStatRequest {
2309
2435
  /** Paths relative to the Workspace root (≤100 items, each ≤512 characters). */
@@ -2375,6 +2501,23 @@ interface TraceAnalysisResponse {
2375
2501
  * frontend's events are paginated, so self-aggregation would undercount.
2376
2502
  */
2377
2503
  elapsedMs: number;
2504
+ /**
2505
+ * The file's model-API time: the sum of the turns' `llmMs` (human approval wait deducted,
2506
+ * compaction requests included, so the scope matches `elapsedMs`).
2507
+ */
2508
+ apiMs: number;
2509
+ /**
2510
+ * The file's tool wall time: the sum of the turns' `toolMs` (parallel tools counted once
2511
+ * within a turn). Summed per turn rather than unioned across the file, so the global figure
2512
+ * stays the sum of the per-turn figures, exactly as `elapsedMs` is. May overlap `apiMs` —
2513
+ * see `TraceTaskStats.toolMs`.
2514
+ */
2515
+ toolMs: number;
2516
+ /**
2517
+ * The file's cost in USD: the sum of the turns' `cost` (compaction turns included, the
2518
+ * scope every total here shares). Absent exactly when the turns carry no `cost`.
2519
+ */
2520
+ cost?: number;
2378
2521
  requests: RequestSpan[];
2379
2522
  /** Token / duration aggregated per Task (used directly by the Trace page's context ring and per-turn TPS). */
2380
2523
  tasks: TraceTaskStats[];
@@ -2577,16 +2720,8 @@ interface UsageErrorItem {
2577
2720
  * items.
2578
2721
  */
2579
2722
  interface UsageErrors {
2723
+ /** Filtered row count — also what a clear of the same filter takes (see {@link UsageErrorsClearResponse}). */
2580
2724
  total: number;
2581
- /**
2582
- * How many of {@link total} a clear would actually take (see {@link UsageErrorsClearResponse}).
2583
- *
2584
- * The same as `total` for an ordinary member, and smaller for an admin, whose reads include
2585
- * unattributed rows that no Project-scoped clear removes. The confirmation is the only place
2586
- * this matters, and it is the place it matters most: an irreversible delete has to name the
2587
- * number that will really go, not the number on screen.
2588
- */
2589
- clearable: number;
2590
2725
  /** Count of unexpected ones (500 / runtime exceptions) among them — the part the frontend highlights. */
2591
2726
  unexpected: number;
2592
2727
  /** The most frequent source · code (null when there are no errors). */
@@ -2598,8 +2733,9 @@ interface UsageErrors {
2598
2733
  * GET /api/projects/:projectId/usage/errors — one page of the error detail table, newest
2599
2734
  * first. The dashboard response above already carries the first page; this exists so
2600
2735
  * "show me earlier ones" does not have to refetch the whole aggregate. It takes the same
2601
- * date/agent filter as the dashboard, so a page never widens what the summary counted, plus
2602
- * an optional `kind` ({@link UsageErrorKind}) narrowing to one of the two categories — which
2736
+ * date/agent filter as the dashboard (`fromTs`/`toTs` narrow it to a trailing window, both
2737
+ * or neither), so a page never widens what the summary counted, plus an optional `kind`
2738
+ * ({@link UsageErrorKind}) narrowing to one of the two categories — which
2603
2739
  * is how the cost-center badge asks "are there unexpected errors, and how new is the newest"
2604
2740
  * with `limit=1` instead of pulling the whole dashboard aggregate.
2605
2741
  */
@@ -2610,11 +2746,15 @@ interface UsageErrorsPage {
2610
2746
  }
2611
2747
  /**
2612
2748
  * DELETE /api/projects/:projectId/usage/errors — empties the error table for the filter the
2613
- * panel is showing (its date range and Agent), Project owner only.
2749
+ * panel is showing (its date range, the trailing window when one is on, and Agent), Project
2750
+ * owner only.
2614
2751
  *
2615
2752
  * Scoped to the filter rather than the Project's whole history, so a clear takes exactly the
2616
- * rows on screen. Errors with no Project attribution are never included, whoever asks: they
2617
- * belong to no Project and are surfaced in every Project's admin view.
2753
+ * rows on screen — for an admin, the unattributed rows an admin's panel shows included; a
2754
+ * member's panel never shows them and a member's clear never takes them.
2755
+ *
2756
+ * `from` and `to` are both required (400 otherwise), where the reads treat them as optional:
2757
+ * an absent bound is unbounded on that side, which is the whole history rather than a filter.
2618
2758
  */
2619
2759
  interface UsageErrorsClearResponse {
2620
2760
  /** How many rows were deleted, so the caller can say what went instead of guessing. */
@@ -2795,31 +2935,99 @@ interface SkillMetadataItem {
2795
2935
  /** Short description for frontend display (frontmatter short_description, optional; falls back to description if missing). */
2796
2936
  shortDescription?: string;
2797
2937
  shortDescriptionZh?: string;
2798
- /** Custom icon (raw icon.svg text from the skill directory, optional; frontend falls back to a default book icon if missing). */
2938
+ /**
2939
+ * Raw icon.svg text from the installed skill directory: the plugin's icon for a library
2940
+ * install (written beside SKILL.md at install time), a custom one for a user-authored skill.
2941
+ * Only installed lists carry it — the library listing's skills share their plugin's icon,
2942
+ * which the plugin item carries once. Absent, the frontend draws the book glyph.
2943
+ */
2799
2944
  icon?: string;
2800
- /** Version number (natural number, frontmatter version; falls back to 1 if invalid). */
2801
- version: number;
2802
- /** Update timestamp (frontmatter updated, ISO 8601 UTC by convention; defaults to an empty string). */
2803
- updated: string;
2945
+ /** Version (`YYYY.MM.DD.N`, frontmatter version; a copy installed before that spelling still carries `YYYY-MM-DD.N`); an empty string when the frontmatter carries none or a malformed one. */
2946
+ version: string;
2804
2947
  }
2805
- interface SkillGroupItem {
2948
+ /** One installed hook package (`agent_state/hooks/<name>/`): its manifest, without the scripts. */
2949
+ interface HookItem {
2950
+ /** Hook package name — the plugin that shipped it (the identity uninstall addresses it by). */
2951
+ name: string;
2952
+ description: string;
2953
+ descriptionZh?: string;
2954
+ /** Version (`YYYY.MM.DD.N`; a copy installed before that spelling still carries `YYYY-MM-DD.N`); an empty string when the manifest carries none. */
2955
+ version: string;
2956
+ /** The hook points the package answers at, e.g. `["stop"]`. */
2957
+ events: string[];
2958
+ /** The plugin's raw icon.svg, written beside the manifest at install time; absent when the plugin ships none (the frontend draws the hook glyph). */
2959
+ icon?: string;
2960
+ }
2961
+ /** One library plugin as the listing describes it: the manifest fields plus what it ships (skill bodies and scripts are never sent). */
2962
+ interface PluginItem {
2963
+ name: string;
2964
+ description: string;
2965
+ descriptionZh?: string;
2966
+ shortDescription?: string;
2967
+ shortDescriptionZh?: string;
2968
+ /** `YYYY.MM.DD.N`. */
2969
+ version: string;
2970
+ /** The plugin's skills (metadata only). */
2971
+ skills: SkillMetadataItem[];
2972
+ /** The hook points the plugin's hook package answers at (`[]` without one). */
2973
+ hooks: string[];
2974
+ /** The plugin's raw icon.svg (beside plugin.json — every built-in plugin ships one), the icon of everything it ships; the frontend draws the puzzle-piece plugin glyph without it. */
2975
+ icon?: string;
2976
+ }
2977
+ interface PluginGroupItem {
2806
2978
  id: string;
2807
2979
  title: string;
2808
- /** Chinese group title (optional; the UI displays it per language). */
2980
+ /** Chinese category title (optional; the UI displays it per language). */
2809
2981
  titleZh?: string;
2810
- skills: SkillMetadataItem[];
2982
+ plugins: PluginItem[];
2983
+ }
2984
+ /** GET /api/plugins: the library by category (any logged-in user). */
2985
+ interface PluginLibraryResponse {
2986
+ groups: PluginGroupItem[];
2811
2987
  }
2812
- /** GET /api/skills: library groups and metadata (excludes body content). */
2813
- interface SkillLibraryResponse {
2814
- groups: SkillGroupItem[];
2988
+ /**
2989
+ * GET /api/plugins/:plugin/files: everything a library plugin ships, for the detail view's file
2990
+ * browser — each skill's installable SKILL.md and auxiliary files under `skills/<name>/`, the
2991
+ * hook package's scripts under `hooks/` — keyed by path relative to the plugin directory. The
2992
+ * manifest and the icon are not among them: the listing already carries both.
2993
+ */
2994
+ interface PluginFilesResponse {
2995
+ files: Record<string, string>;
2815
2996
  }
2816
- /** GET|POST /api/projects/:p/agents/:a/skills: Skills installed on this Agent. */
2997
+ /**
2998
+ * POST /api/projects/:p/agents/:a/plugins: install library plugins by name — each one's skills
2999
+ * and hook package; already-installed ones are overwritten with library content (i.e. updated).
3000
+ * Every name must be in the library (404 `unknown_plugin`, nothing written). 201 returns the
3001
+ * refreshed installed lists.
3002
+ */
3003
+ interface PluginInstallRequest {
3004
+ names: string[];
3005
+ }
3006
+ interface AgentPluginsInstallResponse {
3007
+ skills: SkillMetadataItem[];
3008
+ hooks: HookItem[];
3009
+ }
3010
+ /** GET /api/projects/:p/agents/:a/skills: Skills installed on this Agent. */
2817
3011
  interface AgentSkillsResponse {
2818
3012
  skills: SkillMetadataItem[];
2819
3013
  }
2820
- /** POST install request: all names must exist in the library; already-installed ones are overwritten with library content (i.e. updated). */
2821
- interface SkillInstallRequest {
2822
- names: string[];
3014
+ /** GET /api/projects/:p/agents/:a/hooks: hook packages installed on this Agent; DELETE …/hooks/:name uninstalls one (204). */
3015
+ interface AgentHooksResponse {
3016
+ hooks: HookItem[];
3017
+ }
3018
+ /**
3019
+ * POST /api/projects/:p/agents/:a/hooks/archive: install one hook package from an uploaded zip.
3020
+ * Layout: hooks.json and its scripts at the zip root, or exactly one top-level directory
3021
+ * containing them (the directory name is then the package name). 201 returns the refreshed
3022
+ * installed list (AgentHooksResponse); an already-installed name without `overwrite` is 409
3023
+ * `hook_exists`. GET …/hooks/:name/archive is the matching export: the installed directory as
3024
+ * a zip attachment, which round-trips through this POST.
3025
+ */
3026
+ interface HookArchiveInstallRequest {
3027
+ /** Base64-encoded zip archive (decoded size capped at 14MB, like the skill archive). */
3028
+ dataBase64: string;
3029
+ /** Replace an installed package of the same name instead of answering 409. */
3030
+ overwrite?: boolean;
2823
3031
  }
2824
3032
  /**
2825
3033
  * POST /api/projects/:p/agents/:a/skills/archive: install one Skill from an uploaded zip.
@@ -2870,7 +3078,9 @@ interface UpdateCheckResponse {
2870
3078
  * utilityProcess message channel and served at GET /api/desktop/update. `state` is the
2871
3079
  * discriminator; the optional fields belong to the states named on them.
2872
3080
  *
2873
- * A `downloaded` build stays the reported state until it is installed: a later periodic
3081
+ * The shell never downloads on its own: a check ends in `available`, and the download
3082
+ * starts only on the page's (or the native dialog's) say-so — the `download` command. A
3083
+ * `downloaded` build stays the reported state until it is installed: a later periodic
2874
3084
  * check (or its failure) must not hide the actionable "restart to install" step.
2875
3085
  */
2876
3086
  interface DesktopUpdateStatus {
@@ -2883,8 +3093,8 @@ interface DesktopUpdateStatus {
2883
3093
  * carry that signal (a check that ends where it started is byte-identical).
2884
3094
  */
2885
3095
  seq?: number;
2886
- state: "idle" | "checking" | "up-to-date" | "downloading" | "downloaded" | "error" | "unsupported";
2887
- /** Newer release being fetched / ready to install (`downloading`, `downloaded`). */
3096
+ state: "idle" | "checking" | "up-to-date" | "available" | "downloading" | "downloaded" | "error" | "unsupported";
3097
+ /** The newer release: offered (`available`), being fetched (`downloading`) or ready to install (`downloaded`). */
2888
3098
  version?: string;
2889
3099
  /** Download progress 0–100 (`downloading`). */
2890
3100
  percent?: number;
@@ -2905,15 +3115,19 @@ interface DesktopUpdaterStatusMessage {
2905
3115
  type: "desktop-updater-status";
2906
3116
  status: DesktopUpdateStatus;
2907
3117
  }
2908
- /** Server → shell command over the utilityProcess message channel (relayed from POST /api/desktop/update/check|install). */
3118
+ /**
3119
+ * Server → shell command over the utilityProcess message channel (relayed from
3120
+ * POST /api/desktop/update/check|download|install): look for a release, fetch the one
3121
+ * offered, or restart into the one downloaded.
3122
+ */
2909
3123
  interface DesktopUpdaterCommandMessage {
2910
3124
  type: "desktop-updater-command";
2911
- action: "check" | "install";
3125
+ action: "check" | "download" | "install";
2912
3126
  }
2913
3127
  /**
2914
- * POST /api/version/update (admin only): runs the CLI self-update (`penguin update --yes`)
2915
- * on the server host. `unsupported` covers both a server not launched via the CLI and the
2916
- * CLI's own refusals (source checkout, unrecognized install layout, Windows).
3128
+ * The outcome of one self-update run (`penguin update --yes` on the server host), carried
3129
+ * by {@link UpdateJobStatus.result}. `unsupported` covers both a server not launched via
3130
+ * the CLI and the CLI's own refusals (source checkout, unrecognized install layout, Windows).
2917
3131
  */
2918
3132
  interface UpdateRunResponse {
2919
3133
  status: "updated" | "failed" | "unsupported";
@@ -2924,6 +3138,44 @@ interface UpdateRunResponse {
2924
3138
  /** True when the install changed (or was already current): restart the service to run the new version. */
2925
3139
  needsRestart: boolean;
2926
3140
  }
3141
+ /**
3142
+ * Where a running self-update is: resolving the release and fetching the installer,
3143
+ * downloading the bundle (the one phase with a percentage), or verifying and installing it.
3144
+ */
3145
+ type UpdateJobPhase = "resolving" | "downloading" | "installing";
3146
+ /**
3147
+ * GET / POST /api/version/update (admin only): the self-update job. POST starts a run when
3148
+ * none is in flight — a finished run may be started again, which is how a failed one is
3149
+ * retried — and answers with the status exactly as GET does; the page polls GET while
3150
+ * `state` is `running`. One job per process: two admins clicking at once share the one run,
3151
+ * and the finished status stays readable until the next start.
3152
+ */
3153
+ interface UpdateJobStatus {
3154
+ state: "idle" | "running" | "done";
3155
+ /** The release the run targets — the update check's newest version when the run started; null when none was known. */
3156
+ targetVersion: string | null;
3157
+ /** Running only. */
3158
+ phase?: UpdateJobPhase;
3159
+ /** Running, `downloading` only: 0–100 read off the installer's progress bar; null until its first tick. */
3160
+ percent?: number | null;
3161
+ /** Tail of the update command's combined stdout+stderr so far (capped; empty when nothing ran). */
3162
+ output: string;
3163
+ /** Done only. */
3164
+ result?: UpdateRunResponse;
3165
+ startedAt?: string;
3166
+ finishedAt?: string;
3167
+ }
3168
+ /**
3169
+ * POST /api/version/restart (admin only): asks the process to exit with the supervisor's
3170
+ * restart code after a graceful shutdown, so `penguin server|web` relaunches it on the
3171
+ * installed release. `restarting: false` when nothing supervises this process — it was
3172
+ * started some other way than through the CLI, or it is a dev run — and the page shows the
3173
+ * manual restart hint instead.
3174
+ */
3175
+ interface RestartResponse {
3176
+ restarting: boolean;
3177
+ reason?: "no_supervisor";
3178
+ }
2927
3179
  /** One `Host` entry of the server's `~/.ssh/config`, as the Machines page lists it. */
2928
3180
  interface MachineInfo {
2929
3181
  /** `ssh:<alias>` — the id the install route is asked for. */
@@ -2935,9 +3187,9 @@ interface MachineInfo {
2935
3187
  */
2936
3188
  alias: string;
2937
3189
  /**
2938
- * The last install THIS server carried out there, remembered on disk so it survives a
2939
- * restart, a hot push, and installing on some other machine. Null when this server has
2940
- * never installed there.
3190
+ * The last install THIS server carried out there FOR THIS PROJECT, remembered in web.db so
3191
+ * it survives a restart, a hot push, and installing on some other machine. Null when this
3192
+ * Project has never installed there — a host another Project did is `elsewhere` below.
2941
3193
  *
2942
3194
  * A record of what was done, not a survey of the far side: a machine wiped by hand still
2943
3195
  * reads as installed until the next install probes it and corrects the record. Asking the
@@ -2948,25 +3200,112 @@ interface MachineInfo {
2948
3200
  version: string;
2949
3201
  at: string;
2950
3202
  } | null;
3203
+ /**
3204
+ * Installed by this server, but not this Project's machine — another Project's, or nobody's
3205
+ * since it was released — and so not a host nobody has touched either. Absent in every
3206
+ * other case, including when it IS this Project's (where `installed` carries the same record).
3207
+ *
3208
+ * Reported rather than folded into `installed` because the two lead to different actions:
3209
+ * one is a machine to use, the other is a machine to adopt, which costs a row and no ssh.
3210
+ * Reported rather than hidden because a row that silently looked uninstalled would send
3211
+ * someone to spend a 30 MB transfer re-doing what is already done.
3212
+ */
3213
+ elsewhere?: {
3214
+ version: string;
3215
+ at: string;
3216
+ };
3217
+ /**
3218
+ * The machine's OWN id — 16 base64url characters minted by the server that runs there,
3219
+ * stable across renames, re-aliasing and reinstalls. Null until a server has started on
3220
+ * that machine, since nothing has minted one yet.
3221
+ *
3222
+ * This is what anything stored should point at; `id` above is an ADDRESS (`ssh:<alias>`),
3223
+ * and `alias` is what people read. Two aliases for one host share a `machineId`, and an
3224
+ * alias repointed at a different host answers a different one — an id never changes for a
3225
+ * machine, so a change of id is a change of machine.
3226
+ */
3227
+ machineId: string | null;
3228
+ /** The host this server itself runs on. Always present, always installed, never a target. */
3229
+ local: boolean;
3230
+ /**
3231
+ * The connection this server holds to it — the one ssh session everything to the machine
3232
+ * rides (machines/transport/ssh-session.ts): a fact about a process on THIS side, which
3233
+ * outlives the far server. Present means `/server/<id>/api/…` has somewhere to go; whether
3234
+ * a server ANSWERS over there is `status`'s word, from the last probe — and the two must not
3235
+ * be read for each other: taking the connection for the machine's liveness is the mistake
3236
+ * behind the connect loop (#561). Always null for `local`, which needs no connection.
3237
+ */
3238
+ connection: {
3239
+ pid: number;
3240
+ } | null;
3241
+ /**
3242
+ * The machine's API as last seen by this server's proxy — stamped by traffic passing
3243
+ * through, never by a probe of its own. `answeredAt` when the last forwarded request got
3244
+ * an HTTP answer (any status: a server that refuses is still answering); `failedAt` and
3245
+ * the transport's own words when the connection had nowhere to deliver. Null until a first
3246
+ * request flows, and only as fresh as the last one — no traffic, no measurement, which is
3247
+ * honest: nothing burns ssh for a page nobody is looking at. Always null for `local`;
3248
+ * this server answering the request that fetched this list is that measurement.
3249
+ */
3250
+ api: {
3251
+ answeredAt: string;
3252
+ } | {
3253
+ failedAt: string;
3254
+ detail: string;
3255
+ } | null;
3256
+ /**
3257
+ * What the last probe found over there, or null when none has been taken. Never filled in
3258
+ * at list time: a probe costs an ssh round trip per machine, so the list reports the last
3259
+ * answer and the page asks for a fresh one when it wants one — on a widening schedule,
3260
+ * since each probe is an ssh round trip while the list is only the config's text.
3261
+ */
3262
+ status: MachineServerStatus | null;
2951
3263
  }
2952
3264
  /**
2953
- * The running or last install, polled by GET /api/machines while one runs. `log` carries the
2954
- * far side's own words where there are any: ssh's diagnostics and the remote installer's
2955
- * output say more about a refused key or an unusable Node than a paraphrase would.
3265
+ * One machine's server state. There is deliberately no separate "ssh" status: ssh is the
3266
+ * transport, so a machine it cannot reach reads as `unreachable` with OpenSSH's own
3267
+ * diagnostic in `detail` rather than as two statuses a reader has to combine.
2956
3268
  */
2957
- interface MachineInstallJob {
3269
+ interface MachineServerStatus {
3270
+ state: "running" | "stopped" | "unreachable";
3271
+ /** ISO timestamp of the probe this answer came from. */
3272
+ checkedAt: string;
3273
+ /** The port it is serving on (`running`). */
3274
+ port?: number;
3275
+ /** Why the machine could not be reached (`unreachable`) — ssh's own words. */
3276
+ detail?: string;
3277
+ }
3278
+ /**
3279
+ * The running or last job on a machine — an install, or a connect — polled by GET
3280
+ * /api/machines while one runs. One at a time. `log` carries the far side's own words where
3281
+ * there are any: ssh's diagnostics and the remote installer's output say more about a
3282
+ * refused key or an unusable Node than a paraphrase would.
3283
+ */
3284
+ interface MachineJob {
3285
+ kind: "install" | "connect" | "restart";
2958
3286
  machineId: string;
2959
3287
  alias: string;
2960
3288
  running: boolean;
2961
3289
  log: string[];
2962
3290
  result: null | {
2963
3291
  ok: true;
2964
- kind: "installed" | "already-installed";
3292
+ installed: "installed" | "already-installed";
2965
3293
  version: string | null;
3294
+ } | {
3295
+ ok: true;
3296
+ connected: true;
2966
3297
  } | {
2967
3298
  ok: false;
2968
3299
  step: string;
2969
3300
  message: string;
3301
+ /**
3302
+ * The failure has a next step this side can take, and it needs saying yes to:
3303
+ * installing the PROGRAM over there and restarting it. Set when a hot update could
3304
+ * not be handed over — the machine's store holds no CLI this server can talk to, and
3305
+ * installing is what replicates one. Offered rather than done, because it restarts a
3306
+ * server this Project does not own alone.
3307
+ */
3308
+ canReplaceProgram?: true;
2970
3309
  };
2971
3310
  }
2972
3311
  /** GET /api/machines, and the 202 body of POST /api/machines/:machineId/install. */
@@ -2978,7 +3317,7 @@ interface MachinesResponse {
2978
3317
  * checkout, which stands on no release the remote could download.
2979
3318
  */
2980
3319
  imageVersion: string | null;
2981
- job: MachineInstallJob | null;
3320
+ job: MachineJob | null;
2982
3321
  }
2983
3322
 
2984
- export type { AdminPasswordResetRequest, AdminUserCreateRequest, AdminUserCreateResponse, AdminUsersResponse, AgentCompactionConfigDto, AgentConfigDto, AgentConfigResponse, AgentConfigUpdateRequest, AgentCreateRequest, AgentCreateResponse, AgentImportRequest, AgentImportResponse, AgentKernelUpdateResponse, AgentMemoryConfigDto, AgentModelConfigDto, AgentSchedulesConfigDto, AgentSkillsConfigDto, AgentSkillsResponse, AgentSummary, AgentTraceDateGroup, AgentTraceFileRef, AgentTraceSessionEntry, AgentTraceSessionFile, AgentTraceSessionGroup, AgentTracesResponse, AgentVaultConfigDto, AgentsResponse, ApprovalDecisionRequest, ApprovalMode, AuthLoginRequest, AuthResponse, BenchmarkCaseScore, BenchmarkCaseSummary, BenchmarkCasesResponse, BenchmarkEvaluation, BenchmarkRunScore, BenchmarkSummary, BenchmarksResponse, CaseMaterial, ChatDefaultsDto, CommandPolicyDto, CommandPolicyRuleDto, ContextToolShare, CredentialInfo, DefaultModelResponse, DefaultModelUpdateRequest, DesktopUpdateStatus, DesktopUpdateStatusResponse, DesktopUpdaterCommandMessage, DesktopUpdaterStatusMessage, DirEntryInfo, DirListResponse, DirectorySkillItem, DirectorySkillsResponse, DraftShortcut, EndpointModelListRequest, EndpointModelListResponse, ErrorBody, FeishuBindingInfo, FeishuBindingPutRequest, FeishuBindingResponse, FeishuTestRequest, FeishuTestResponse, FilesStatRequest, FilesStatResponse, GoalResponse, GoalServerEvent, GoalStateView, HistoryMessage, InstallResponse, MachineInfo, MachineInstallJob, MachinesResponse, McpServerTestResponse, MeResponse, MemberAddRequest, MemberAddResponse, MemberInfo, MembersResponse, MemoryFileInfo, MemoryFileResponse, MemoryFilesResponse, MemoryImportMode, MemoryImportRequest, MemoryImportResponse, MemoryOverviewResponse, MemoryScopeExport, MemoryScopeInfo, MemoryTransferFile, MessagesLiveTail, MessagesPageInfo, MessagesResponse, MessagingBindingCommon, MessagingBindingInfo, MessagingBindingStateRequest, MessagingBindingsResponse, MessagingChannel, MessagingChannelState, MessagingDeliveryError, MessagingDeliveryPatch, MessagingRuntimeState, MessagingRuntimeStatus, MessagingTestMessageResponse, ModelInfo, ModelOAuthCodeRequest, ModelOAuthCodeResponse, ModelOAuthErrorCode, ModelOAuthMode, ModelOAuthStartRequest, ModelOAuthStartResponse, ModelOAuthStatusResponse, ModelPricingDto, ModelProtocolDetectRequest, ModelProtocolDetectResponse, ModelProtocolProbeDto, ModelRefDto, ModelTestRequest, ModelTestResponse, ModelUpdateEntry, ModelVisionDetectRequest, ModelVisionDetectResponse, ModelVisionOutcome, ModelsResponse, ModelsUpdateRequest, PasswordChangeRequest, PendingFollowUpInfo, PendingSteeringInfo, PrefsResponse, ProjectCreateRequest, ProjectCreateResponse, ProjectRole, ProjectSummary, ProjectUpdateRequest, ProjectUpdateResponse, ProjectsResponse, ProtocolProbeOutcome, QQBindingInfo, QQBindingPutRequest, QQBindingResponse, QQScanPollResponse, QQScanStartResponse, QQTestRequest, QQTestResponse, RecalledMessageResponse, RequestSpan, RetryNowResponse, ScheduleItem, ScheduleServerEvent, ScheduleStatus, ScheduleUpsertRequest, SchedulesResponse, ServerEvent, ServerSettings, ServerSettingsResponse, ServerSettingsUpdateRequest, SessionCategory, SessionCategoryCounts, SessionContextParts, SessionContextResponse, SessionCreateRequest, SessionCreateResponse, SessionForkRequest, SessionForkResponse, SessionInfo, SessionPatchRequest, SessionProcessInfo, SessionProcessesResponse, SessionResponse, SessionSource, SessionStatus, SessionTracesResponse, SessionsResponse, SkillArchiveInstallRequest, SkillGroupItem, SkillInstallRequest, SkillLibraryResponse, SkillMetadataItem, SkillUpdateRef, SteerRequest, SubagentMessageResponse, SubagentRuntimeInfo, TaskCreateRequest, TaskCreateResponse, TaskInputPart, TelegramBindingInfo, TelegramBindingPutRequest, TelegramBindingResponse, TelegramTestRequest, TelegramTestResponse, ToolCallSpan, TraceAnalysisResponse, TraceEventsResponse, TraceFileInfo, TraceImportRequest, TraceImportResponse, TraceModelSegment, TraceOtherSpan, TracePosition, TraceTaskStats, TraceToolSpan, UiPrefs, UpdateCheckResponse, UpdateRunResponse, UploadLimits, UsageAgentSeries, UsageBucket, UsageEntitySeriesCounts, UsageErrorCount, UsageErrorItem, UsageErrorKind, UsageErrors, UsageErrorsClearResponse, UsageErrorsPage, UsageGranularity, UsageGroupBy, UsageGroupRow, UsageModelSeries, UsageModelTotal, UsageModelTotals, UsageResponse, UsageSeriesPoint, UsageTrendPointInTrace, UserInfo, VaultEntryInfo, VaultEntryUpdate, VaultResponse, VaultUpdateRequest, VersionResponse, WeChatBindingInfo, WeChatBindingPutRequest, WeChatBindingResponse, WeChatScanPollResponse, WeChatScanStartResponse, WeChatScanStatus, WeChatScanVerifyRequest, WeChatTestResponse, WorkspaceFileEntry, WorkspaceFilesResponse };
3323
+ export type { AdminPasswordResetRequest, AdminUserCreateRequest, AdminUserCreateResponse, AdminUsersResponse, AgentCompactionConfigDto, AgentConfigDto, AgentConfigResponse, AgentConfigUpdateRequest, AgentCreateRequest, AgentCreateResponse, AgentHooksConfigDto, AgentHooksResponse, AgentImportRequest, AgentImportResponse, AgentKernelUpdateResponse, AgentMemoryConfigDto, AgentModelConfigDto, AgentPluginsInstallResponse, AgentSchedulesConfigDto, AgentSkillsConfigDto, AgentSkillsResponse, AgentSummary, AgentTraceDateGroup, AgentTraceFileRef, AgentTraceSessionEntry, AgentTraceSessionFile, AgentTraceSessionGroup, AgentTracesResponse, AgentVaultConfigDto, AgentsResponse, ApprovalDecisionRequest, ApprovalMode, AuthLoginRequest, AuthResponse, BenchmarkCaseScore, BenchmarkCaseSummary, BenchmarkCasesResponse, BenchmarkEvaluation, BenchmarkRunScore, BenchmarkSummary, BenchmarksResponse, CaseMaterial, ChatDefaultsDto, CommandPolicyDto, CommandPolicyRuleDto, ContextFileShare, ContextToolShare, CredentialInfo, DefaultModelResponse, DefaultModelUpdateRequest, DesktopUpdateStatus, DesktopUpdateStatusResponse, DesktopUpdaterCommandMessage, DesktopUpdaterStatusMessage, DirEntryInfo, DirListResponse, DirectorySkillItem, DirectorySkillsResponse, DraftShortcut, EndpointModelListRequest, EndpointModelListResponse, ErrorBody, FeishuBindingInfo, FeishuBindingPutRequest, FeishuBindingResponse, FeishuTestRequest, FeishuTestResponse, FilesStatRequest, FilesStatResponse, FilesWriteRequest, GoalResponse, GoalServerEvent, GoalStateView, HistoryMessage, HookArchiveInstallRequest, HookItem, InstallResponse, MachineInfo, MachineJob, MachineServerStatus, MachinesResponse, McpServerTestResponse, MeResponse, MemberAddRequest, MemberAddResponse, MemberInfo, MembersResponse, MemoryFileInfo, MemoryFileResponse, MemoryFilesResponse, MemoryImportMode, MemoryImportRequest, MemoryImportResponse, MemoryOverviewResponse, MemoryScopeExport, MemoryScopeInfo, MemoryTransferFile, MessagesLiveTail, MessagesPageInfo, MessagesResponse, MessagingBindingCommon, MessagingBindingInfo, MessagingBindingStateRequest, MessagingBindingsResponse, MessagingChannel, MessagingChannelState, MessagingDeliveryError, MessagingDeliveryPatch, MessagingRuntimeState, MessagingRuntimeStatus, MessagingTestMessageResponse, ModelInfo, ModelOAuthCodeRequest, ModelOAuthCodeResponse, ModelOAuthErrorCode, ModelOAuthMode, ModelOAuthStartRequest, ModelOAuthStartResponse, ModelOAuthStatusResponse, ModelPricingDto, ModelProtocolDetectRequest, ModelProtocolDetectResponse, ModelProtocolProbeDto, ModelRefDto, ModelTestRequest, ModelTestResponse, ModelUpdateEntry, ModelVisionDetectRequest, ModelVisionDetectResponse, ModelVisionOutcome, ModelsResponse, ModelsUpdateRequest, PasswordChangeRequest, PendingFollowUpInfo, PendingSteeringInfo, PluginFilesResponse, PluginGroupItem, PluginInstallRequest, PluginItem, PluginLibraryResponse, PluginUpdateRef, PrefsResponse, ProjectCreateRequest, ProjectCreateResponse, ProjectRole, ProjectSummary, ProjectUpdateRequest, ProjectUpdateResponse, ProjectsResponse, ProtocolProbeOutcome, QQBindingInfo, QQBindingPutRequest, QQBindingResponse, QQScanPollResponse, QQScanStartResponse, QQTestRequest, QQTestResponse, RecalledMessageResponse, RequestSpan, RestartResponse, RetryNowResponse, ScheduleItem, ScheduleServerEvent, ScheduleStatus, ScheduleUpsertRequest, SchedulesResponse, ServerEvent, ServerSettings, ServerSettingsResponse, ServerSettingsUpdateRequest, SessionBackgroundTasks, SessionCategory, SessionCategoryCounts, SessionContextParts, SessionContextResponse, SessionCreateRequest, SessionCreateResponse, SessionForkRequest, SessionForkResponse, SessionInfo, SessionPatchRequest, SessionProcessInfo, SessionProcessesResponse, SessionResponse, SessionSource, SessionStatus, SessionTracesResponse, SessionsResponse, SkillArchiveInstallRequest, SkillMetadataItem, SteerRequest, SubagentMessageResponse, SubagentRuntimeInfo, TaskCreateRequest, TaskCreateResponse, TaskInputPart, TelegramBindingInfo, TelegramBindingPutRequest, TelegramBindingResponse, TelegramTestRequest, TelegramTestResponse, ToolCallSpan, TraceAnalysisResponse, TraceEventsResponse, TraceFileInfo, TraceImportRequest, TraceImportResponse, TraceModelSegment, TraceOtherSpan, TracePosition, TraceTaskStats, TraceToolSpan, UiPrefs, UpdateCheckResponse, UpdateJobPhase, UpdateJobStatus, UpdateRunResponse, UploadLimits, UsageAgentSeries, UsageBucket, UsageEntitySeriesCounts, UsageErrorCount, UsageErrorItem, UsageErrorKind, UsageErrors, UsageErrorsClearResponse, UsageErrorsPage, UsageGranularity, UsageGroupBy, UsageGroupRow, UsageModelSeries, UsageModelTotal, UsageModelTotals, UsageResponse, UsageSeriesPoint, UsageTrendPointInTrace, UserInfo, VaultEntryInfo, VaultEntryUpdate, VaultResponse, VaultUpdateRequest, VersionResponse, WeChatBindingInfo, WeChatBindingPutRequest, WeChatBindingResponse, WeChatScanPollResponse, WeChatScanStartResponse, WeChatScanStatus, WeChatScanVerifyRequest, WeChatTestResponse, WorkspaceFileEntry, WorkspaceFilesResponse };