@khorsheed/dsh-file-preview 0.1.0 → 0.2.0
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/CHANGELOG.md +12 -0
- package/README.en.md +15 -11
- package/README.i18n.yaml +2 -2
- package/README.md +31 -27
- package/lib/index.js +100 -46
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/typert.host.js +171 -31
- package/lib/typert.remote-client.d.ts.map +1 -1
- package/lib/typert.remote-client.js +4 -4
- package/lib/types/bash-writes.js +1 -1
- package/lib/types/fold.d.ts +8 -6
- package/lib/types/fold.d.ts.map +1 -1
- package/lib/types/fold.js +41 -18
- package/lib/types/index.d.ts +26 -8
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +81 -25
- package/package.json +15 -13
package/lib/typert.host.js
CHANGED
|
@@ -93,7 +93,7 @@ export const TYPERT = {
|
|
|
93
93
|
typeSymbol: '@khorsheed/dsh-file-preview/types#FilePreviewList',
|
|
94
94
|
schema: _khorsheed_dsh_file_preview_filePreview_list_result$schema,
|
|
95
95
|
},
|
|
96
|
-
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":
|
|
96
|
+
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":368,"column":9},
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
99
|
id: '@khorsheed/dsh-file-preview#filePreview/read',
|
|
@@ -134,7 +134,7 @@ export const TYPERT = {
|
|
|
134
134
|
typeSymbol: '@khorsheed/dsh-file-preview/types#FilePreviewRead',
|
|
135
135
|
schema: _khorsheed_dsh_file_preview_filePreview_read_result$schema,
|
|
136
136
|
},
|
|
137
|
-
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":
|
|
137
|
+
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":458,"column":9},
|
|
138
138
|
},
|
|
139
139
|
{
|
|
140
140
|
id: '@khorsheed/dsh-file-preview#filePreview/reveal',
|
|
@@ -175,7 +175,7 @@ export const TYPERT = {
|
|
|
175
175
|
typeSymbol: '@khorsheed/dsh-file-preview/types#FilePreviewReveal',
|
|
176
176
|
schema: _khorsheed_dsh_file_preview_filePreview_reveal_result$schema,
|
|
177
177
|
},
|
|
178
|
-
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":
|
|
178
|
+
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":535,"column":9},
|
|
179
179
|
},
|
|
180
180
|
{
|
|
181
181
|
id: '@khorsheed/dsh-file-preview#filePreview/turnFiles',
|
|
@@ -205,32 +205,32 @@ export const TYPERT = {
|
|
|
205
205
|
typeSymbol: '@khorsheed/dsh-file-preview/types#FilePreviewTurnMap',
|
|
206
206
|
schema: _khorsheed_dsh_file_preview_filePreview_turnFiles_result$schema,
|
|
207
207
|
},
|
|
208
|
-
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":
|
|
208
|
+
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":405,"column":9},
|
|
209
209
|
},
|
|
210
210
|
],
|
|
211
211
|
model: {
|
|
212
212
|
"services": [
|
|
213
213
|
{
|
|
214
|
-
"description": "The `filePreview` Remote service: session-scoped read-only file inspection for web surfaces. `list` is a
|
|
214
|
+
"description": "The `filePreview` Remote service: session-scoped read-only file inspection for web surfaces. `list` is a fold over the session log, then filtered to the paths that still exist on disk (resolved against the session cwd and stat-ed per call); `read` resolves the path against the session cwd and serves current text content through `ctx.fs` (or a browser URL for images), capped by config. Image bytes ride a dedicated host route so the browser loads them natively without bloating the RPC channel.",
|
|
215
215
|
"summary": "The `filePreview` Remote service: session-scoped read-only file inspection for web surfaces.",
|
|
216
216
|
"tags": [],
|
|
217
|
-
"jsDoc": "/**\n * The `filePreview` Remote service: session-scoped read-only file inspection\n * for web surfaces. `list` is a
|
|
217
|
+
"jsDoc": "/**\n * The `filePreview` Remote service: session-scoped read-only file inspection\n * for web surfaces. `list` is a fold over the session log, then filtered to the\n * paths that still exist on disk (resolved against the session cwd and stat-ed\n * per call); `read` resolves the path against the session cwd and serves current\n * text content through `ctx.fs` (or a browser URL for images), capped by\n * config. Image bytes ride a dedicated host route so the browser loads them\n * natively without bloating the RPC channel.\n */",
|
|
218
218
|
"key": "filePreview",
|
|
219
219
|
"exportName": "FilePreviewService",
|
|
220
220
|
"members": [
|
|
221
221
|
{
|
|
222
222
|
"kind": "method",
|
|
223
223
|
"name": "list",
|
|
224
|
-
"signature": "@Remote('list') list(agent: Agent): FilePreviewList",
|
|
224
|
+
"signature": "@Remote('list') async list(agent: Agent): Promise<FilePreviewList>",
|
|
225
225
|
"summary": "List the files one session wrote or edited: the log fold plus any bash-written files the collector verified (the S2 seam), merged so a captured path the fold already knows keeps its log-derived entry.",
|
|
226
|
-
"jsDoc": "/**\n * List the files one session wrote or edited: the log fold plus any\n * bash-written files the collector verified (the S2 seam), merged so a\n * captured path the fold already knows keeps its log-derived entry.\n * @param agent - owning live agent; its session log is the data source.\n * @returns first-seen files capped by `maxFiles`, with the log watermark.\n */"
|
|
226
|
+
"jsDoc": "/**\n * List the files one session wrote or edited: the log fold plus any\n * bash-written files the collector verified (the S2 seam), merged so a\n * captured path the fold already knows keeps its log-derived entry. Only\n * paths that currently exist on disk are returned — a file the session\n * wrote and later deleted is history, not a product.\n * @param agent - owning live agent; its session log is the data source.\n * @returns existing first-seen files capped by `maxFiles`, with the log watermark.\n */"
|
|
227
227
|
},
|
|
228
228
|
{
|
|
229
229
|
"kind": "method",
|
|
230
230
|
"name": "turnFiles",
|
|
231
|
-
"signature": "@Remote('turnFiles') turnFiles(agent: Agent): FilePreviewTurnMap",
|
|
231
|
+
"signature": "@Remote('turnFiles') async turnFiles(agent: Agent): Promise<FilePreviewTurnMap>",
|
|
232
232
|
"summary": "Every turn's file mutations for the turn-tail card — the single source of truth the card renders (the client's old write/edit-only fold retired).",
|
|
233
|
-
"jsDoc": "/**\n * Every turn's file mutations for the turn-tail card — the single source of\n * truth the card renders (the client's old write/edit-only fold retired).\n * Built by folding the session log per turn (write/edit calls, Code Mode\n * dispatches borrowing the root call's turn, and render-intent paths from\n * result diff meta) and merging the collector's bash-written captures by\n * their own turn. The fold is cached per session and invalidated by the log\n * watermark, so repeated card fetches do not refold. A path touched in two\n * turns appears in BOTH turn groups — per-turn attribution is exact.\n * @param agent - owning live agent; its session log is the data source.\n * @returns per-turn file groups plus the scanned watermark.\n */"
|
|
233
|
+
"jsDoc": "/**\n * Every turn's file mutations for the turn-tail card — the single source of\n * truth the card renders (the client's old write/edit-only fold retired).\n * Built by folding the session log per turn (write/edit calls, Code Mode\n * dispatches borrowing the root call's turn, and render-intent paths from\n * result diff meta) and merging the collector's bash-written captures by\n * their own turn. The fold is cached per session and invalidated by the log\n * watermark, so repeated card fetches do not refold. A path touched in two\n * turns appears in BOTH turn groups — per-turn attribution is exact. Only\n * paths that currently exist on disk are returned (a deleted temp script is\n * history, not a product); existence is probed fresh on every call, so the\n * cached fold is filtered per request rather than cached.\n * @param agent - owning live agent; its session log is the data source.\n * @returns existing per-turn file groups plus the scanned watermark.\n */"
|
|
234
234
|
},
|
|
235
235
|
{
|
|
236
236
|
"kind": "method",
|
|
@@ -256,14 +256,30 @@ export const TYPERT = {
|
|
|
256
256
|
"name": "AgentCancelCause",
|
|
257
257
|
"declaration": "export type AgentCancelCause = { readonly kind: 'user'; } | { readonly kind: 'parent'; } | { readonly kind: 'hook'; readonly reason: string; } | { readonly kind: 'disposed'; };"
|
|
258
258
|
},
|
|
259
|
+
{
|
|
260
|
+
"name": "AgentMessageSource",
|
|
261
|
+
"declaration": "export interface AgentMessageSource {\n readonly kind: 'agent-message';\n readonly form: 'relay';\n readonly senderSessionId: SessionId;\n}"
|
|
262
|
+
},
|
|
259
263
|
{
|
|
260
264
|
"name": "AgentOptions",
|
|
261
|
-
"declaration": "export interface AgentOptions {\n provider?: string;\n model?: string;\n maxTokens?: number;\n}"
|
|
265
|
+
"declaration": "export interface AgentOptions {\n provider?: string;\n model?: string;\n reasoningEffort?: ReasoningEffortId;\n maxTokens?: number;\n subagentDepth?: number;\n}"
|
|
262
266
|
},
|
|
263
267
|
{
|
|
264
268
|
"name": "AgentStatus",
|
|
265
269
|
"declaration": "export type AgentStatus = 'idle' | 'running';"
|
|
266
270
|
},
|
|
271
|
+
{
|
|
272
|
+
"name": "ApprovalOutcome",
|
|
273
|
+
"declaration": "export type ApprovalOutcome = 'allowed-once' | 'rejected' | 'cancelled' | 'unavailable';"
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"name": "ApprovalPolicy",
|
|
277
|
+
"declaration": "export type ApprovalPolicy = 'ask' | 'never';"
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"name": "ApprovalRequestId",
|
|
281
|
+
"declaration": "export type ApprovalRequestId = Branded<'ApprovalRequestId'>;"
|
|
282
|
+
},
|
|
267
283
|
{
|
|
268
284
|
"name": "AssistantMessage",
|
|
269
285
|
"declaration": "export interface AssistantMessage extends Message {\n readonly role: 'assistant';\n readonly source: ModelMessageSource;\n}"
|
|
@@ -281,20 +297,24 @@ export const TYPERT = {
|
|
|
281
297
|
"declaration": "export type Branded<B extends string> = string & { readonly [BRAND]: B; };"
|
|
282
298
|
},
|
|
283
299
|
{
|
|
284
|
-
"name": "
|
|
285
|
-
"declaration": "export type
|
|
300
|
+
"name": "BrandedNumber",
|
|
301
|
+
"declaration": "export type BrandedNumber<B extends string> = number & { readonly [BRAND]: B; };"
|
|
286
302
|
},
|
|
287
303
|
{
|
|
288
304
|
"name": "CancelOptions",
|
|
289
305
|
"declaration": "export interface CancelOptions {\n keepInbox?: boolean | undefined;\n}"
|
|
290
306
|
},
|
|
291
307
|
{
|
|
292
|
-
"name": "
|
|
293
|
-
"declaration": "export
|
|
308
|
+
"name": "CommandId",
|
|
309
|
+
"declaration": "export type CommandId = Branded<'CommandId'>;"
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"name": "CommandSource",
|
|
313
|
+
"declaration": "export type CommandSource = CommandSourceMap[keyof CommandSourceMap];"
|
|
294
314
|
},
|
|
295
315
|
{
|
|
296
|
-
"name": "
|
|
297
|
-
"declaration": "export interface
|
|
316
|
+
"name": "CommandSourceMap",
|
|
317
|
+
"declaration": "export interface CommandSourceMap {\n user: { kind: 'user'; };\n}"
|
|
298
318
|
},
|
|
299
319
|
{
|
|
300
320
|
"name": "ContentBlock",
|
|
@@ -316,6 +336,10 @@ export const TYPERT = {
|
|
|
316
336
|
"name": "ContextSnapshotSection",
|
|
317
337
|
"declaration": "export interface ContextSnapshotSection {\n readonly name: string;\n readonly text: string;\n}"
|
|
318
338
|
},
|
|
339
|
+
{
|
|
340
|
+
"name": "ContinuableSubagentDescriptorData",
|
|
341
|
+
"declaration": "export interface ContinuableSubagentDescriptorData extends SubagentDescriptorBase {\n readonly mode: 'continuable';\n readonly label: string;\n readonly agentProvider?: string;\n readonly agentModel?: string;\n readonly agentReasoningEffort?: ReasoningEffortId;\n readonly persona?: string;\n readonly toolFilter?: ToolRestriction;\n}"
|
|
342
|
+
},
|
|
319
343
|
{
|
|
320
344
|
"name": "EpochHeader",
|
|
321
345
|
"declaration": "export interface EpochHeader {\n config: LlmCallConfig;\n adapterDefaults?: LlmCallConfigAdapterDefaults;\n system?: string;\n tools?: ToolSchema[];\n}"
|
|
@@ -418,16 +442,28 @@ export const TYPERT = {
|
|
|
418
442
|
},
|
|
419
443
|
{
|
|
420
444
|
"name": "MessageSourceMap",
|
|
421
|
-
"declaration": "export interface MessageSourceMap {\n user: { kind: 'user'; };\n plugin: { kind: 'plugin'; plugin: string; } & ContextFormed;\n model: ModelMessageSource;\n tool: ToolMessageSource;\n}"
|
|
445
|
+
"declaration": "export interface MessageSourceMap {\n user: { kind: 'user'; };\n plugin: { kind: 'plugin'; plugin: string; } & ContextFormed;\n model: ModelMessageSource;\n tool: ToolMessageSource;\n 'agent-message': AgentMessageSource;\n 'subagent-settled': SubagentSettledMessageSource;\n}"
|
|
422
446
|
},
|
|
423
447
|
{
|
|
424
448
|
"name": "ModelMessageSource",
|
|
425
449
|
"declaration": "export interface ModelMessageSource extends AssistantProvenance {\n kind: 'model';\n}"
|
|
426
450
|
},
|
|
451
|
+
{
|
|
452
|
+
"name": "OneShotSubagentDescriptorData",
|
|
453
|
+
"declaration": "export interface OneShotSubagentDescriptorData extends SubagentDescriptorBase {\n readonly mode: 'one-shot';\n readonly label?: string;\n}"
|
|
454
|
+
},
|
|
427
455
|
{
|
|
428
456
|
"name": "ProviderRequestId",
|
|
429
457
|
"declaration": "export type ProviderRequestId = Branded<'ProviderRequestId'>;"
|
|
430
458
|
},
|
|
459
|
+
{
|
|
460
|
+
"name": "PtcDispatchEventData",
|
|
461
|
+
"declaration": "export interface PtcDispatchEventData extends PtcDispatchStartEventData {\n isError: boolean;\n content: ContentBlock[];\n}"
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
"name": "PtcDispatchStartEventData",
|
|
465
|
+
"declaration": "export interface PtcDispatchStartEventData {\n rootCallId: ToolCallId;\n parentCallId: ToolCallId;\n subCallId: ToolCallId;\n name: string;\n arguments: unknown;\n}"
|
|
466
|
+
},
|
|
431
467
|
{
|
|
432
468
|
"name": "ReasoningBlock",
|
|
433
469
|
"declaration": "export interface ReasoningBlock {\n type: 'reasoning';\n text: string;\n}"
|
|
@@ -446,19 +482,79 @@ export const TYPERT = {
|
|
|
446
482
|
},
|
|
447
483
|
{
|
|
448
484
|
"name": "RequestHeaderReason",
|
|
449
|
-
"declaration": "export type RequestHeaderReason = 'initial' | 'resume' | 'change';"
|
|
485
|
+
"declaration": "export type RequestHeaderReason = 'initial' | 'resume' | 'change' | 'series';"
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
"name": "RoomCreatedEvent",
|
|
489
|
+
"declaration": "export interface RoomCreatedEvent {\n readonly version: 1;\n}"
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
"name": "RoomDispatchEvent",
|
|
493
|
+
"declaration": "export interface RoomDispatchEvent {\n readonly targets: readonly string[];\n readonly text: string;\n}"
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
"name": "RoomGoalEvent",
|
|
497
|
+
"declaration": "export interface RoomGoalEvent {\n readonly text: string;\n}"
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
"name": "RoomJsonValue",
|
|
501
|
+
"declaration": "export type RoomJsonValue = null | boolean | number | string | RoomJsonValue[] | { [key: string]: RoomJsonValue; };"
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
"name": "RoomMemberAddedEvent",
|
|
505
|
+
"declaration": "export interface RoomMemberAddedEvent {\n readonly name: string;\n readonly kind: 'main-agent' | 'cli';\n readonly provider?: string;\n readonly instructions?: string;\n readonly invitedBy: 'human' | 'agent';\n readonly cwd?: string;\n readonly childSessionId?: SessionId;\n}"
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
"name": "RoomMemberRemovedEvent",
|
|
509
|
+
"declaration": "export interface RoomMemberRemovedEvent {\n readonly name: string;\n}"
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
"name": "RoomMemberUpdatedEvent",
|
|
513
|
+
"declaration": "export interface RoomMemberUpdatedEvent {\n readonly name: string;\n readonly rename?: string;\n readonly instructions?: string | null;\n readonly cwd?: string | null;\n readonly childSessionId?: SessionId;\n}"
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
"name": "RoomRelayEvent",
|
|
517
|
+
"declaration": "export interface RoomRelayEvent {\n readonly id: string;\n readonly from: string;\n readonly to: string;\n readonly content: string;\n readonly provenance?: Record<string, RoomJsonValue>;\n}"
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
"name": "RoomRelayResolvedEvent",
|
|
521
|
+
"declaration": "export interface RoomRelayResolvedEvent {\n readonly id: string;\n readonly state: 'confirmed' | 'dismissed' | 'sent';\n}"
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
"name": "RoomRunStateEvent",
|
|
525
|
+
"declaration": "export interface RoomRunStateEvent {\n readonly member: string;\n readonly state: 'running' | 'done' | 'cancelled' | 'failed';\n readonly startedAt: number;\n readonly elapsedMs?: number;\n readonly error?: string;\n}"
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
"name": "RoomSpeechEvent",
|
|
529
|
+
"declaration": "export interface RoomSpeechEvent {\n readonly member: string;\n readonly text: string;\n readonly childSessionId?: SessionId;\n readonly durationMs?: number;\n}"
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
"name": "RoomTaskAddedEvent",
|
|
533
|
+
"declaration": "export interface RoomTaskAddedEvent {\n readonly id: string;\n readonly member: string;\n readonly title: string;\n readonly status: 'pending' | 'in_progress';\n readonly blockedBy?: string;\n}"
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
"name": "RoomTaskEditedEvent",
|
|
537
|
+
"declaration": "export interface RoomTaskEditedEvent {\n readonly id: string;\n readonly title?: string;\n readonly blockedBy?: string | null;\n}"
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
"name": "RoomTaskUpdatedEvent",
|
|
541
|
+
"declaration": "export interface RoomTaskUpdatedEvent {\n readonly id: string;\n readonly status: 'in_progress' | 'done' | 'cancelled' | 'failed';\n}"
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
"name": "SandboxMode",
|
|
545
|
+
"declaration": "export type SandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access';"
|
|
450
546
|
},
|
|
451
547
|
{
|
|
452
548
|
"name": "Session",
|
|
453
|
-
"declaration": "export class Session {\n get surface(): SessionSurface;\n readonly header: SessionHeader;\n get id(): SessionId;\n readonly firstLiveSeq:
|
|
549
|
+
"declaration": "export class Session {\n get surface(): SessionSurface;\n readonly header: SessionHeader;\n readonly inheritedEventCount: SessionLogOffset;\n get id(): SessionId;\n readonly firstLiveSeq: SessionLogOffset;\n eventAt(seq: SessionSeq): SessionEvent | undefined;\n snapshotEvents(fromSeq: SessionLogOffset = SessionLogOffset(0), toSeqExclusive: SessionLogOffset = this.seq): readonly SessionEvent[];\n ownEvents(): readonly SessionEvent[];\n isOwnSeq(seq: SessionSeq): boolean;\n get seq(): SessionLogOffset;\n append<T extends SessionEventType>(type: T, data: SessionEventMap[T], ...opts: T extends SurfaceEventType ? [opts: SurfaceIntent] : []): SessionEvent<T>;\n requestHeader(): EpochHeader | undefined;\n requestContext(): RequestContext | undefined;\n deriveMessages(): Message[];\n deriveEventMessage(event: SessionEvent): Message | null;\n}"
|
|
454
550
|
},
|
|
455
551
|
{
|
|
456
552
|
"name": "SessionEvent",
|
|
457
|
-
"declaration": "export type SessionEvent<T extends SessionEventType = SessionEventType> = { [K in SessionEventType]: { type: K; seq:
|
|
553
|
+
"declaration": "export type SessionEvent<T extends SessionEventType = SessionEventType> = { [K in SessionEventType]: { type: K; seq: SessionSeq; time: number; data: SessionEventMap[K]; ignorable?: true; } & (K extends SurfaceEventType ? { sourceEventSeqs?: SessionSeq[]; surfaceOp?: SurfaceOp; } : object) }[T];"
|
|
458
554
|
},
|
|
459
555
|
{
|
|
460
556
|
"name": "SessionEventMap",
|
|
461
|
-
"declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'assistant/chunk': { turn: number; step: number; chunk: StreamChunk; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; usage?: TokenUsage; interrupted?: true; };\n 'tool/call': { turn: number; step: number; callId:
|
|
557
|
+
"declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'assistant/chunk': { turn: number; step: number; chunk: StreamChunk; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; usage?: TokenUsage; interrupted?: true; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': Record<string, never>;\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/code-dispatch-start': PtcDispatchStartEventData;\n 'tool/code-dispatch': PtcDispatchEventData;\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: import('@deepseek-ai/dsh-session/types').SessionSeq; };\n 'subagent/descriptor': SubagentDescriptorData;\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'sandbox/mode': { mode: SandboxMode; source?: 'delegation'; };\n 'agent-preset/selected': { agentPreset: string; };\n 'room/created': RoomCreatedEvent;\n 'room/member-added': RoomMemberAddedEvent;\n 'room/member-updated': RoomMemberUpdatedEvent;\n 'room/member-removed': RoomMemberRemovedEvent;\n 'room/dispatch': RoomDispatchEvent;\n 'room/speech': RoomSpeechEvent;\n 'room/run-state': RoomRunStateEvent;\n 'room/relay': RoomRelayEvent;\n 'room/relay-resolved': RoomRelayResolvedEvent;\n 'room/task-added': RoomTaskAddedEvent;\n 'room/task-updated': RoomTaskUpdatedEvent;\n 'room/task-edited': RoomTaskEditedEvent;\n 'room/goal': RoomGoalEvent;\n}"
|
|
462
558
|
},
|
|
463
559
|
{
|
|
464
560
|
"name": "SessionEventType",
|
|
@@ -466,19 +562,55 @@ export const TYPERT = {
|
|
|
466
562
|
},
|
|
467
563
|
{
|
|
468
564
|
"name": "SessionHeader",
|
|
469
|
-
"declaration": "export interface SessionHeader {\n readonly version: number;\n readonly id: SessionId;\n readonly createdAt: number;\n readonly cwd?: string;\n readonly parentSession?: SessionId;\n readonly
|
|
565
|
+
"declaration": "export interface SessionHeader {\n readonly version: number;\n readonly id: SessionId;\n readonly createdAt: number;\n readonly cwd?: string;\n readonly parentSession?: SessionId;\n readonly isSeeded: boolean;\n readonly origin?: 'subagent';\n readonly delegationDepth?: number;\n readonly agentPreset?: string;\n}"
|
|
470
566
|
},
|
|
471
567
|
{
|
|
472
568
|
"name": "SessionId",
|
|
473
569
|
"declaration": "export type SessionId = Branded<'SessionId'>;"
|
|
474
570
|
},
|
|
571
|
+
{
|
|
572
|
+
"name": "SessionLogOffset",
|
|
573
|
+
"declaration": "export type SessionLogOffset = BrandedNumber<'SessionLogOffset'>;"
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
"name": "SessionSeq",
|
|
577
|
+
"declaration": "export type SessionSeq = BrandedNumber<'SessionSeq'>;"
|
|
578
|
+
},
|
|
475
579
|
{
|
|
476
580
|
"name": "SessionSurface",
|
|
477
|
-
"declaration": "export interface SessionSurface {\n readonly nodes: readonly
|
|
581
|
+
"declaration": "export interface SessionSurface {\n readonly nodes: readonly SessionSeq[];\n readonly replaceGeneration: number;\n}"
|
|
582
|
+
},
|
|
583
|
+
{
|
|
584
|
+
"name": "SessionTitleEventData",
|
|
585
|
+
"declaration": "export interface SessionTitleEventData {\n readonly title: string;\n readonly messageSeqs: SessionSeq[];\n readonly source: SessionTitleSource;\n}"
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
"name": "SessionTitleModelProvenance",
|
|
589
|
+
"declaration": "export interface SessionTitleModelProvenance {\n readonly provider: string;\n readonly model: string;\n}"
|
|
590
|
+
},
|
|
591
|
+
{
|
|
592
|
+
"name": "SessionTitleProviderId",
|
|
593
|
+
"declaration": "export type SessionTitleProviderId = Branded<'SessionTitleProviderId'>;"
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
"name": "SessionTitleSource",
|
|
597
|
+
"declaration": "export type SessionTitleSource = { readonly kind: 'fallback'; } | { readonly kind: 'provider'; readonly provider: SessionTitleProviderId; readonly model?: SessionTitleModelProvenance; } | { readonly kind: 'user'; };"
|
|
478
598
|
},
|
|
479
599
|
{
|
|
480
600
|
"name": "StreamChunk",
|
|
481
|
-
"declaration": "export type StreamChunk = { type: 'block-start'; index: number; blockType: ContentBlockType; } | { type: 'text-delta'; index: number; text: string; } | { type: 'reasoning-delta'; index: number; text: string; } | { type: 'tool-call-delta'; index: number; id:
|
|
601
|
+
"declaration": "export type StreamChunk = { type: 'block-start'; index: number; blockType: ContentBlockType; } | { type: 'text-delta'; index: number; text: string; } | { type: 'reasoning-delta'; index: number; text: string; } | { type: 'tool-call-delta'; index: number; id: ToolCallId; name?: string; argumentsDelta: string; } | { type: 'block-end'; index: number; block: ContentBlock; } | { type: 'usage'; usage: TokenUsage; } | { type: 'finish'; reason: FinishReason; replayState?: ReplayEnvelope; };"
|
|
602
|
+
},
|
|
603
|
+
{
|
|
604
|
+
"name": "SubagentDescriptorBase",
|
|
605
|
+
"declaration": "export interface SubagentDescriptorBase {\n readonly version: number;\n readonly mode: 'one-shot' | 'continuable';\n readonly provider: string;\n}"
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
"name": "SubagentDescriptorData",
|
|
609
|
+
"declaration": "export type SubagentDescriptorData = OneShotSubagentDescriptorData | ContinuableSubagentDescriptorData;"
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
"name": "SubagentSettledMessageSource",
|
|
613
|
+
"declaration": "export interface SubagentSettledMessageSource {\n readonly kind: 'subagent-settled';\n readonly form: 'notice';\n readonly summary: string;\n readonly senderSessionId: SessionId;\n}"
|
|
482
614
|
},
|
|
483
615
|
{
|
|
484
616
|
"name": "SurfaceEventType",
|
|
@@ -486,11 +618,11 @@ export const TYPERT = {
|
|
|
486
618
|
},
|
|
487
619
|
{
|
|
488
620
|
"name": "SurfaceIntent",
|
|
489
|
-
"declaration": "export interface SurfaceIntent {\n surfaceOp: SurfaceOp;\n sourceEventSeqs?:
|
|
621
|
+
"declaration": "export interface SurfaceIntent {\n surfaceOp: SurfaceOp;\n sourceEventSeqs?: SessionSeq[];\n}"
|
|
490
622
|
},
|
|
491
623
|
{
|
|
492
624
|
"name": "SurfaceOp",
|
|
493
|
-
"declaration": "export type SurfaceOp = 'append' | { op: 'replace'; start:
|
|
625
|
+
"declaration": "export type SurfaceOp = 'append' | { op: 'replace'; start: SessionSeq; end: SessionSeq; };"
|
|
494
626
|
},
|
|
495
627
|
{
|
|
496
628
|
"name": "TextBlock",
|
|
@@ -502,19 +634,27 @@ export const TYPERT = {
|
|
|
502
634
|
},
|
|
503
635
|
{
|
|
504
636
|
"name": "TokenUsage",
|
|
505
|
-
"declaration": "export interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n reasoningTokens?: number;\n}"
|
|
637
|
+
"declaration": "export interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n totalTokens?: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n reasoningTokens?: number;\n}"
|
|
506
638
|
},
|
|
507
639
|
{
|
|
508
640
|
"name": "ToolCallBlock",
|
|
509
|
-
"declaration": "export interface ToolCallBlock {\n type: 'tool-call';\n id:
|
|
641
|
+
"declaration": "export interface ToolCallBlock {\n type: 'tool-call';\n id: ToolCallId;\n name: string;\n arguments: string;\n}"
|
|
642
|
+
},
|
|
643
|
+
{
|
|
644
|
+
"name": "ToolCallId",
|
|
645
|
+
"declaration": "export type ToolCallId = Branded<'ToolCallId'>;"
|
|
510
646
|
},
|
|
511
647
|
{
|
|
512
648
|
"name": "ToolMessageSource",
|
|
513
|
-
"declaration": "export interface ToolMessageSource {\n kind: 'tool';\n callId:
|
|
649
|
+
"declaration": "export interface ToolMessageSource {\n kind: 'tool';\n callId: ToolCallId;\n}"
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
"name": "ToolRestriction",
|
|
653
|
+
"declaration": "export interface ToolRestriction {\n readonly allow?: readonly string[];\n readonly deny?: readonly string[];\n}"
|
|
514
654
|
},
|
|
515
655
|
{
|
|
516
656
|
"name": "ToolResultBlock",
|
|
517
|
-
"declaration": "export interface ToolResultBlock {\n type: 'tool-result';\n toolCallId:
|
|
657
|
+
"declaration": "export interface ToolResultBlock {\n type: 'tool-result';\n toolCallId: ToolCallId;\n content: ContentBlock[];\n isError?: boolean;\n}"
|
|
518
658
|
},
|
|
519
659
|
{
|
|
520
660
|
"name": "ToolResultMessage",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typert.remote-client.d.ts","names":["list","read","reveal","turnFiles"],"sources":["../src/index.ts"],"sourcesContent":[null],"mappings":";;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"typert.remote-client.d.ts","names":["list","read","reveal","turnFiles"],"sources":["../src/index.ts"],"sourcesContent":[null],"mappings":";;;;;;;;;;IA+WQA,I;IA0FAC,I;IA6EAC,M;IAlIAC,S;;;IArCAH,kB;IA0FAC,kB;IA6EAC,oB;IAlIAC,uB;;;;;;IArCAH,wB;IA0FAC,wB;IA6EAC,0B;IAlIAC,6B","ignoreList":[]}
|
|
@@ -90,7 +90,7 @@ export const TYPERT_REMOTE = {
|
|
|
90
90
|
typeSymbol: '@khorsheed/dsh-file-preview/types#FilePreviewList',
|
|
91
91
|
schema: _khorsheed_dsh_file_preview_filePreview_list_result$schema,
|
|
92
92
|
},
|
|
93
|
-
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":
|
|
93
|
+
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":368,"column":9},
|
|
94
94
|
},
|
|
95
95
|
{
|
|
96
96
|
id: '@khorsheed/dsh-file-preview#filePreview/read',
|
|
@@ -131,7 +131,7 @@ export const TYPERT_REMOTE = {
|
|
|
131
131
|
typeSymbol: '@khorsheed/dsh-file-preview/types#FilePreviewRead',
|
|
132
132
|
schema: _khorsheed_dsh_file_preview_filePreview_read_result$schema,
|
|
133
133
|
},
|
|
134
|
-
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":
|
|
134
|
+
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":458,"column":9},
|
|
135
135
|
},
|
|
136
136
|
{
|
|
137
137
|
id: '@khorsheed/dsh-file-preview#filePreview/reveal',
|
|
@@ -172,7 +172,7 @@ export const TYPERT_REMOTE = {
|
|
|
172
172
|
typeSymbol: '@khorsheed/dsh-file-preview/types#FilePreviewReveal',
|
|
173
173
|
schema: _khorsheed_dsh_file_preview_filePreview_reveal_result$schema,
|
|
174
174
|
},
|
|
175
|
-
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":
|
|
175
|
+
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":535,"column":9},
|
|
176
176
|
},
|
|
177
177
|
{
|
|
178
178
|
id: '@khorsheed/dsh-file-preview#filePreview/turnFiles',
|
|
@@ -202,7 +202,7 @@ export const TYPERT_REMOTE = {
|
|
|
202
202
|
typeSymbol: '@khorsheed/dsh-file-preview/types#FilePreviewTurnMap',
|
|
203
203
|
schema: _khorsheed_dsh_file_preview_filePreview_turnFiles_result$schema,
|
|
204
204
|
},
|
|
205
|
-
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":
|
|
205
|
+
sourceLocation: {"file":"packages/file-preview/src/index.ts","line":405,"column":9},
|
|
206
206
|
},
|
|
207
207
|
],
|
|
208
208
|
}
|
package/lib/types/bash-writes.js
CHANGED
|
@@ -305,7 +305,7 @@ export class BashWriteCollector {
|
|
|
305
305
|
#replay(session) {
|
|
306
306
|
this.#pending.set(session.id, new Map());
|
|
307
307
|
this.#captured.set(session.id, new Map());
|
|
308
|
-
for (const event of session.
|
|
308
|
+
for (const event of session.snapshotEvents())
|
|
309
309
|
this.#onEvent(session, event);
|
|
310
310
|
}
|
|
311
311
|
#onEvent(session, event) {
|
package/lib/types/fold.d.ts
CHANGED
|
@@ -26,7 +26,8 @@ export declare function diffsFromResultMeta(meta: unknown): readonly FilePreview
|
|
|
26
26
|
* first-seen order and deduplicated by display path; a later occurrence
|
|
27
27
|
* refreshes the entry's op and location without moving it, and each write/edit
|
|
28
28
|
* tool result appends its change's diff to the entry's `diffs` in event order.
|
|
29
|
-
* Nested Code Mode file dispatches (`tool/code-dispatch` events
|
|
29
|
+
* Nested Code Mode file dispatches (`tool/code-dispatch` events, or
|
|
30
|
+
* `tool/ptc-dispatch` on seats running the PTC rename) count too —
|
|
30
31
|
* they carry no turn/step of their own, so the entry borrows the enclosing
|
|
31
32
|
* root call's location.
|
|
32
33
|
* @param events - the session's events in ascending seq order.
|
|
@@ -55,11 +56,12 @@ export type TurnFilesByTurn = ReadonlyMap<number, ReadonlyMap<string, TurnFileFa
|
|
|
55
56
|
* single source of truth. Unlike {@link foldFilePreview}, this does NOT dedupe
|
|
56
57
|
* a path to its last occurrence: a file touched in two turns appears in BOTH
|
|
57
58
|
* turn maps, so each turn's card lists exactly what that turn mutated.
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
59
|
+
* Reads leave no card entry (the card is the mutation vocabulary — write/edit
|
|
60
|
+
* only), so a pure-read call never registers; write/edit calls register with
|
|
61
|
+
* their own turn; nested Code Mode dispatches borrow the enclosing root call's
|
|
62
|
+
* turn (dispatch events carry none); a `tool/result` whose presentation meta
|
|
63
|
+
* carries diffs registers its paths (the render-intent vocabulary) with the
|
|
64
|
+
* result's turn, and per-turn line deltas are summed from the diffs. A `write` whose result carries no diffs is a
|
|
63
65
|
* create (the write tool records no diffs when the file had no prior content):
|
|
64
66
|
* its full written content — read from the call arguments, which the log keeps
|
|
65
67
|
* — is the added-line count, once per file per turn.
|
package/lib/types/fold.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../../src/fold.ts"],"names":[],"mappings":"AAAA,8GAA8G;AAE9G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAG5D,OAAO,KAAK,EAAqC,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../../src/fold.ts"],"names":[],"mappings":"AAAA,8GAA8G;AAE9G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAG5D,OAAO,KAAK,EAAqC,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAiBnG,uEAAuE;AACvE,MAAM,WAAW,qBAAqB;IACpC,uCAAuC;IACvC,QAAQ,CAAC,EAAE,EAAE,aAAa,CAAA;IAC1B,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,2EAA2E;AAC3E,MAAM,MAAM,qBAAqB,GAAG;IAClC,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,4DAA4D;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,gCAAgC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB,CAAA;AAmBD,sFAAsF;AACtF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS,CAOvG;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,qBAAqB,EAAE,GAAG,SAAS,CAc/F;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,CAiElG;AAED,kGAAkG;AAClG,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI9C;AAED,8EAA8E;AAC9E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uFAAuF;IACvF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,4FAA4F;IAC5F,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,4FAA4F;AAC5F,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAA;AAuCpF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,eAAe,CAiItF"}
|
package/lib/types/fold.js
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
/** Pure log fold over the files a session read, wrote, or edited. @module @khorsheed/dsh-file-preview/fold */
|
|
2
2
|
/** Tool names whose calls record a touched file path. */
|
|
3
3
|
const FILE_TOOL_NAMES = new Set(['read', 'write', 'edit']);
|
|
4
|
+
/**
|
|
5
|
+
* Settled nested-dispatch event names, matched by name (feature detection,
|
|
6
|
+
* never a version check): `tool/code-dispatch` is the Code Mode name every
|
|
7
|
+
* host through 0.1.2-rc.1 emits; `tool/ptc-dispatch` is the PTC rename later
|
|
8
|
+
* 0.1.2 seats move to. Both carry the same settled-dispatch payload, so one
|
|
9
|
+
* branch serves either.
|
|
10
|
+
*/
|
|
11
|
+
const DISPATCH_EVENT_NAMES = new Set(['tool/code-dispatch', 'tool/ptc-dispatch']);
|
|
4
12
|
/** The argument key carrying the touched path (shared by all three file tools). */
|
|
5
13
|
const FILE_PATH_ARGUMENT = 'file_path';
|
|
6
14
|
/**
|
|
@@ -57,7 +65,8 @@ export function diffsFromResultMeta(meta) {
|
|
|
57
65
|
* first-seen order and deduplicated by display path; a later occurrence
|
|
58
66
|
* refreshes the entry's op and location without moving it, and each write/edit
|
|
59
67
|
* tool result appends its change's diff to the entry's `diffs` in event order.
|
|
60
|
-
* Nested Code Mode file dispatches (`tool/code-dispatch` events
|
|
68
|
+
* Nested Code Mode file dispatches (`tool/code-dispatch` events, or
|
|
69
|
+
* `tool/ptc-dispatch` on seats running the PTC rename) count too —
|
|
61
70
|
* they carry no turn/step of their own, so the entry borrows the enclosing
|
|
62
71
|
* root call's location.
|
|
63
72
|
* @param events - the session's events in ascending seq order.
|
|
@@ -88,16 +97,19 @@ export function foldFilePreview(events, maxFiles) {
|
|
|
88
97
|
record(target, event.seq, event.data.turn, event.data.step);
|
|
89
98
|
continue;
|
|
90
99
|
}
|
|
91
|
-
if (event.type
|
|
100
|
+
if (DISPATCH_EVENT_NAMES.has(event.type)) {
|
|
92
101
|
// The dispatch event IS the settled outcome: a failed sub-call changed
|
|
93
|
-
// nothing, so only successful file touches record.
|
|
94
|
-
|
|
102
|
+
// nothing, so only successful file touches record. The PTC rename keeps
|
|
103
|
+
// the code-dispatch payload shape (the ptc name has no SessionEventMap
|
|
104
|
+
// row yet), so the data reads through the declared constituent.
|
|
105
|
+
const dispatch = event;
|
|
106
|
+
if (dispatch.data.isError)
|
|
95
107
|
continue;
|
|
96
|
-
const target = targetFromArguments(
|
|
108
|
+
const target = targetFromArguments(dispatch.data.name, dispatch.data.arguments);
|
|
97
109
|
if (target === undefined)
|
|
98
110
|
continue;
|
|
99
|
-
const site = callSites.get(String(
|
|
100
|
-
record(target,
|
|
111
|
+
const site = callSites.get(String(dispatch.data.rootCallId)) ?? { turn: 0, step: 0 };
|
|
112
|
+
record(target, dispatch.seq, site.turn, site.step);
|
|
101
113
|
continue;
|
|
102
114
|
}
|
|
103
115
|
if (event.type === 'tool/result') {
|
|
@@ -172,11 +184,12 @@ function resultCallFacts(message) {
|
|
|
172
184
|
* single source of truth. Unlike {@link foldFilePreview}, this does NOT dedupe
|
|
173
185
|
* a path to its last occurrence: a file touched in two turns appears in BOTH
|
|
174
186
|
* turn maps, so each turn's card lists exactly what that turn mutated.
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
187
|
+
* Reads leave no card entry (the card is the mutation vocabulary — write/edit
|
|
188
|
+
* only), so a pure-read call never registers; write/edit calls register with
|
|
189
|
+
* their own turn; nested Code Mode dispatches borrow the enclosing root call's
|
|
190
|
+
* turn (dispatch events carry none); a `tool/result` whose presentation meta
|
|
191
|
+
* carries diffs registers its paths (the render-intent vocabulary) with the
|
|
192
|
+
* result's turn, and per-turn line deltas are summed from the diffs. A `write` whose result carries no diffs is a
|
|
180
193
|
* create (the write tool records no diffs when the file had no prior content):
|
|
181
194
|
* its full written content — read from the call arguments, which the log keeps
|
|
182
195
|
* — is the added-line count, once per file per turn.
|
|
@@ -257,6 +270,11 @@ export function foldFilePreviewByTurn(events) {
|
|
|
257
270
|
const target = pathFromToolCall(event.data.name, event.data.arguments);
|
|
258
271
|
if (target === undefined)
|
|
259
272
|
continue;
|
|
273
|
+
// The card's vocabulary is mutations only: a read call registers
|
|
274
|
+
// nothing (it may still anchor a nested code dispatch's location via
|
|
275
|
+
// callSites above).
|
|
276
|
+
if (target.op === 'read')
|
|
277
|
+
continue;
|
|
260
278
|
if (target.op === 'write') {
|
|
261
279
|
const content = contentFromWriteCall(event.data.arguments);
|
|
262
280
|
if (content !== undefined) {
|
|
@@ -268,19 +286,24 @@ export function foldFilePreviewByTurn(events) {
|
|
|
268
286
|
recordLocation(target.path, event.data.turn, event.seq, event.data.step);
|
|
269
287
|
continue;
|
|
270
288
|
}
|
|
271
|
-
if (event.type
|
|
289
|
+
if (DISPATCH_EVENT_NAMES.has(event.type)) {
|
|
272
290
|
// The dispatch event IS the settled outcome: a failed sub-call changed
|
|
273
291
|
// nothing, so only successful file touches record. Code Mode writes are
|
|
274
292
|
// uncountable (no result diffs reach the session), so they register the
|
|
275
|
-
// path and poison the line-count totals (unknown wins).
|
|
276
|
-
|
|
293
|
+
// path and poison the line-count totals (unknown wins). Same payload
|
|
294
|
+
// shape caveat as foldFilePreview above.
|
|
295
|
+
const dispatch = event;
|
|
296
|
+
if (dispatch.data.isError)
|
|
277
297
|
continue;
|
|
278
|
-
const target = targetFromArguments(
|
|
298
|
+
const target = targetFromArguments(dispatch.data.name, dispatch.data.arguments);
|
|
279
299
|
if (target === undefined)
|
|
280
300
|
continue;
|
|
281
|
-
|
|
301
|
+
// Reads leave no card entry here too — only mutations register.
|
|
302
|
+
if (target.op === 'read')
|
|
303
|
+
continue;
|
|
304
|
+
const site = callSites.get(String(dispatch.data.rootCallId)) ?? { turn: 0, step: 0 };
|
|
282
305
|
sessionSeen.add(target.path);
|
|
283
|
-
recordContribution(target.path, site.turn,
|
|
306
|
+
recordContribution(target.path, site.turn, dispatch.seq, site.step, undefined, undefined, true);
|
|
284
307
|
continue;
|
|
285
308
|
}
|
|
286
309
|
if (event.type === 'tool/result') {
|