dsh-context 0.74.0 → 0.75.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -4,7 +4,6 @@ import "@deepseek-ai/dsh-session";
4
4
  import z$1 from "@deepseek-ai/schemastery";
5
5
  import { Context } from "@deepseek-ai/cordis";
6
6
  //#region src/host/activity.d.ts
7
- /** A pending tool run's start instant and the step-initiation day it prices. */
8
7
  interface ToolStart {
9
8
  start: number;
10
9
  day: string;
@@ -14,20 +13,16 @@ interface ActivityState {
14
13
  /** The route in force (the last `request/header`'s config wins) — prices each settlement. */
15
14
  model?: string;
16
15
  provider?: string;
17
- /** The open step's start instant (armed by `step/start`, cleared by `step/end`). */
18
16
  stepStart?: number;
19
17
  /** The last turn whose first settlement was booked, so a multi-step turn counts once. */
20
18
  lastTurn?: number;
21
- /** Pending tool runs (call id → start + initiation day), consumed by the pairing `tool/result`. */
22
19
  toolStarts?: Record<string, ToolStart | undefined>;
23
- /** Pending `skill`-tool call ids (armed by `tool/call`, consumed by the pairing `tool/result`):
24
- * the wrapper match alone is not trusted, or a `read` of source text quoting
25
- * `<skill_content name="…">` would book a load. Bounded at {@link MAX_PENDING_SKILL_CALLS}. */
20
+ /** Pending `skill`-tool call ids: the wrapper match alone is not trusted, or a `read` quoting it would book a load. */
26
21
  skillCalls?: string[];
27
22
  }
28
23
  //#endregion
29
24
  //#region src/host/headers.d.ts
30
- /** One stored tool: v1 rows carried the producer description and raw schema; later folds append metadata-only. */
25
+ /** v1 rows carried the producer description and raw schema; later folds append metadata-only. */
31
26
  interface StoredHeaderTool {
32
27
  name: string;
33
28
  tokens: number;
@@ -35,7 +30,7 @@ interface StoredHeaderTool {
35
30
  plugin?: string;
36
31
  schema?: unknown;
37
32
  }
38
- /** One stored epoch: v1 rows carried `system`; later folds carry `systemTokens`. */
33
+ /** v1 rows carried `system`; later folds carry `systemTokens`. */
39
34
  interface StoredHeaderRecord {
40
35
  seq: number;
41
36
  time: number;
@@ -48,115 +43,111 @@ interface HeadersState {
48
43
  }
49
44
  //#endregion
50
45
  //#region src/host/foldState.d.ts
46
+ /** The state's command record: the wire record plus the callId the fold pairs result/job events on. Never served —
47
+ * `foldWire` strips it (optional precisely so the strip is a plain `delete`). */
48
+ interface CommandStateRecord extends CommandRecord {
49
+ call?: string;
50
+ }
51
51
  interface TimelineState {
52
52
  /** Model-visible surface, newest last. */
53
53
  surface: SurfaceNode[];
54
54
  sums: Record<Category, number>;
55
55
  systemTokens: number;
56
- /** The live system-prompt nodes, oldest first. `systemTokens` is the LAST entry with tokens > 0 (the harness's
57
- * own "last nonempty surviving system" rule), so an empty dormant node keeps its position without clearing the
58
- * prompt. Bounded by SYSTEM_NODES_MAX. Absent on rows folded before this field existed; the client then falls
59
- * back to the header epoch's own envelope figure. */
56
+ /** The live system-prompt nodes, oldest first; `systemTokens` is the LAST nonempty one (the harness rule), so an empty dormant node
57
+ * keeps its position. Absent rows fall back to the header epoch's envelope figure. */
60
58
  systems?: SystemPromptNode[];
61
59
  toolsTokens: number;
62
- /** The projection cache requires plain JSON: a property whose value is `undefined` makes the whole checkpoint
63
- * unserializable, failing EVERY cache write for the session — including the `title` row that powers the session
64
- * list after a restart. Optional fields therefore stay absent until a value is known, never `undefined`-valued. */
60
+ /** The projection cache requires plain JSON: an `undefined`-valued property fails EVERY cache write for the session, so optional fields
61
+ * stay absent until a value is known. */
65
62
  model?: string;
66
63
  provider?: string;
64
+ /** Last-wins: a header without an effort clears it. */
65
+ reasoningEffort?: string;
67
66
  lastModel?: string;
68
67
  contextWindow?: number;
69
- /** The newest `request/header` envelope's routed output cap (dsh materializes the adapter default
70
- * into it). Last-wins: a header omitting the cap clears it. */
68
+ /** The newest `request/header` envelope's routed output cap (dsh materializes the adapter default into it). Last-wins: a header
69
+ * omitting the cap clears it. */
71
70
  maxOutputTokens?: number;
72
71
  requests: RequestRecord[];
73
- /** The number of turn runs in `requests` (a run = consecutive records sharing one `turn`). Maintained
74
- * incrementally at the single append site and recomputed when a trim replaces the array, so the retention
75
- * trim's cap check stays O(1) per event. Absent on rows folded before the field existed. */
72
+ /** Turn runs in `requests` (consecutive records sharing one `turn`), maintained at the single append site and recomputed on trim, so
73
+ * the cap check stays O(1); absent on older rows. */
76
74
  turnRuns?: number;
77
75
  events: ContextEventRecord[];
78
- /** Recently removed surface nodes (stamped COPIES carrying `gone`), in removal order. Bounded two ways in
79
- * trimState: capped to `maxArchiveNodes`, and pruned to removals after the oldest retained request. */
76
+ /** Removed surface nodes as stamped COPIES carrying `gone`, in removal order; bounded to `maxArchiveNodes` and pruned to removals after
77
+ * the oldest retained request. */
80
78
  archived: SurfaceNode[];
81
- /** Cumulative billed-token totals per (provider, model), split into pricing periods for DeepSeek. Never trimmed, so
82
- * the estimate covers the COMPLETE session log. */
79
+ /** Cumulative billed-token totals per (provider, model, period); never trimmed, so the estimate covers the COMPLETE log. */
83
80
  cost?: SessionCostUsage;
84
- /** Whole-session human-input tally (see Snapshot.humanInputs); never trimmed, like `cost`. */
85
81
  humanInputs?: number;
86
- /** Whole-session answers tally (see Snapshot.answers); never trimmed, like `humanInputs`. */
87
82
  answers?: number;
88
- /** The user's newest own message as a bounded one-line preview. Last-wins: a text-less input (images only) keeps the previous line. */
83
+ /** The user's newest own message as a bounded one-line preview. Last-wins: a text-less input keeps the previous line. */
89
84
  lastUser?: string;
90
85
  archiveFloor?: number;
91
- /** Bumped by every fold that mutates the request records, context events, live surface, or removed-node
92
- * archive; the slim wire head carries it so an open tab knows its fetched detail went stale. */
86
+ /** Bumped when a fold mutates the served detail (requests, events, live surface, archive); the slim head carries it. */
93
87
  detailRev?: number;
94
- /** Whole-session timing totals (see TimingTotals), running sums over the COMPLETE session log like `cost`. */
88
+ /** Whole-session timing totals, running sums over the COMPLETE log like `cost`. */
95
89
  timing?: TimingTotals;
96
- /** The open step's start instant, armed by `step/start` and consumed by the `assistant/message` (TTFT/generation
97
- * split) and `step/end` (wall time) that follow. One slot, not a map: steps are sequential in the log, so the
98
- * newest `step/start` is the one those events close — a hostile interleaved log degrades to skipped durations. */
90
+ /** The open step's start instant, armed by `step/start` and consumed by the following `assistant/message` and `step/end`; one slot, not
91
+ * a map, so a hostile interleaved log degrades to skipped durations. */
99
92
  stepStart?: {
100
93
  time: number;
101
94
  firstToken?: number;
102
95
  };
103
- /** The open step's CLOSED user-wait intervals (real log instants), pushed replace-style as each wait settles: an
104
- * approval decision, or an `ask_user_question` call's whole tool window. `step/end` subtracts their clamped
105
- * union from the step window to price the request's `activeMs`, then deletes the slot. */
96
+ /** The open step's CLOSED user-wait intervals; `step/end` subtracts their clamped union from the step window to price `activeMs`, then
97
+ * deletes the slot. */
106
98
  stepWaits?: {
107
99
  start: number;
108
100
  end: number;
109
101
  }[];
110
- /** The open step's PENDING approval waits (request id → its `approval/asked` instant), disarmed by the matching
111
- * `approval/decided`. A crash mid-decision leaves the pair dangling, so `step/end` closes the survivors at its
112
- * own instant. Deleted at `step/start` (a superseded step's leftovers) and `step/end`. */
102
+ /** The open step's PENDING approval waits (request id → `approval/asked` instant); a crash mid-decision leaves the pair dangling, so
103
+ * `step/end` closes the survivors at its own instant. */
113
104
  stepApprovals?: Record<string, number>;
114
- /** The seq of the request record committed by the open step's `assistant/message` — the back-pointer `step/end`
115
- * stamps `activeMs` onto. Nothing pushes between a step's message and its end, so the record is the requests
116
- * tail and the stamp is an O(1) tail write guarded by this seq. */
105
+ /** The seq of the request record the open step's `assistant/message` committed — the back-pointer `step/end` stamps `activeMs` onto;
106
+ * nothing pushes between a step's message and its end, so the stamp is an O(1) tail write. */
117
107
  stepRequestSeq?: number;
118
- /** The timing strip's painted spans: every completed step's time slices in log order, stamped with their REAL
119
- * instants — the TTFT wait, the decode blocks in stream order, the tool-run windows, and the in-step residue.
120
- * Idle time BETWEEN steps carries no span. Bounded by TIMING_SPANS_MAX (newest tail kept). */
108
+ /** The timing strip's painted spans in log order, stamped with their REAL instants; idle time BETWEEN steps carries no span. Bounded by
109
+ * TIMING_SPANS_MAX (newest tail kept). */
121
110
  spans: TimingSpan[];
122
- /** The open step's accumulated painted spans; `step/end` clamps them into the step window, de-overlaps
123
- * first-wins (parallel runs paint their union), fills the holes with the residue kind, and flushes the tiling
124
- * into `spans`. Deleted at the flush (the plain-JSON precondition). */
111
+ /** The open step's accumulated spans; `step/end` clamps them into the step window, de-overlaps first-wins (parallel runs paint their
112
+ * union), fills holes with the residue kind, then deletes the slot (plain-JSON precondition). */
125
113
  stepSpans?: TimingSpan[];
126
- /** Tool callId → the call's name, start instant, and raw arguments, armed by `tool/call` and DELETED when its
127
- * `tool/result` folds in — the map stays at pending-call size instead of growing for the session's lifetime. */
114
+ /** Tool callId → name, start instant and raw arguments, armed by `tool/call` and DELETED when its `tool/result` folds in — the map
115
+ * stays at pending-call size instead of growing for the session's lifetime. */
128
116
  callNames: Record<string, {
129
117
  name: string;
130
118
  start: number;
131
119
  argsRaw?: string;
132
120
  }>;
133
- /** Seq list of the surface nodes the next replacement will shadow, armed by the metering event
134
- * (`compaction/summary` | `compaction/prune`) and consumed by the replacement that must follow it
135
- * synchronously. The producer's shadow price covers exactly these seqs, which can differ from the
136
- * replacement's declared range (pruned replacement nodes keep their own seqs, beyond the range end). */
121
+ /** Seq list the next replacement shadows, armed by the metering event and consumed by the replacement that must follow synchronously;
122
+ * it can differ from the replacement's declared range (pruned nodes keep their own seqs). */
137
123
  pendingShadowedSeqs?: number[];
138
- /** The seq of the `compaction/prune` event that armed `pendingShadowedSeqs`. The shadowed path rewrites that
139
- * event's `tokens` from the gross shadow price to the NET freed amount, so the row matches the drop the trend chart shows. */
124
+ /** The metering event whose `tokens` the shadowed path rewrites from gross shadow price to the NET freed amount. */
140
125
  pendingShadowEventSeq?: number;
141
- /** The fold-derived file-operation log: one record per executed file op, bounded by `maxFileOps`; the trim stamps `fileOpsFloor`. */
142
126
  fileOps: FileOpRecord[];
143
127
  /** The newest dropped op's seq (the card's coverage floor for the served op log). */
144
128
  fileOpsFloor?: number;
145
- /** Nested Code-Mode ops buffered by their top run_code call id until the parent's result folds (the dispatch
146
- * events land BEFORE it). Bounded by PENDING_CODE_OPS_MAX, so a hostile log that never settles a run_code cannot grow it. */
129
+ /** The command log, in call order (creation at `tool/call`, settle in place at `tool/result`/`job/settled`). */
130
+ commands: CommandStateRecord[];
131
+ /** The newest dropped command record's seq (the panel's coverage floor). */
132
+ commandsFloor?: number;
133
+ /** Whole-log execution tallies; each record contributes exactly once, at its running → terminal transition. */
134
+ commandStats?: CommandStats;
135
+ /** Nested Code-Mode command records buffered by their top run_code call id until the parent's result folds
136
+ * (same lifecycle as `pendingCodeOps`). */
137
+ pendingCodeCmds?: Record<string, CommandStateRecord[]>;
138
+ /** Nested Code-Mode ops buffered by their top run_code call id until the parent's result folds (the dispatch events land BEFORE it).
139
+ * Bounded by PENDING_CODE_OPS_MAX, so a hostile log that never settles a run_code cannot grow it. */
147
140
  pendingCodeOps?: Record<string, FileOpRecord[]>;
148
141
  }
149
142
  //#endregion
150
143
  //#region src/shared/types.d.ts
151
144
  declare module '@deepseek-ai/dsh-session-projection/types' {
152
145
  interface SessionProjectionMap {
153
- /** The plugin's timeline: slim head on the split generation, inline value on channel-less
154
- * hosts; key absence = the host half is not composed. */
146
+ /** Slim head on the split generation, inline value on channel-less hosts; key absence = no host half. */
155
147
  contextTimeline: ContextTimeline;
156
- /** Request-header content epochs — a separate unit so the hot timeline value stays lean;
157
- * key absence = an older host (tokens only). */
148
+ /** Epoch metadata in its own unit so the hot timeline stays lean; key absence = an older host (tokens only). */
158
149
  contextHeaders: ContextHeaders;
159
- /** The per-day activity ledger behind the Context Insights heatmap; key absence = an older host (empty heatmap). */
150
+ /** The per-day activity ledger; key absence = an older host (empty heatmap). */
160
151
  contextActivity: ContextActivity;
161
152
  }
162
153
  interface SessionProjectionStateMap {
@@ -165,25 +156,23 @@ declare module '@deepseek-ai/dsh-session-projection/types' {
165
156
  contextActivity: ActivityState;
166
157
  }
167
158
  }
168
- /** The priced surface buckets. `skill` carries the skill-machinery content the harness injects:
169
- * the `<available_skills>` digest, a `/name` invocation's instructions, and a `skill`-tool load. */
159
+ /** `skill` is the harness-injected skill machinery: the `<available_skills>` digest, a `/name` invocation's instructions, and a
160
+ * `skill`-tool load. */
170
161
  type Category = 'user' | 'inject' | 'skill' | 'assistant' | 'tool';
171
- /** One live system-prompt node; the harness models the prompt as a surface node, so its TEXT is
172
- * fetched from the `system/message` event at `seq`. The effective figure is the LAST node with `tokens > 0`. */
162
+ /** Its TEXT comes from the `system/message` event at `seq`; the effective figure is the LAST node with `tokens > 0`. */
173
163
  interface SystemPromptNode {
174
164
  seq: number;
175
165
  time: number;
176
166
  tokens: number;
177
167
  }
178
- /** Counts precomputed over the RETAINED request/event records; `steps` is the retained request-record count. */
168
+ /** Counts over the RETAINED records; `steps` is the retained request-record count. */
179
169
  interface TimelineCounts {
180
170
  turns: number;
181
171
  steps: number;
182
172
  injects: number;
183
173
  compactions: number;
184
174
  prunes: number;
185
- /** Distinct names among the retained events tagged `sub: 'skill'`; the `<available_skills>`
186
- * digest has no name and never counts. Absent = 0. */
175
+ /** Distinct names among the retained events tagged `sub: 'skill'`; the digest has none and never counts. Absent = 0. */
187
176
  skills?: number;
188
177
  }
189
178
  /** The newest retained request record's billing summary. */
@@ -193,13 +182,11 @@ interface TimelineLast {
193
182
  prompt?: number;
194
183
  }
195
184
  interface ActivityDay {
196
- /** Billed tokens from provider-reported usage that day (input + cache read/write + output); a
197
- * settlement-less request counts only toward `requests`. */
185
+ /** Billed tokens that day (input + cache read/write + output); a settlement-less request counts only toward `requests`. */
198
186
  tokens: number;
199
187
  /** Completed model calls (assistant settlements) that day. */
200
188
  requests: number;
201
- /** The day's billed buckets keyed provider → model → pricing period, scoped to the day the
202
- * requests INITIATED in. Absent = tokens-only bars. */
189
+ /** Keyed provider → model → pricing period, scoped to the day the requests INITIATED. Absent = tokens-only bars. */
203
190
  cost?: SessionCostUsage;
204
191
  /** Turns whose FIRST settlement landed on this (step-initiation) day. */
205
192
  turns?: number;
@@ -215,37 +202,35 @@ interface ActivityDay {
215
202
  last: number;
216
203
  }>;
217
204
  }
218
- /** The per-session daily ledger: host-local day key (`YYYY-MM-DD`, shared/days.ts) → that day's
219
- * billed volume; the Context Insights page merges every listed session's ledger. */
205
+ /** Host-local day key (`YYYY-MM-DD`, shared/days.ts) → that day's billed volume; the Insights page merges every listed ledger. */
220
206
  interface ContextActivity {
221
207
  days: Record<string, ActivityDay>;
222
208
  }
223
- /** One available skill's catalog metadata, served by `/api/dsh-context/skills` (host/skills.ts); every field but `name` is best-effort. */
209
+ /** Served by `/api/dsh-context/skills` (host/skills.ts); every field but `name` is best-effort. */
224
210
  interface SkillInfo {
225
211
  /** Kebab-case identifier — the join key onto `ActivityDay.skills`. */
226
212
  name: string;
227
213
  description: string;
228
214
  /** Absolute instruction file path, when the provider is filesystem-backed. */
229
215
  path?: string;
230
- /** Discovery source bucket (e.g. 'project-agents', 'user-dsh', 'bundled'). */
216
+ /** Discovery source bucket ('project-agents', 'user-dsh', 'bundled', …). */
231
217
  source?: string;
232
218
  }
233
- /** The display-preference vocabulary of the `dsh-context` entry — the ONE declaration shared by
234
- * the Host Config schema (host/config.ts) and the Client's settings form (client/settings.ts). */
219
+ /** The ONE declaration shared by the Host Config schema (host/config.ts) and the Client's settings form. */
235
220
  type DefaultGranularity = 'step' | 'turn';
236
221
  type DefaultTrendMode = 'total' | 'delta';
237
- /** The browser delta baseline: against the immediately preceding record, or the previous turn's last step. */
222
+ /** The browser delta baseline: the immediately preceding record, or the previous turn's last step. */
238
223
  type DefaultDeltaBase = 'step' | 'turn';
239
- type DefaultFileSort = 'count' | 'latest' | 'path' | 'name';
224
+ type DefaultFileSort = 'count' | 'lines' | 'latest' | 'path' | 'name';
240
225
  type DefaultToolSort = 'size' | 'count' | 'name';
241
- type DefaultPlacement = 'all' | 'tab' | 'sidebar';
226
+ /** Where the Context panel mounts; 'hide' registers no surface. */
227
+ type DefaultPlacement = 'all' | 'tab' | 'sidebar' | 'hide';
242
228
  type InsightsEntry = 'show' | 'hide';
243
229
  type DefaultDurationCurve = 'show' | 'hide';
244
230
  /** Retained-step count at which the trend turns its Overview ribbon on; 'off' never auto-switches. */
245
231
  type OverviewAutoSteps = 'off' | '100' | '200' | '300';
246
- /** The Context Insights page's rolling preset; a calendar-picked range replaces it for that visit only. */
232
+ /** The Insights page's rolling preset; a calendar-picked range replaces it for that visit only. */
247
233
  type DefaultOverviewRange = 'today' | '7d' | '30d' | 'all';
248
- /** Whether the Fleet conversation tab is served. */
249
234
  type FleetTab = 'show' | 'hide';
250
235
  interface PluginSettings {
251
236
  defaultPlacement: DefaultPlacement;
@@ -266,17 +251,19 @@ interface PluginSettings {
266
251
  }
267
252
  interface Snapshot {
268
253
  ok: boolean;
269
- /** Present ONLY when the running harness is below the supported baseline: the host folds
270
- * nothing (all figures zero) and the client shows the upgrade gate. */
254
+ /** Present ONLY below the supported baseline: the host folds nothing (all figures zero) and the client shows the upgrade gate. */
271
255
  unsupported?: {
272
256
  current: string;
273
257
  minimum: string;
274
258
  };
275
259
  model?: string;
276
260
  provider?: string;
261
+ /** The newest request envelope's materialized reasoning effort. Absent = no effort in force, or a row folded before the field
262
+ * existed. */
263
+ reasoningEffort?: string;
277
264
  contextWindow?: number;
278
- /** The newest request envelope's routed output cap, which auto-compaction reserves before pricing
279
- * its pressure trigger. Absent = no cap in the log (or a row folded before the field existed). */
265
+ /** The newest request envelope's routed output cap (auto-compaction reserves it). Absent = no cap in the log, or a row folded before
266
+ * the field existed. */
280
267
  maxOutputTokens?: number;
281
268
  current: {
282
269
  system: number;
@@ -288,57 +275,58 @@ interface Snapshot {
288
275
  tool: number;
289
276
  total: number;
290
277
  };
291
- /** Image blocks in the CURRENT context (uploads plus nested tool-result images), summed over live surface nodes. Absent = 0. */
278
+ /** Image blocks in the CURRENT context (uploads plus nested tool-result images). Absent = 0. */
292
279
  images?: number;
293
- /** Tool calls whose result is live (a `skill`-tool node keeps counting); in-flight and
294
- * compacted/pruned-out calls are excluded. Absent = 0. */
280
+ /** Tool calls whose result is live (a `skill`-tool node keeps counting). Absent = 0. */
295
281
  toolCalls?: number;
296
- /** Whole-session tally of non-injection `user/message` plus answered `ask_user_question` — a
297
- * running total over the COMPLETE log. Absent = 0. */
282
+ /** Whole-session tally of non-injection `user/message` plus answered `ask_user_question` over the COMPLETE log. Absent = 0. */
298
283
  humanInputs?: number;
299
284
  /** Whole-session replies: one per assistant message carrying non-blank text (tool-only steps are not replies). Absent = 0. */
300
285
  answers?: number;
301
286
  /** The newest own message as a one-line preview (first text block, whitespace collapsed, 80 chars max). Absent = hidden. */
302
287
  lastUser?: string;
303
- /** Split-generation head fields — present exactly when the host serves the slim head;
304
- * `detailRev` bumps whenever the detail collections change. */
288
+ /** Split-generation head fields: present exactly when the host serves the slim head; `detailRev` bumps whenever the detail collections
289
+ * change. */
305
290
  counts?: TimelineCounts;
306
291
  last?: TimelineLast;
307
292
  detailRev?: number;
308
- /** The slim head serves these EMPTY (the collections ride the detail channel); the client swaps in the detail payload's collections. */
293
+ /** The slim head serves these EMPTY (collections ride the detail channel): the client swaps in the detail payload's. */
309
294
  requests: RequestRecord[];
310
295
  events: ContextEventRecord[];
311
- /** Cumulative session-cost raw material (SessionCostUsage); absent until a request with a known model reports usage. */
296
+ /** Cumulative session-cost raw material; absent until a request with a known model reports usage. */
312
297
  cost?: SessionCostUsage;
313
- /** Whole-session timing totals (TimingTotals). Absent until the first step lifecycle completes. */
298
+ /** Whole-session timing totals; absent until the first step lifecycle completes. */
314
299
  timing?: TimingTotals;
315
- /** The live system-prompt nodes, oldest first. Absent on rows folded before the field existed
316
- * — the client then reads the header epoch's `systemTokens`. */
300
+ /** The live system-prompt nodes, oldest first. Absent on rows folded before the field existed: the client then reads the header epoch's
301
+ * `systemTokens`. */
317
302
  systems?: SystemPromptNode[];
318
- /** The served live surface: the newest `maxNodes` tail PLUS every live inject/skill node older
319
- * than the tail (they land first and are pinned). Seq-ordered, oldest first. */
303
+ /** The served live surface: the newest `maxNodes` tail PLUS every older live inject/skill node (they land first and are pinned).
304
+ * Seq-ordered, oldest first. */
320
305
  nodes: SurfaceNode[];
321
306
  /** Live nodes not served: the overflow beyond `maxNodes` minus the pinned inject/skill nodes. */
322
307
  droppedNodes: number;
323
- /** Recently REMOVED surface nodes (compaction/prune shadows) stamped with `gone` (the replacing
324
- * event's seq); a node belongs to request R when `seq < R.seq && (gone undefined || gone > R.seq)`. */
308
+ /** Recently REMOVED surface nodes stamped with `gone` (the replacing event's seq); a node belongs to request R when `seq < R.seq &&
309
+ * (gone undefined || gone > R.seq)`. */
325
310
  archive: SurfaceNode[];
326
311
  /** Newest seq among the `droppedNodes` nodes not served; present only when droppedNodes > 0. */
327
312
  surfaceFloor?: number;
328
313
  /** Newest `gone` among retention-dropped archive entries; steps below it may miss removed nodes. */
329
314
  archiveFloor?: number;
330
- /** The fold-derived file-op log and trim floor: the INLINE value and detail payload, never the slim head. */
315
+ /** The fold-derived file-op log and trim floor: INLINE value and detail payload only, never the slim head. */
331
316
  fileOps?: FileOpRecord[];
332
317
  fileOpsFloor?: number;
333
- /** The timing strip's painted spans: INLINE value and detail payload only; absent on rows folded before the collection existed. */
318
+ /** The fold-derived command log and its trim floor/coverage honesty, same channel as `fileOps`. */
319
+ commands?: CommandRecord[];
320
+ commandsFloor?: number;
321
+ /** Whole-log execution tallies behind the command panel's title; survives list trimming. */
322
+ commandStats?: CommandStats;
323
+ /** INLINE value and detail payload only; absent on rows folded before the collection existed. */
334
324
  spans?: TimingSpan[];
335
325
  }
336
- /** The on-demand DETAIL payload of the split generation: the heavy collections the slim head no
337
- * longer carries (host/detail.ts). `rev` mirrors the head's `detailRev` and is the client's latest-wins cursor. */
326
+ /** The split generation's DETAIL payload (host/detail.ts); `rev` mirrors the head's `detailRev` and is the client's latest-wins cursor. */
338
327
  interface ContextTimelineDetail {
339
328
  rev: number;
340
- /** The slim head at the SAME fold cut as the collections — a session listed cold has no
341
- * `contextTimeline` row, so the Agent network ring reads this. Optional. */
329
+ /** The slim head at the SAME fold cut; a cold-listed session has no `contextTimeline` row, so the Agent network ring reads this. */
342
330
  head?: ContextTimeline;
343
331
  requests: RequestRecord[];
344
332
  events: ContextEventRecord[];
@@ -347,16 +335,84 @@ interface ContextTimelineDetail {
347
335
  archive: SurfaceNode[];
348
336
  surfaceFloor?: number;
349
337
  archiveFloor?: number;
350
- /** The file-op log (shared/fileOps.ts) over the FULL log; Code-Mode nested dispatches book on their parent run_code result (`parent`). */
338
+ /** The file-op log (shared/fileOps.ts) over the FULL log; Code-Mode nested dispatches book on their parent `run_code` result. */
351
339
  fileOps?: FileOpRecord[];
352
- /** The newest dropped op's seq when the op log trimmed (coverage honesty, same family as archiveFloor). */
340
+ /** The newest dropped op's seq when the op log trimmed (coverage honesty, same family as `archiveFloor`). */
353
341
  fileOpsFloor?: number;
342
+ /** The command log (shared/commands.ts); nested Code-Mode dispatches flush on their parent `run_code` result. */
343
+ commands?: CommandRecord[];
344
+ /** The newest dropped record's seq when the command log trimmed. */
345
+ commandsFloor?: number;
346
+ commandStats?: CommandStats;
354
347
  /** The completed steps' time slices in log order, positioned by their real instants. Absent = no strip. */
355
348
  spans?: TimingSpan[];
356
349
  }
357
- /** One executed file operation, folded host-side from the durable tool lifecycle (`tool/call` +
358
- * `tool/result`, or a nested `tool/ptc-dispatch`); line deltas are estimates read off the call
359
- * ARGUMENTS. `gone` is client-joined, not host-stamped. */
350
+ type CommandStatus = 'running' | 'completed' | 'failed' | 'killed';
351
+ /** One shell/code execution, folded from `tool/call` (creation) paired with `tool/result` and — on hosts that log them —
352
+ * `job/registered` / `job/settled` (precise timing and outcome). Without job events the timing/exit are envelope-derived
353
+ * (`derived: true`). Nested Code-Mode dispatches carry `parent` (their run_code result's seq, the locate target).
354
+ * `gone` is client-joined, not host-stamped. */
355
+ interface CommandRecord {
356
+ /** The call event's seq — the record's stable identity. */
357
+ seq: number;
358
+ /** The result event's seq — the surface node a reveal targets. Absent while running and on nested Code-Mode records
359
+ * (those reveal on `parent`). */
360
+ resultSeq?: number;
361
+ /** The call event's instant — the list's chronological anchor. */
362
+ time: number;
363
+ tool: string;
364
+ /** The command text (a run_code record carries the program's source), capped at the fold's maxCommandChars. */
365
+ cmd: string;
366
+ cmdTruncated?: true;
367
+ /** The model-authored intent (bash/pwsh require it; persistent shells and run_code may omit it). */
368
+ description?: string;
369
+ /** The result meta's cwd when logged, else the workdir argument; absent = the session's cwd. */
370
+ cwd?: string;
371
+ timeoutMs?: number;
372
+ /** Dispatched to the background (an acked result with no outcome yet shows running until a `job/settled` lands). */
373
+ background?: true;
374
+ /** The requested sandbox escalation, when the call carried one. */
375
+ sandbox?: string;
376
+ /** A nested Code-Mode dispatch record. */
377
+ codeMode?: true;
378
+ parent?: number;
379
+ turn?: number;
380
+ step?: number;
381
+ /** job.startedAt when registered, else the call instant. */
382
+ start: number;
383
+ /** job.finishedAt when settled, else the result instant; absent while running. */
384
+ end?: number;
385
+ status: CommandStatus;
386
+ /** Explicit exit code from a marker or job detail; absent = unknown (never fabricate a 0). */
387
+ exit?: number;
388
+ /** The exit 0 was inferred from the ABSENCE of any marker (the shell tools omit the marker on a clean exit). */
389
+ exitInferred?: true;
390
+ signal?: string;
391
+ timedOut?: true;
392
+ stopped?: true;
393
+ denied?: true;
394
+ /** The result message's isError (an infrastructure failure, not a command failure). */
395
+ err: boolean;
396
+ outChars?: number;
397
+ outTruncated?: true;
398
+ stderr?: true;
399
+ /** Timing/exit derive from event envelopes — no job events on this log (parallel calls can overstate durations). */
400
+ derived?: true;
401
+ gone?: number;
402
+ }
403
+ /** Whole-log execution tallies, maintained incrementally: `runs`/`failed`/`ms` at each record's terminal transition,
404
+ * `bg` when a background dispatch becomes known (the argument at creation, else the hand-off ack). */
405
+ interface CommandStats {
406
+ runs: number;
407
+ /** Failed OR killed terminal outcomes. */
408
+ failed: number;
409
+ /** Summed execution ms over records with both endpoints known (concurrent runs double-count wall time). */
410
+ ms: number;
411
+ /** Runs dispatched to the background, whether or not they ever settle. */
412
+ bg: number;
413
+ }
414
+ /** Folded from the durable tool lifecycle (`tool/call` + `tool/result`, or a nested `tool/ptc-dispatch`); line deltas are estimates off
415
+ * the call ARGUMENTS. `gone` is client-joined, not host-stamped. */
360
416
  interface FileOpRecord {
361
417
  seq: number;
362
418
  /** The op's file; for a pathless search the searched PATTERN (`pattern: true`). */
@@ -390,9 +446,8 @@ interface FileOpRecord {
390
446
  }
391
447
  /** The `contextTimeline` projection's whole value; `ok` is always `true` here (kept for wire compatibility). */
392
448
  type ContextTimeline = Snapshot;
393
- /** One painted span of the timing card's session-time strip (a step's TTFT wait, decode block,
394
- * tool-run window, or residue gap). `start`/`end` are the slice's REAL instants; the strip packs
395
- * them gapless in log order, and `end` > `start` always. */
449
+ /** One painted span of the timing strip (TTFT wait, decode block, tool-run window, or residue gap); `start`/`end` are REAL instants,
450
+ * packed gapless in log order, and `end` > `start` always. */
396
451
  interface TimingSpan {
397
452
  /** The timing card's own slice vocabulary (same keys, same colors). */
398
453
  kind: 'ttft' | 'reasoning' | 'text' | 'toolarg' | 'tools' | 'other';
@@ -410,23 +465,9 @@ interface ToolTimingTotals {
410
465
  calls: number;
411
466
  ms: number;
412
467
  }
413
- /**
414
- * Whole-session timing totals, host-folded from the durable step/tool lifecycle plus the call's
415
- * first token (its embedded `assistant/message.data.stream`); running totals over the COMPLETE log.
416
- *
417
- * Milliseconds: `wallMs` sums whole steps; `ttftMs` the step-start → decode-start slice and `genMs`
418
- * the decode-start → assistant-message slice (only over calls whose stream carried a token delta);
419
- * `toolsMs` sums per-call tool durations (parallel calls each count). The decode window opens at the
420
- * first OBSERVABLE instant — the first token, or an earlier `block-start` marker (a redacted
421
- * reasoning block leaves no chunk): anchoring at the token would double-count the marker-tiled
422
- * window past 100%.
423
- *
424
- * The generation split comes off the stream's `block-start` framing (`blockType`): `reasoningMs` /
425
- * `textMs` / `toolArgMs` and their block counts, each marker owning the interval to the next.
426
- * `speedTokens`/`speedMs` are the harness-parity throughput seat (first-token → assistant-message,
427
- * calls carrying both); `speedMs` KEEPS the first-token anchor. `calls` counts folded assistant
428
- * messages, `toolCalls` folded call/result pairs.
429
- */
468
+ /** Whole-session totals over the COMPLETE log: `wallMs` whole steps, `ttftMs` step-start → decode-start, `genMs`
469
+ * decode-start → assistant-message, `toolsMs` per-call. The decode window opens at the first OBSERVABLE instant, so
470
+ * marker-tiled windows never double-count; speed* keep the first-token anchor; `calls`/`toolCalls` count messages/pairs. */
430
471
  interface TimingTotals {
431
472
  wallMs: number;
432
473
  ttftMs: number;
@@ -445,21 +486,19 @@ interface TimingTotals {
445
486
  /** Per-tool-name tallies behind the timing card's ranking (bounded). */
446
487
  tools: Record<string, ToolTimingTotals>;
447
488
  }
448
- /** One billed model's totals split by pricing period: providers without period pricing book
449
- * everything under `peak`; DeepSeek's `peak` buckets price at twice the list (off-peak) rate,
450
- * `off` buckets at list. */
489
+ /** One billed model's totals split by pricing period: period-less providers book everything under `peak`; DeepSeek's `peak` prices at
490
+ * twice the list (off-peak) rate, `off` at list. */
451
491
  interface CostModelUsage {
452
492
  peak?: CostBucketTotals;
453
493
  off?: CostBucketTotals;
454
494
  }
455
- /** The session-cost raw material: cumulative provider-reported billed tokens keyed by the request
456
- * envelope's DSH provider id ('' when none) then model id — the faces the Client's models.dev price book resolves. */
495
+ /** Cumulative provider-reported billed tokens keyed by the request envelope's DSH provider id ('' when none) then model id — the faces
496
+ * the Client's models.dev price book resolves. */
457
497
  interface SessionCostUsage {
458
498
  [provider: string]: {
459
499
  [model: string]: CostModelUsage;
460
500
  };
461
501
  }
462
- /** One model-visible message on the surface, with its heuristic token price. */
463
502
  interface SurfaceNode {
464
503
  seq: number;
465
504
  time?: number;
@@ -470,8 +509,8 @@ interface SurfaceNode {
470
509
  /** Set only on `archive` entries: the seq of the replacement event that shadowed this node. */
471
510
  gone?: number;
472
511
  form?: string;
473
- /** The producer identity the matching inject event names (host pricing.ts
474
- * `injectionSourceName`); absent when unreadable or predating the stamp. */
512
+ /** The producer identity the matching inject event names (host pricing.ts `injectionSourceName`); absent when unreadable or predating
513
+ * the stamp. */
475
514
  name?: string;
476
515
  text?: string;
477
516
  tool?: string;
@@ -493,15 +532,13 @@ interface RequestRecord {
493
532
  tool: number;
494
533
  total: number;
495
534
  prompt?: number;
496
- /** Skill-machinery tokens of this request (the `skill` composition category); absent on rows
497
- * folded before the category existed (read as 0). */
535
+ /** Skill-machinery tokens of this request; absent on rows folded before the category existed (read as 0). */
498
536
  skill?: number;
499
- /** Billed cache-read (served) prompt tokens — the hit-rate numerator against `prompt`; absent
500
- * on older hosts, and zero is a real value. */
537
+ /** Billed cache-read (served) prompt tokens — the hit-rate numerator against `prompt`; absent on older hosts, and zero is a real value.
538
+ */
501
539
  cacheRead?: number;
502
540
  output?: number;
503
- /** The step's ACTIVE ms (`step/start` → `step/end` minus in-step user waits: approval decisions
504
- * and `ask_user_question`), stamped at `step/end`; absent while the step is open. */
541
+ /** The step's ACTIVE ms (`step/start` → `step/end` minus in-step user waits), stamped at `step/end`; absent while the step is open. */
505
542
  activeMs?: number;
506
543
  /** Turn-mode aggregate marker, set by the Client's aggregateByTurn (the Host never sets it). */
507
544
  stepCount?: number;
@@ -527,17 +564,15 @@ interface ContextEventRecord {
527
564
  turn?: number;
528
565
  step?: number;
529
566
  }
530
- /** One tool of a request-header epoch, with its display price. */
531
567
  interface HeaderTool {
532
568
  name: string;
533
569
  tokens: number;
534
- /** The registering plugin's label when known: `mcp:<server>` for MCP tools, or the pinned
535
- * first-party map; `UNKNOWN_TOOL_SOURCE` marks a boot-time tool, absent = no tag. */
570
+ /** The registering plugin's label: `mcp:<server>` for MCP tools, or the pinned first-party map; `UNKNOWN_TOOL_SOURCE` marks a boot-time
571
+ * tool, absent = no tag. */
536
572
  plugin?: string;
537
573
  }
538
- /** One request-header epoch's METADATA (epoch boundaries and token prices, in force from this seq
539
- * until the next). The CONTENT is deliberately not projected — every list row and push frame would
540
- * carry it — and is fetched on demand as a {@link HeaderEpochContent}. */
574
+ /** One request-header epoch's METADATA, in force from this seq until the next. CONTENT is deliberately not projected (every list row
575
+ * would carry it) and is fetched as a {@link HeaderEpochContent}. */
541
576
  interface HeaderRecord {
542
577
  seq: number;
543
578
  time: number;
@@ -549,18 +584,16 @@ interface HeaderRecord {
549
584
  interface ContextHeaders {
550
585
  headers: HeaderRecord[];
551
586
  }
552
- /** One currency's DeepSeek open-platform balance figures. */
553
587
  interface PlatformBalanceEntry {
554
588
  /** The ISO code the platform reported (`CNY` / `USD`). */
555
589
  currency: string;
556
590
  /** `granted` + `toppedUp`, derived rather than read from the platform's `total_balance`, which rounds independently of its parts. */
557
591
  total: number;
558
- /** The not-expired granted (gift) balance. */
559
592
  granted: number;
560
593
  toppedUp: number;
561
594
  }
562
- /** The DeepSeek open-platform balance, served by `/api/dsh-context/balance`; `null` on the wire
563
- * (nothing rendered) when unconfigured or the read fails. */
595
+ /** The DeepSeek open-platform balance, served by `/api/dsh-context/balance`; `null` on the wire (nothing rendered) when unconfigured or
596
+ * the read fails. */
564
597
  interface PlatformBalance {
565
598
  isAvailable: boolean;
566
599
  /** One entry per currency the account holds; at least one. */
@@ -577,6 +610,9 @@ declare const DEFAULT_BOUNDS: {
577
610
  maxNodes: number;
578
611
  maxArchiveNodes: number;
579
612
  maxFileOps: number;
613
+ maxCommands: number;
614
+ /** The command text caps per record; the card offers the full text through the browser's message body. */
615
+ maxCommandChars: number;
580
616
  };
581
617
  /** The resolved fold bounds; derived from {@link DEFAULT_BOUNDS} so the two cannot drift. */
582
618
  type FoldBounds = typeof DEFAULT_BOUNDS;
@@ -588,12 +624,14 @@ export declare const Config: z$1<Schemastery.ObjectS<NoInfer<{
588
624
  maxNodes: z$1<number, number, "defined">;
589
625
  maxArchiveNodes: z$1<number, number, "defined">;
590
626
  maxFileOps: z$1<number, number, "defined">;
591
- defaultPlacement: z$1<"all" | "sidebar" | "tab", "all" | "sidebar" | "tab", "defined">;
627
+ maxCommands: z$1<number, number, "defined">;
628
+ maxCommandChars: z$1<number, number, "defined">;
629
+ defaultPlacement: z$1<"all" | "hide" | "sidebar" | "tab", "all" | "hide" | "sidebar" | "tab", "defined">;
592
630
  defaultGranularity: z$1<"step" | "turn", "step" | "turn", "defined">;
593
631
  defaultTrendMode: z$1<"delta" | "total", "delta" | "total", "defined">;
594
632
  defaultDeltaBase: z$1<"step" | "turn", "step" | "turn", "defined">;
595
633
  defaultToolSort: z$1<"count" | "name" | "size", "count" | "name" | "size", "defined">;
596
- defaultFileSort: z$1<"count" | "latest" | "name" | "path", "count" | "latest" | "name" | "path", "defined">;
634
+ defaultFileSort: z$1<"count" | "latest" | "lines" | "name" | "path", "count" | "latest" | "lines" | "name" | "path", "defined">;
597
635
  insightsEntry: z$1<"hide" | "show", "hide" | "show", "defined">;
598
636
  defaultDurationCurve: z$1<"hide" | "show", "hide" | "show", "defined">;
599
637
  overviewAutoSteps: z$1<"100" | "200" | "300" | "off", "100" | "200" | "300" | "off", "defined">;
@@ -608,12 +646,14 @@ export declare const Config: z$1<Schemastery.ObjectS<NoInfer<{
608
646
  maxNodes: z$1<number, number, "defined">;
609
647
  maxArchiveNodes: z$1<number, number, "defined">;
610
648
  maxFileOps: z$1<number, number, "defined">;
611
- defaultPlacement: z$1<"all" | "sidebar" | "tab", "all" | "sidebar" | "tab", "defined">;
649
+ maxCommands: z$1<number, number, "defined">;
650
+ maxCommandChars: z$1<number, number, "defined">;
651
+ defaultPlacement: z$1<"all" | "hide" | "sidebar" | "tab", "all" | "hide" | "sidebar" | "tab", "defined">;
612
652
  defaultGranularity: z$1<"step" | "turn", "step" | "turn", "defined">;
613
653
  defaultTrendMode: z$1<"delta" | "total", "delta" | "total", "defined">;
614
654
  defaultDeltaBase: z$1<"step" | "turn", "step" | "turn", "defined">;
615
655
  defaultToolSort: z$1<"count" | "name" | "size", "count" | "name" | "size", "defined">;
616
- defaultFileSort: z$1<"count" | "latest" | "name" | "path", "count" | "latest" | "name" | "path", "defined">;
656
+ defaultFileSort: z$1<"count" | "latest" | "lines" | "name" | "path", "count" | "latest" | "lines" | "name" | "path", "defined">;
617
657
  insightsEntry: z$1<"hide" | "show", "hide" | "show", "defined">;
618
658
  defaultDurationCurve: z$1<"hide" | "show", "hide" | "show", "defined">;
619
659
  overviewAutoSteps: z$1<"100" | "200" | "300" | "off", "100" | "200" | "300" | "off", "defined">;