@askdkc/dsh-cli 0.12.3 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/cordis.patch.yml +12 -131
  2. package/lib/types/adapter/channel/session-projection.d.ts.map +1 -1
  3. package/lib/types/adapter/channel/session-projection.js +0 -7
  4. package/lib/types/adapter/ports/channel-view.d.ts +1 -1
  5. package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
  6. package/lib/types/dsh-adapter/bundled-presets.d.ts +3 -8
  7. package/lib/types/dsh-adapter/bundled-presets.d.ts.map +1 -1
  8. package/lib/types/dsh-adapter/bundled-presets.js +5 -20
  9. package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
  10. package/lib/types/dsh-adapter/channel/binding-events.js +2 -9
  11. package/lib/types/dsh-adapter/channel/external-commands.d.ts.map +1 -1
  12. package/lib/types/dsh-adapter/channel/external-commands.js +9 -33
  13. package/lib/types/dsh-adapter/channel/local-actions.d.ts +2 -1
  14. package/lib/types/dsh-adapter/channel/local-actions.d.ts.map +1 -1
  15. package/lib/types/dsh-adapter/channel/local-actions.js +6 -2
  16. package/lib/types/dsh-adapter/channel/model-actions.js +3 -3
  17. package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -1
  18. package/lib/types/dsh-adapter/channel/model-switch.js +0 -1
  19. package/lib/types/dsh-adapter/channel/permissions.d.ts +1 -6
  20. package/lib/types/dsh-adapter/channel/permissions.d.ts.map +1 -1
  21. package/lib/types/dsh-adapter/channel/permissions.js +2 -54
  22. package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -1
  23. package/lib/types/dsh-adapter/channel/projection.js +15 -70
  24. package/lib/types/dsh-adapter/channel/session-fork.d.ts.map +1 -1
  25. package/lib/types/dsh-adapter/channel/session-fork.js +2 -5
  26. package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
  27. package/lib/types/dsh-adapter/channel/session-metadata.js +1 -4
  28. package/lib/types/dsh-adapter/channel/session-resume.js +2 -2
  29. package/lib/types/dsh-adapter/channel/session-rewind.d.ts.map +1 -1
  30. package/lib/types/dsh-adapter/channel/session-rewind.js +0 -1
  31. package/lib/types/dsh-adapter/channel/session-tree-actions.d.ts.map +1 -1
  32. package/lib/types/dsh-adapter/channel/session-tree-actions.js +1 -2
  33. package/lib/types/dsh-adapter/channel/session-tree.d.ts.map +1 -1
  34. package/lib/types/dsh-adapter/channel/session-tree.js +9 -62
  35. package/lib/types/dsh-adapter/channel/skill-catalog.js +1 -1
  36. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
  37. package/lib/types/dsh-adapter/channel/subagent-projection.js +2 -8
  38. package/lib/types/dsh-adapter/channel/transcript.d.ts +0 -16
  39. package/lib/types/dsh-adapter/channel/transcript.d.ts.map +1 -1
  40. package/lib/types/dsh-adapter/channel/transcript.js +0 -43
  41. package/lib/types/dsh-adapter/channel.js +2 -2
  42. package/lib/types/dsh-adapter/compat/index.d.ts +5 -25
  43. package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -1
  44. package/lib/types/dsh-adapter/compat/index.js +5 -25
  45. package/lib/types/dsh-adapter/compat/liveSession.d.ts +12 -23
  46. package/lib/types/dsh-adapter/compat/liveSession.d.ts.map +1 -1
  47. package/lib/types/dsh-adapter/compat/liveSession.js +15 -68
  48. package/lib/types/dsh-adapter/compat/messages.d.ts +1 -3
  49. package/lib/types/dsh-adapter/compat/messages.d.ts.map +1 -1
  50. package/lib/types/dsh-adapter/compat/messages.js +2 -10
  51. package/lib/types/dsh-adapter/compat/persistence.d.ts +2 -3
  52. package/lib/types/dsh-adapter/compat/persistence.d.ts.map +1 -1
  53. package/lib/types/dsh-adapter/compat/persistence.js +9 -14
  54. package/lib/types/dsh-adapter/compat/sessionLog.d.ts +10 -144
  55. package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -1
  56. package/lib/types/dsh-adapter/compat/sessionLog.js +45 -275
  57. package/lib/types/dsh-adapter/compat/settings.d.ts +4 -10
  58. package/lib/types/dsh-adapter/compat/settings.d.ts.map +1 -1
  59. package/lib/types/dsh-adapter/compat/settings.js +6 -23
  60. package/lib/types/dsh-adapter/compat/shell.d.ts +2 -3
  61. package/lib/types/dsh-adapter/compat/shell.d.ts.map +1 -1
  62. package/lib/types/dsh-adapter/compat/shell.js +2 -7
  63. package/lib/types/dsh-adapter/contract.d.ts +4 -34
  64. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  65. package/lib/types/dsh-adapter/contract.js +8 -83
  66. package/lib/types/dsh-adapter/packaged-presets.d.ts +0 -19
  67. package/lib/types/dsh-adapter/packaged-presets.d.ts.map +1 -1
  68. package/lib/types/dsh-adapter/packaged-presets.js +1 -83
  69. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  70. package/lib/types/dsh-adapter/plugin.js +26 -183
  71. package/lib/types/dsh-adapter/preset-resolution.d.ts +1 -22
  72. package/lib/types/dsh-adapter/preset-resolution.d.ts.map +1 -1
  73. package/lib/types/dsh-adapter/preset-resolution.js +0 -34
  74. package/lib/types/dsh-adapter/presets.d.ts +1 -4
  75. package/lib/types/dsh-adapter/presets.d.ts.map +1 -1
  76. package/lib/types/dsh-adapter/presets.js +3 -6
  77. package/lib/types/dsh-adapter/questions-answerer.d.ts +5 -43
  78. package/lib/types/dsh-adapter/questions-answerer.d.ts.map +1 -1
  79. package/lib/types/dsh-adapter/questions-answerer.js +7 -63
  80. package/lib/types/dsh-adapter/sessionTree.d.ts +0 -19
  81. package/lib/types/dsh-adapter/sessionTree.d.ts.map +1 -1
  82. package/lib/types/dsh-adapter/sessionTree.js +2 -112
  83. package/lib/types/dsh-adapter/sessions/header.d.ts +2 -2
  84. package/lib/types/dsh-adapter/sessions/header.d.ts.map +1 -1
  85. package/lib/types/dsh-adapter/sessions/header.js +2 -8
  86. package/lib/types/dsh-adapter/sessions/list.d.ts +7 -28
  87. package/lib/types/dsh-adapter/sessions/list.d.ts.map +1 -1
  88. package/lib/types/dsh-adapter/sessions/list.js +48 -103
  89. package/lib/types/dsh-adapter/sessions/store.d.ts +1 -2
  90. package/lib/types/dsh-adapter/sessions/store.d.ts.map +1 -1
  91. package/lib/types/dsh-adapter/sessions/store.js +7 -10
  92. package/lib/types/dsh-adapter/sharp.d.ts.map +1 -1
  93. package/lib/types/dsh-adapter/sharp.js +0 -1
  94. package/lib/types/dsh-adapter/subagents.d.ts +1 -2
  95. package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
  96. package/lib/types/dsh-adapter/subagents.js +1 -12
  97. package/lib/types/dsh-adapter/trajectory/aggregate.d.ts +1 -1
  98. package/lib/types/dsh-adapter/trajectory/aggregate.js +1 -1
  99. package/lib/types/dsh-adapter/trajectory/guards.d.ts +5 -22
  100. package/lib/types/dsh-adapter/trajectory/guards.d.ts.map +1 -1
  101. package/lib/types/dsh-adapter/trajectory/guards.js +5 -23
  102. package/lib/types/dsh-adapter/trajectory/projection.d.ts +5 -21
  103. package/lib/types/dsh-adapter/trajectory/projection.d.ts.map +1 -1
  104. package/lib/types/dsh-adapter/trajectory/projection.js +4 -38
  105. package/lib/types/dsh-adapter/trajectory/types.d.ts +1 -1
  106. package/lib/types/dsh-adapter/trajectory/types.d.ts.map +1 -1
  107. package/lib/types/i18n.d.ts +2 -22
  108. package/lib/types/i18n.d.ts.map +1 -1
  109. package/lib/types/i18n.js +2 -10
  110. package/lib/types/presetPrefs.d.ts +1 -3
  111. package/lib/types/presetPrefs.d.ts.map +1 -1
  112. package/lib/types/presetPrefs.js +2 -4
  113. package/lib/types/sessionHistory.d.ts +2 -0
  114. package/lib/types/sessionHistory.d.ts.map +1 -1
  115. package/lib/types/sessionHistory.js +8 -0
  116. package/node_modules/@askdkc/dsh-auth/README.ja.md +28 -9
  117. package/node_modules/@askdkc/dsh-auth/README.md +19 -8
  118. package/node_modules/@askdkc/dsh-auth/dsh-plugin.json +3 -3
  119. package/node_modules/@askdkc/dsh-auth/lib/THIRD_PARTY_NOTICES.txt +168 -0
  120. package/node_modules/@askdkc/dsh-auth/lib/abortable.d.ts +2 -0
  121. package/node_modules/@askdkc/dsh-auth/lib/abortable.js +9 -0
  122. package/node_modules/@askdkc/dsh-auth/lib/auth-contract.d.ts +66 -0
  123. package/node_modules/@askdkc/dsh-auth/lib/auth-contract.js +1 -0
  124. package/node_modules/@askdkc/dsh-auth/lib/command.js +15 -1
  125. package/node_modules/@askdkc/dsh-auth/lib/credentials.d.ts +8 -14
  126. package/node_modules/@askdkc/dsh-auth/lib/credentials.js +1 -1
  127. package/node_modules/@askdkc/dsh-auth/lib/index.d.ts +8 -28
  128. package/node_modules/@askdkc/dsh-auth/lib/index.js +67 -65
  129. package/node_modules/@askdkc/dsh-auth/lib/interaction.d.ts +5 -5
  130. package/node_modules/@askdkc/dsh-auth/lib/opencode-adapter.d.ts +37 -0
  131. package/node_modules/@askdkc/dsh-auth/lib/opencode-adapter.js +206 -0
  132. package/node_modules/@askdkc/dsh-auth/lib/opencode-catalog.d.ts +72 -0
  133. package/node_modules/@askdkc/dsh-auth/lib/opencode-catalog.js +252 -0
  134. package/node_modules/@askdkc/dsh-auth/lib/opencode-codec.d.ts +6 -0
  135. package/node_modules/@askdkc/dsh-auth/lib/opencode-codec.js +93 -0
  136. package/node_modules/@askdkc/dsh-auth/lib/opencode-owned.generated.d.ts +113 -0
  137. package/node_modules/@askdkc/dsh-auth/lib/opencode-owned.generated.js +2866 -0
  138. package/node_modules/@askdkc/dsh-auth/lib/opencode-replay.d.ts +15 -0
  139. package/node_modules/@askdkc/dsh-auth/lib/opencode-replay.js +141 -0
  140. package/node_modules/@askdkc/dsh-auth/lib/opencode-sdk.d.ts +5 -0
  141. package/node_modules/@askdkc/dsh-auth/lib/opencode-sdk.js +43465 -0
  142. package/node_modules/@askdkc/dsh-auth/lib/opencode-sdk.js.map +7 -0
  143. package/node_modules/@askdkc/dsh-auth/lib/opencode-transport.d.ts +5 -0
  144. package/node_modules/@askdkc/dsh-auth/lib/opencode-transport.js +69 -0
  145. package/node_modules/@askdkc/dsh-auth/lib/pi-routes.d.ts +32 -0
  146. package/node_modules/@askdkc/dsh-auth/lib/pi-routes.js +45 -0
  147. package/node_modules/@askdkc/dsh-auth/lib/profiles.d.ts +2 -20
  148. package/node_modules/@askdkc/dsh-auth/lib/profiles.js +6 -41
  149. package/node_modules/@askdkc/dsh-auth/lib/routes.d.ts +20 -0
  150. package/node_modules/@askdkc/dsh-auth/lib/routes.js +13 -0
  151. package/node_modules/@askdkc/dsh-auth/lib/service.d.ts +11 -2
  152. package/node_modules/@askdkc/dsh-auth/lib/service.js +26 -16
  153. package/node_modules/@askdkc/dsh-auth/package.json +26 -15
  154. package/package.json +100 -96
  155. package/lib/types/dsh-adapter/providerGuard.d.ts +0 -75
  156. package/lib/types/dsh-adapter/providerGuard.d.ts.map +0 -1
  157. package/lib/types/dsh-adapter/providerGuard.js +0 -104
  158. package/lib/types/migrationPrefs.d.ts +0 -60
  159. package/lib/types/migrationPrefs.d.ts.map +0 -1
  160. package/lib/types/migrationPrefs.js +0 -97
  161. package/node_modules/@askdkc/dsh-auth/lib/fresh-models.d.ts +0 -59
  162. package/node_modules/@askdkc/dsh-auth/lib/fresh-models.js +0 -246
  163. package/node_modules/@askdkc/dsh-auth/lib/opencode-snapshot.generated.d.ts +0 -321
  164. package/node_modules/@askdkc/dsh-auth/lib/opencode-snapshot.generated.js +0 -528
  165. package/presets/liangshen/.dsh-tui-managed.json +0 -5
@@ -1,64 +1,8 @@
1
- /**
2
- * User-question answerer compatibility.
3
- *
4
- * Legacy rc.2 exposes one global `registerProvider` seat. The 0.1.2 line removed that
5
- * API in favour of a scope-aware `user-questions/request` waterfall. Keep the
6
- * capability probe and both registration paths here so the TUI bootstrap only
7
- * consumes a small prepared-registration result.
8
- */
9
- import { decideQuestionProviderYield, incumbentQuestionProviderId, tagTuiQuestionProvider, } from './providerGuard.js';
10
- function secretRequest(request) {
11
- return request.questions.some(question => question.id === 'dsh-auth-secret');
12
- }
13
- function hasLegacyProvider(service) {
14
- return typeof service.registerProvider === 'function';
15
- }
16
- /**
17
- * Prepare the answerer against whichever upstream API the active package
18
- * exposes. The legacy path registers immediately and binds the returned
19
- * disposer to this TUI fiber. The waterfall path returns a late binder because
20
- * channel.agentId changes across `/new`, `/resume`, and rewind.
21
- *
22
- * Agentless waterfall requests are claimed deliberately: dsh-auth's `/auth`
23
- * wizard asks through the same service without an agent. Foreign-agent
24
- * requests continue to the next answerer.
25
- *
26
- * Security scope (#586): the provider-seat guard (DUPLICATE_PROVIDER probe +
27
- * private symbol check) exists ONLY on the legacy path. The waterfall has no
28
- * seat. Agent-bearing requests are scope-filtered; agentless requests such as
29
- * dsh-auth `/auth` are dispatched without a scope carrier. Under the answerer
30
- * contract, the first eligible listener that returns instead of delegating
31
- * with `next()` claims the request. Cordis waterfall is around middleware,
32
- * however: an outer listener can call `next()` and then observe, replace, or
33
- * reject the downstream result, while `{ prepend: true }` inserts a listener
34
- * at the front. Upstream exposes no supported way to discover or reserve an
35
- * exclusive claimant, so the legacy guard and its warning cannot be
36
- * reproduced here.
37
- */
38
- export function prepareQuestionAnswerer(ctx, service, answerer) {
39
- if (!hasLegacyProvider(service)) {
40
- const events = ctx;
41
- return {
42
- kind: 'waterfall',
43
- register: owner => events.on('user-questions/request', (request, next) => {
44
- if (request.agent !== undefined && String(request.agent.id) !== owner.agentId)
45
- return next();
46
- return answerer.ask(request, { redact: secretRequest(request) });
47
- }),
48
- };
49
- }
50
- const provider = { ask: request => answerer.ask(request, { redact: secretRequest(request) }) };
51
- tagTuiQuestionProvider(provider);
52
- try {
53
- ctx.effect(() => service.registerProvider(provider), 'dsh-tui.questions.legacy-provider');
54
- return { kind: 'legacy' };
55
- }
56
- catch (error) {
57
- if (error.code !== 'DUPLICATE_PROVIDER')
58
- throw error;
59
- return {
60
- kind: 'legacy',
61
- yieldDecision: decideQuestionProviderYield(incumbentQuestionProviderId(service)),
62
- };
63
- }
1
+ /** Read the mutable channel identity for every request, including after resume. */
2
+ export function registerQuestionAnswerer(ctx, owner, answerer) {
3
+ return ctx.on('user-questions/request', (request, next) => {
4
+ if (request.agent !== undefined && String(request.agent.id) !== owner.agentId)
5
+ return next();
6
+ return answerer.ask(request, { redact: request.questions.some(question => question.id === 'dsh-auth-secret') });
7
+ });
64
8
  }
@@ -87,25 +87,6 @@ export interface GutterInfo {
87
87
  position: number;
88
88
  show: boolean;
89
89
  }
90
- /**
91
- * Coalesce runs of same-type assistant/chunk deltas into single synthetic
92
- * events for REPLAY only. A streamed pre-V3 turn logs one event per token
93
- * (~100k events in long sessions); replaying them one at a time costs
94
- * per-chunk string growth on every row (quadratic in the turn's length).
95
- * Merging is outcome-identical: ensureStreaming/ensureReasoning only read
96
- * chunk.type and the concatenated text, and the row's seq comes from the
97
- * run's FIRST chunk (the fork boundary rewindToNode derives from it). Parts
98
- * join once — no quadratic concat. Live events never go through this.
99
- *
100
- * Pre-V3 durable logs only: 0.1.5 removed `assistant/chunk` from the event
101
- * union (V3 embeds the compacted stream in `assistant/message.stream`), so
102
- * the merger works on the widened structural shape — runtime payloads from
103
- * raw pre-V3 logs remain typed as SessionEvent by the reader.
104
- *
105
- * (Moved from channel.ts: the transcript replay and the tree extraction
106
- * share it.)
107
- */
108
- export declare function coalesceReplayEvents(events: readonly SessionEvent[]): SessionEvent[];
109
90
  /**
110
91
  * Fork boundary for rewinding to the entry at `seq`: the seq just before its
111
92
  * enclosing turn/start (DSH logs `turn/start → user/message → … → turn/end`,
@@ -1 +1 @@
1
- {"version":3,"file":"sessionTree.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/sessionTree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sessionTree.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/sessionTree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,SAAS,EAAiE,MAAM,qCAAqC,CAAA;AAC9J,YAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAC9J;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAG5D,wEAAwE;AACxE,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,KAAK,CAAA;AACrE,eAAO,MAAM,YAAY,EAAE,SAAS,UAAU,EAAgD,CAAA;AAE9F,wEAAwE;AACxE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B;;;mDAG+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAA;IACxC,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;IAC7B;;kEAE8D;IAC9D,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAC3B;;;;;qDAKiD;IACjD,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAChC;AAED,8EAA8E;AAC9E,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B;;;uEAGmE;IACnE,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,CAUjG;AAED,sEAAsE;AACtE,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB;;uEAEmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAA;IACd,0EAA0E;IAC1E,aAAa,EAAE,OAAO,CAAA;IACtB,mDAAmD;IACnD,MAAM,EAAE,OAAO,CAAA;IACf,6EAA6E;IAC7E,OAAO,EAAE,SAAS,UAAU,EAAE,CAAA;IAC9B,4DAA4D;IAC5D,kBAAkB,EAAE,OAAO,CAAA;IAC3B,2EAA2E;IAC3E,aAAa,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,OAAO,CAAA;CACd;AA2BD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAUjF;AAED,gEAAgE;AAChE,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,CA0BvF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,CAkBrF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,SAAS,EAAE,MAAM,GAChB,SAAS,YAAY,EAAE,CAyBzB;AAED,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAgBjF;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,EAAE,CAmH9F;AAcD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,aAAa,EAAE,MAAM,EACrB,SAAS,UAAQ,GAChB,eAAe,CAoQjB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,EAAE,CA0F/F;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,SAAS,QAAQ,EAAE,EACzB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,MAAM,GACZ,QAAQ,EAAE,CA+FZ;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,SAAS,QAAQ,EAAE,EAC5B,IAAI,EAAE,SAAS,QAAQ,EAAE,EACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB,MAAM,CAaR"}
@@ -37,63 +37,6 @@ function textOf(content) {
37
37
  function firstTextOf(content) {
38
38
  return (content ?? []).find(block => block.type === 'text')?.text?.trim() ?? '';
39
39
  }
40
- /**
41
- * Coalesce runs of same-type assistant/chunk deltas into single synthetic
42
- * events for REPLAY only. A streamed pre-V3 turn logs one event per token
43
- * (~100k events in long sessions); replaying them one at a time costs
44
- * per-chunk string growth on every row (quadratic in the turn's length).
45
- * Merging is outcome-identical: ensureStreaming/ensureReasoning only read
46
- * chunk.type and the concatenated text, and the row's seq comes from the
47
- * run's FIRST chunk (the fork boundary rewindToNode derives from it). Parts
48
- * join once — no quadratic concat. Live events never go through this.
49
- *
50
- * Pre-V3 durable logs only: 0.1.5 removed `assistant/chunk` from the event
51
- * union (V3 embeds the compacted stream in `assistant/message.stream`), so
52
- * the merger works on the widened structural shape — runtime payloads from
53
- * raw pre-V3 logs remain typed as SessionEvent by the reader.
54
- *
55
- * (Moved from channel.ts: the transcript replay and the tree extraction
56
- * share it.)
57
- */
58
- export function coalesceReplayEvents(events) {
59
- const legacyChunkDataOf = (event) => {
60
- if (event.type !== 'assistant/chunk')
61
- return undefined;
62
- const data = event.data;
63
- if (data.chunk?.type !== 'text-delta' && data.chunk?.type !== 'reasoning-delta')
64
- return undefined;
65
- return data;
66
- };
67
- const out = [];
68
- let run = null;
69
- const flush = () => {
70
- if (run === null)
71
- return;
72
- out.push({
73
- ...run.event,
74
- data: { ...run.data, chunk: { ...run.data.chunk, text: run.parts.join('') } },
75
- });
76
- run = null;
77
- };
78
- for (const event of events) {
79
- const data = legacyChunkDataOf(event);
80
- if (data !== undefined) {
81
- if (run !== null && run.data.chunk.type === data.chunk.type) {
82
- // oxlint-disable-next-line typescript/no-unnecessary-condition -- durable replay data may lack text
83
- run.parts.push(data.chunk.text ?? '');
84
- continue;
85
- }
86
- flush();
87
- // oxlint-disable-next-line typescript/no-unnecessary-condition -- durable replay data may lack text
88
- run = { event, data, parts: [data.chunk.text ?? ''] };
89
- continue;
90
- }
91
- flush();
92
- out.push(event);
93
- }
94
- flush();
95
- return out;
96
- }
97
40
  /**
98
41
  * Fork boundary for rewinding to the entry at `seq`: the seq just before its
99
42
  * enclosing turn/start (DSH logs `turn/start → user/message → … → turn/end`,
@@ -301,48 +244,14 @@ export function extractEntries(sessionId, events) {
301
244
  entries.push({ ...entry, sessionId, ...(inFirstTurn ? { firstTurn: true } : {}) });
302
245
  return entries.length - 1;
303
246
  };
304
- /** Steps with a settled assistant/message (chunk-run tentatives drop). */
305
- const seenSteps = new Set();
306
- /** stepKey → entry indices of chunk-synthesized assistant texts. One step
307
- * can yield SEVERAL runs when a non-chunk event interleaves the deltas
308
- * (coalescing flushes at the boundary) — track them all, or earlier runs
309
- * survive as ghost duplicates of the settled message. */
310
- const tentatives = new Map();
311
247
  /** callId → entry index of an unsettled tool card. */
312
248
  const openTools = new Map();
313
- /** Turns whose turn/end said aborted/interrupted. */
314
- const abortedTurns = new Set();
315
- for (const event of coalesceReplayEvents(events)) {
249
+ for (const event of events) {
316
250
  if (event.type === 'turn/start') {
317
251
  turnsSeen += 1;
318
252
  inFirstTurn = markFirstTurn && turnsSeen === 1;
319
253
  continue;
320
254
  }
321
- // Pre-V3 durable logs only: per-token chunk events predate the 0.1.5
322
- // union (V3 embeds the stream in assistant/message.stream), so they are
323
- // handled structurally outside the typed switch.
324
- if (event.type === 'assistant/chunk') {
325
- const data = event.data;
326
- if (data.chunk.type === 'text-delta') {
327
- const text = data.chunk.text ?? '';
328
- if (text.trim()) {
329
- const key = `${data.turn}:${data.step}`;
330
- const index = push({
331
- seq: event.seq,
332
- kind: 'assistant',
333
- text: preview(text),
334
- searchText: `assistant ${text}`,
335
- time: event.time,
336
- });
337
- const group = tentatives.get(key);
338
- if (group === undefined)
339
- tentatives.set(key, [index]);
340
- else
341
- group.push(index);
342
- }
343
- }
344
- continue;
345
- }
346
255
  switch (event.type) {
347
256
  case 'user/message': {
348
257
  const source = event.data.source;
@@ -372,8 +281,6 @@ export function extractEntries(sessionId, events) {
372
281
  break;
373
282
  }
374
283
  case 'assistant/message': {
375
- const { turn, step } = event.data;
376
- seenSteps.add(`${turn}:${step}`);
377
284
  const text = textOf(event.data.message.content);
378
285
  // pi hides assistant messages with only tool calls (no text).
379
286
  if (text) {
@@ -417,7 +324,6 @@ export function extractEntries(sessionId, events) {
417
324
  case 'turn/end': {
418
325
  const reason = event.data.reason;
419
326
  if (reason.kind === 'aborted' || reason.kind === 'interrupted') {
420
- abortedTurns.add(event.data.turn);
421
327
  push({ seq: event.seq, kind: 'interrupt', text: 'interrupted', searchText: 'interrupt interrupted', time: event.time });
422
328
  }
423
329
  else if (reason.kind !== 'completed') {
@@ -441,23 +347,7 @@ export function extractEntries(sessionId, events) {
441
347
  break;
442
348
  }
443
349
  }
444
- // Chunk-synthesized assistant entries lose to a settled assistant/message
445
- // for the same step; survivors of an aborted turn get the marker.
446
- const drop = new Set();
447
- for (const [key, indices] of tentatives) {
448
- if (seenSteps.has(key)) {
449
- for (const index of indices)
450
- drop.add(index);
451
- continue;
452
- }
453
- const turn = Number(key.slice(0, key.indexOf(':')));
454
- if (abortedTurns.has(turn)) {
455
- for (const index of indices) {
456
- entries[index] = { ...entries[index], label: 'aborted' };
457
- }
458
- }
459
- }
460
- return drop.size === 0 ? entries : entries.filter((_, index) => !drop.has(index));
350
+ return entries;
461
351
  }
462
352
  /** A session's title event, if it ever got one (manual /rename or auto). */
463
353
  function titleOf(events) {
@@ -31,8 +31,8 @@ export interface RawSessionHeader {
31
31
  */
32
32
  export declare function readHeader(value: unknown): RawSessionHeader | undefined;
33
33
  /**
34
- * Exact inherited prefix length from a persistence record. Accepts physical
35
- * `seedLength` or inspect `inheritedEventCount`. Never infers 0 from
34
+ * Exact inherited prefix length from a persistence record. Reads handle
35
+ * `inheritedEventCount`. Never infers 0 from
36
36
  * `isSeeded`, snapshot length, or `session/end-seed`.
37
37
  */
38
38
  export declare function readInheritedCut(value: unknown): number | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"header.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/sessions/header.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,qEAAqE;AACrE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IACtC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5C,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;CACzC;AAYD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,GAAG,SAAS,CAevE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAkBnE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,WAAW,CAY9D"}
1
+ {"version":3,"file":"header.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/sessions/header.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,qEAAqE;AACrE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IACtC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5C,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;CACzC;AAYD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,GAAG,SAAS,CAevE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAWnE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,GAAG,WAAW,CAY9D"}
@@ -32,20 +32,14 @@ export function readHeader(value) {
32
32
  };
33
33
  }
34
34
  /**
35
- * Exact inherited prefix length from a persistence record. Accepts physical
36
- * `seedLength` or inspect `inheritedEventCount`. Never infers 0 from
35
+ * Exact inherited prefix length from a persistence record. Reads handle
36
+ * `inheritedEventCount`. Never infers 0 from
37
37
  * `isSeeded`, snapshot length, or `session/end-seed`.
38
38
  */
39
39
  export function readInheritedCut(value) {
40
40
  if (value === null || typeof value !== 'object')
41
41
  return undefined;
42
42
  const record = value;
43
- const seedLength = finiteNumber(record['seedLength']);
44
- if (seedLength !== undefined &&
45
- Number.isSafeInteger(seedLength) &&
46
- seedLength >= 0 &&
47
- !Object.is(seedLength, -0))
48
- return seedLength;
49
43
  const inherited = finiteNumber(record['inheritedEventCount']);
50
44
  if (inherited !== undefined &&
51
45
  Number.isSafeInteger(inherited) &&
@@ -1,40 +1,19 @@
1
1
  import { type RawSessionHeader } from './header.js';
2
2
  import type { SessionSummary } from './types.js';
3
- /**
4
- * The slice of `ctx.sessionPersistence` this module uses.
5
- *
6
- * Structural and fully optional: the service is resolved from a running
7
- * context whose packages may be a version apart from ours, and a listing that
8
- * degrades is worth more than one that throws.
9
- */
3
+ /** Current persistence snapshots and optional artifact location for JSONL backends. */
10
4
  export interface SessionSource {
11
- /** Headers plus per-log change tokens — the contract built for this. */
12
- listSnapshots?: (signal?: AbortSignal) => Promise<readonly unknown[]>;
13
- /** Headers alone, for a backend or version without snapshots. */
14
- list?: (signal?: AbortSignal) => Promise<readonly unknown[]>;
15
- /** Absolute artifact path for one header; absent for storeless backends. */
5
+ list(options?: {
6
+ signal?: AbortSignal;
7
+ }): Promise<readonly unknown[]>;
16
8
  locate?: (meta: unknown) => unknown;
17
9
  }
18
- /** A header paired with the backend's change token, when it offered one. */
10
+ /** A header paired with the backend's authoritative change token. */
19
11
  interface Listed {
20
12
  readonly header: RawSessionHeader;
21
13
  readonly raw: unknown;
22
- readonly revision: string | undefined;
14
+ readonly revision: string;
23
15
  }
24
- /**
25
- * Enumerate stored sessions.
26
- *
27
- * Prefers `listSnapshots()` because its revision is the backend's own answer
28
- * to "has this log changed", and falls back to `list()` when the resolved
29
- * service predates it — in which case the change token is derived from the
30
- * file's own size and mtime further down. Both are honest change tokens for an
31
- * append-only log; only the authority differs.
32
- *
33
- * `list()` itself is read dual-shape: 0.1.5 folded snapshots INTO it (each
34
- * element is `{ header, revision, sizeBytes }`), while every older backend
35
- * returns bare headers — so each element is tried as a snapshot first and
36
- * then as a bare header.
37
- */
16
+ /** Enumerate current snapshots with the backend's authoritative revision. */
38
17
  export declare function enumerateSessions(source: SessionSource, signal?: AbortSignal): Promise<Listed[]>;
39
18
  /**
40
19
  * Read every stored session into a complete summary.
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/sessions/list.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAGzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAQhD;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,wEAAwE;IACxE,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,SAAS,OAAO,EAAE,CAAC,CAAA;IACrE,iEAAiE;IACjE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,SAAS,OAAO,EAAE,CAAC,CAAA;IAC5D,4EAA4E;IAC5E,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAA;CACpC;AAED,4EAA4E;AAC5E,UAAU,MAAM;IACd,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;IACjC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;CACtC;AAaD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAYtG;AAwCD;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,EACrB,MAAM,CAAC,EAAE,WAAW,EACpB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAC7C,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CA+MpC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS7B"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/sessions/list.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAGzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAQhD,uFAAuF;AACvF,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,OAAO,EAAE,CAAC,CAAA;IACrE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAA;CACpC;AAED,qEAAqE;AACrE,UAAU,MAAM;IACd,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;IACjC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAaD,6EAA6E;AAC7E,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGtG;AAmBD;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,EACrB,MAAM,CAAC,EAAE,WAAW,EACpB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAC7C,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAkMpC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS7B"}
@@ -29,7 +29,7 @@ import { readLastUsed } from '../../sessionHistory.js';
29
29
  const listingVersions = new WeakMap();
30
30
  /** Large append batches use bounded windows, then background title recovery. */
31
31
  const FOREGROUND_SUFFIX_BYTES = 2 * 1024 * 1024;
32
- /** Pull `{ header, revision }` out of one `listSnapshots()` element. */
32
+ /** Pull `{ header, revision }` out of one `list()` element. */
33
33
  function readSnapshot(value) {
34
34
  if (value === null || typeof value !== 'object')
35
35
  return undefined;
@@ -39,56 +39,14 @@ function readSnapshot(value) {
39
39
  if (header === undefined)
40
40
  return undefined;
41
41
  const revision = record['revision'];
42
- return { header, raw, revision: typeof revision === 'string' ? revision : undefined };
42
+ return typeof revision === 'string' ? { header, raw, revision } : undefined;
43
43
  }
44
- /**
45
- * Enumerate stored sessions.
46
- *
47
- * Prefers `listSnapshots()` because its revision is the backend's own answer
48
- * to "has this log changed", and falls back to `list()` when the resolved
49
- * service predates it — in which case the change token is derived from the
50
- * file's own size and mtime further down. Both are honest change tokens for an
51
- * append-only log; only the authority differs.
52
- *
53
- * `list()` itself is read dual-shape: 0.1.5 folded snapshots INTO it (each
54
- * element is `{ header, revision, sizeBytes }`), while every older backend
55
- * returns bare headers — so each element is tried as a snapshot first and
56
- * then as a bare header.
57
- */
44
+ /** Enumerate current snapshots with the backend's authoritative revision. */
58
45
  export async function enumerateSessions(source, signal) {
59
- if (typeof source.listSnapshots === 'function') {
60
- const snapshots = await source.listSnapshots(signal);
61
- return snapshots.map(readSnapshot).filter((entry) => entry !== undefined);
62
- }
63
- if (typeof source.list === 'function') {
64
- const headers = await source.list(signal);
65
- return headers
66
- .map((raw) => readSnapshot(raw) ?? bareListed(raw))
67
- .filter((entry) => entry !== undefined);
68
- }
69
- return [];
70
- }
71
- /** Pull a bare header out of one pre-0.1.5 `list()` element. */
72
- function bareListed(raw) {
73
- const header = readHeader(raw);
74
- return header === undefined ? undefined : { header, raw, revision: undefined };
46
+ const snapshots = await source.list({ signal });
47
+ return snapshots.map(readSnapshot).filter((entry) => entry !== undefined);
75
48
  }
76
- /**
77
- * Absolute artifact path for one session.
78
- *
79
- * The backend's own `locate()` is authoritative and is asked first — but
80
- * since 0.1.5 it answers the CURRENT generation's path without touching the
81
- * filesystem, which does not exist for a session still stored as an older
82
- * generation; resolve older generations inside that same directory. Only
83
- * backends without a location fall back to scanning session roots, as the
84
- * compat layer has always done (generation-aware there) and is deliberately
85
- * independent of the backend's workspace-key scheme — so a runtime whose
86
- * persistence service predates `locate`, whose key sanitization changes, or
87
- * whose current-generation path has not materialized yet still resolves.
88
- *
89
- * A backend that stores no per-session artifact (SQLite) answers neither, and
90
- * its sessions are summarized from their headers alone.
91
- */
49
+ /** Backend artifact location; file discovery also supports optional current embedders. */
92
50
  function locate(source, raw, sessionId) {
93
51
  if (typeof source.locate === 'function') {
94
52
  let location;
@@ -162,69 +120,56 @@ export async function listSummaries(source, signal, onEnriched) {
162
120
  let facts;
163
121
  let derived = cached?.derived;
164
122
  let path;
165
- if (revision !== undefined && derived?.revision === revision && derived.modifiedAt === undefined) {
166
- // Schema v3 held the same derived facts but not mtime. Upgrade that
167
- // record with one metadata read rather than re-decoding its log.
168
- path = locate(source, raw, header.id);
169
- facts = path === undefined ? undefined : fileFacts(path);
170
- derived = { ...derived, modifiedAt: facts?.modifiedAt ?? 0 };
171
- changed = true;
172
- }
173
123
  // The backend's opaque revision is authoritative. A hit does not even
174
124
  // resolve a path; incomplete titles are handled by the recovery queue.
175
- if (revision === undefined || derived === undefined || derived.revision !== revision) {
125
+ if (derived === undefined || derived.revision !== revision) {
176
126
  path = locate(source, raw, header.id);
177
127
  facts = path === undefined ? undefined : fileFacts(path);
178
- // Older persistence implementations provide no revision. Their one
179
- // metadata read per entry remains necessary to detect changes.
180
- const token = revision ?? (facts === undefined ? undefined : `${facts.bytes}:${facts.modifiedAt}`);
181
- if (token === undefined || derived?.revision !== token) {
182
- derived = undefined;
183
- if (cached?.derived !== undefined)
184
- changed = true;
185
- if (path !== undefined && token !== undefined) {
186
- const previous = cached?.derived;
187
- const appendGrowth = (facts !== undefined && previous?.identity !== undefined &&
188
- previous.identity === facts.identity && previous.anchor !== undefined &&
189
- facts.bytes > previous.bytes &&
190
- await sessionTitleAnchor(path, previous.bytes, signal) === previous.anchor);
191
- if (appendGrowth && facts !== undefined && previous !== undefined && facts.bytes - previous.bytes <= FOREGROUND_SUFFIX_BYTES) {
192
- const suffix = await digestAppendedSuffix(path, previous.bytes, facts.bytes, signal);
193
- if (suffix.complete) {
194
- derived = {
195
- revision: token,
196
- bytes: facts.bytes,
197
- modifiedAt: facts.modifiedAt,
198
- identity: facts.identity,
199
- anchor: await sessionTitleAnchor(path, facts.bytes, signal),
200
- title: suffix.title?.text ?? previous.title,
201
- titleSource: suffix.title?.source ?? previous.titleSource,
202
- titleComplete: suffix.title !== undefined || previous.titleComplete,
203
- hasPrompt: previous.hasPrompt || suffix.hasHumanPrompt,
204
- model: suffix.model ?? previous.model,
205
- label: suffix.label ?? previous.label,
206
- };
207
- }
208
- }
209
- if (derived === undefined) {
210
- const digest = digestSession(path, header.cwd ?? '');
211
- const carried = appendGrowth && digest.titleComplete !== true ? previous : undefined;
128
+ derived = undefined;
129
+ if (cached?.derived !== undefined)
130
+ changed = true;
131
+ if (path !== undefined) {
132
+ const previous = cached?.derived;
133
+ const appendGrowth = (facts !== undefined && previous?.identity !== undefined &&
134
+ previous.identity === facts.identity && previous.anchor !== undefined &&
135
+ facts.bytes > previous.bytes &&
136
+ await sessionTitleAnchor(path, previous.bytes, signal) === previous.anchor);
137
+ if (appendGrowth && facts !== undefined && previous !== undefined && facts.bytes - previous.bytes <= FOREGROUND_SUFFIX_BYTES) {
138
+ const suffix = await digestAppendedSuffix(path, previous.bytes, facts.bytes, signal);
139
+ if (suffix.complete) {
212
140
  derived = {
213
- revision: token,
214
- bytes: facts?.bytes ?? 0,
215
- modifiedAt: facts?.modifiedAt,
216
- identity: facts?.identity,
217
- anchor: facts === undefined ? undefined : await sessionTitleAnchor(path, facts.bytes, signal),
218
- title: carried?.title ?? digest.title?.text ?? '',
219
- titleSource: carried?.titleSource ?? digest.title?.source ?? 'fallback',
220
- titleComplete: digest.titleComplete === true,
221
- hasPrompt: digest.hasPrompt,
222
- model: digest.model ?? carried?.model,
223
- label: digest.label ?? carried?.label,
141
+ revision,
142
+ bytes: facts.bytes,
143
+ modifiedAt: facts.modifiedAt,
144
+ identity: facts.identity,
145
+ anchor: await sessionTitleAnchor(path, facts.bytes, signal),
146
+ title: suffix.title?.text ?? previous.title,
147
+ titleSource: suffix.title?.source ?? previous.titleSource,
148
+ titleComplete: suffix.title !== undefined || previous.titleComplete,
149
+ hasPrompt: previous.hasPrompt || suffix.hasHumanPrompt,
150
+ model: suffix.model ?? previous.model,
151
+ label: suffix.label ?? previous.label,
224
152
  };
225
153
  }
226
- changed = true;
227
154
  }
155
+ if (derived === undefined) {
156
+ const digest = digestSession(path, header.cwd ?? '');
157
+ const carried = appendGrowth && digest.titleComplete !== true ? previous : undefined;
158
+ derived = {
159
+ revision,
160
+ bytes: facts?.bytes ?? 0,
161
+ modifiedAt: facts?.modifiedAt,
162
+ identity: facts?.identity,
163
+ anchor: facts === undefined ? undefined : await sessionTitleAnchor(path, facts.bytes, signal),
164
+ title: carried?.title ?? digest.title?.text ?? '',
165
+ titleSource: carried?.titleSource ?? digest.title?.source ?? 'fallback',
166
+ titleComplete: digest.titleComplete === true,
167
+ hasPrompt: digest.hasPrompt,
168
+ model: digest.model ?? carried?.model,
169
+ label: digest.label ?? carried?.label,
170
+ };
171
+ }
172
+ changed = true;
228
173
  }
229
174
  }
230
175
  if (derived !== undefined && !derived.titleComplete && signal?.aborted !== true &&
@@ -30,8 +30,7 @@ export interface IndexEntry {
30
30
  export type SessionIndex = Map<string, IndexEntry>;
31
31
  /**
32
32
  * Load the cache.
33
- * @returns The parsed index; version 3 derivations are upgraded lazily and
34
- * version 2 retains branch notes only.
33
+ * @returns The parsed index; older schemas are discarded and rebuilt.
35
34
  */
36
35
  export declare function readIndex(): SessionIndex;
37
36
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/sessions/store.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAsB7C,mEAAmE;AACnE,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CAEnD;AAED,gDAAgD;AAChD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,wFAAwF;IACxF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,8EAA8E;IAC9E,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAED,gFAAgF;AAChF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,SAAS,CAAA;IAC1C,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC;AAED,2CAA2C;AAC3C,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AA0DlD;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,YAAY,CAoCxC;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CA0BpD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAO9E"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/sessions/store.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAoB7C,mEAAmE;AACnE,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CAEnD;AAED,gDAAgD;AAChD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,wFAAwF;IACxF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,8EAA8E;IAC9E,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAED,gFAAgF;AAChF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,SAAS,CAAA;IAC1C,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC;AAED,2CAA2C;AAC3C,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AA0DlD;;;GAGG;AACH,wBAAgB,SAAS,IAAI,YAAY,CAoCxC;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CA0BpD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAO9E"}
@@ -4,7 +4,7 @@
4
4
  * Deriving a session's title costs a bounded read; doing it for every session
5
5
  * on every picker open costs that read times the history. The persistence
6
6
  * service already hands out the exact token needed to avoid it:
7
- * `listSnapshots()` returns, per session, an opaque revision that changes
7
+ * `list()` returns, per session, an opaque revision that changes
8
8
  * whenever the stored log changes. An entry whose revision still matches is
9
9
  * reused verbatim; anything else is re-derived. Steady state is therefore zero
10
10
  * log reads, and a session edited by another client (the store is shared with
@@ -31,9 +31,7 @@ import { mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync }
31
31
  import { join } from 'node:path';
32
32
  import { DATA_DIR } from '../../utils/paths.js';
33
33
  /**
34
- * Bumped for cached mtime. Version 3 derivations remain readable and receive
35
- * that field on their next listing; version 2 could cache incomplete reads as
36
- * empty, so only its branch notes survive.
34
+ * Only the current cache schema is read; older caches are re-derived.
37
35
  */
38
36
  const SCHEMA_VERSION = 4;
39
37
  const INDEX_FILE = join(DATA_DIR, 'session-index.json');
@@ -59,12 +57,12 @@ function readTitleSource(value) {
59
57
  : undefined;
60
58
  }
61
59
  /** Narrow one persisted entry; an unrecognizable record is simply absent. */
62
- function readEntry(value, derivedValid) {
60
+ function readEntry(value) {
63
61
  if (value === null || typeof value !== 'object')
64
62
  return undefined;
65
63
  const record = value;
66
64
  const branch = typeof record['branch'] === 'string' ? record['branch'] : undefined;
67
- const raw = derivedValid ? record['derived'] : undefined;
65
+ const raw = record['derived'];
68
66
  if (raw === null || typeof raw !== 'object')
69
67
  return { derived: undefined, branch };
70
68
  const derived = raw;
@@ -108,8 +106,7 @@ function readEntry(value, derivedValid) {
108
106
  }
109
107
  /**
110
108
  * Load the cache.
111
- * @returns The parsed index; version 3 derivations are upgraded lazily and
112
- * version 2 retains branch notes only.
109
+ * @returns The parsed index; older schemas are discarded and rebuilt.
113
110
  */
114
111
  export function readIndex() {
115
112
  const stamp = indexStamp();
@@ -131,7 +128,7 @@ export function readIndex() {
131
128
  return new Map(index);
132
129
  }
133
130
  const file = parsed;
134
- if (file['version'] !== SCHEMA_VERSION && file['version'] !== 3 && file['version'] !== 2) {
131
+ if (file['version'] !== SCHEMA_VERSION) {
135
132
  loadedStamp = stamp;
136
133
  loadedIndex = index;
137
134
  return new Map(index);
@@ -143,7 +140,7 @@ export function readIndex() {
143
140
  return new Map(index);
144
141
  }
145
142
  for (const [id, value] of Object.entries(entries)) {
146
- const entry = readEntry(value, file['version'] === SCHEMA_VERSION || file['version'] === 3);
143
+ const entry = readEntry(value);
147
144
  if (entry !== undefined)
148
145
  index.set(id, entry);
149
146
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sharp.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/sharp.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;AAIpE,iEAAiE;AACjE,wBAAgB,SAAS,IAAI,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAG5D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAe9C"}
1
+ {"version":3,"file":"sharp.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/sharp.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;AAIpE,iEAAiE;AACjE,wBAAgB,SAAS,IAAI,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAG5D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAe9C"}