@earendil-works/pi-agent-core 0.85.1 → 0.86.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 (198) hide show
  1. package/README.md +16 -6
  2. package/dist/agent-loop.d.ts.map +1 -1
  3. package/dist/agent-loop.js +64 -22
  4. package/dist/agent-loop.js.map +1 -1
  5. package/dist/agent.d.ts +5 -3
  6. package/dist/agent.d.ts.map +1 -1
  7. package/dist/agent.js +15 -6
  8. package/dist/agent.js.map +1 -1
  9. package/dist/harness/config.d.ts +1 -1
  10. package/dist/harness/config.d.ts.map +1 -1
  11. package/dist/harness/config.js +10 -2
  12. package/dist/harness/config.js.map +1 -1
  13. package/dist/harness/env/nodejs.d.ts +2 -1
  14. package/dist/harness/env/nodejs.d.ts.map +1 -1
  15. package/dist/harness/env/nodejs.js +98 -27
  16. package/dist/harness/env/nodejs.js.map +1 -1
  17. package/dist/harness/execution/tools.d.ts +1 -1
  18. package/dist/harness/execution/tools.d.ts.map +1 -1
  19. package/dist/harness/execution/tools.js +0 -2
  20. package/dist/harness/execution/tools.js.map +1 -1
  21. package/dist/harness/messages.d.ts.map +1 -1
  22. package/dist/harness/messages.js +1 -0
  23. package/dist/harness/messages.js.map +1 -1
  24. package/dist/harness/pico3/bash.d.ts +10 -0
  25. package/dist/harness/pico3/bash.d.ts.map +1 -0
  26. package/dist/harness/pico3/bash.js +25 -0
  27. package/dist/harness/pico3/bash.js.map +1 -0
  28. package/dist/harness/pico3/bounded.d.ts +21 -0
  29. package/dist/harness/pico3/bounded.d.ts.map +1 -0
  30. package/dist/harness/pico3/bounded.js +98 -0
  31. package/dist/harness/pico3/bounded.js.map +1 -0
  32. package/dist/harness/pico3/chord.d.ts +41 -0
  33. package/dist/harness/pico3/chord.d.ts.map +1 -0
  34. package/dist/harness/pico3/chord.js +130 -0
  35. package/dist/harness/pico3/chord.js.map +1 -0
  36. package/dist/harness/pico3/context.d.ts +16 -0
  37. package/dist/harness/pico3/context.d.ts.map +1 -0
  38. package/dist/harness/pico3/context.js +88 -0
  39. package/dist/harness/pico3/context.js.map +1 -0
  40. package/dist/harness/pico3/harness.d.ts +197 -0
  41. package/dist/harness/pico3/harness.d.ts.map +1 -0
  42. package/dist/harness/pico3/harness.js +654 -0
  43. package/dist/harness/pico3/harness.js.map +1 -0
  44. package/dist/harness/pico3/hooks.d.ts +10 -0
  45. package/dist/harness/pico3/hooks.d.ts.map +1 -0
  46. package/dist/harness/pico3/hooks.js +33 -0
  47. package/dist/harness/pico3/hooks.js.map +1 -0
  48. package/dist/harness/pico3/index.d.ts +19 -0
  49. package/dist/harness/pico3/index.d.ts.map +1 -0
  50. package/dist/harness/pico3/index.js +15 -0
  51. package/dist/harness/pico3/index.js.map +1 -0
  52. package/dist/harness/pico3/jsonl.d.ts +58 -0
  53. package/dist/harness/pico3/jsonl.d.ts.map +1 -0
  54. package/dist/harness/pico3/jsonl.js +325 -0
  55. package/dist/harness/pico3/jsonl.js.map +1 -0
  56. package/dist/harness/pico3/kinds/collapse.d.ts +49 -0
  57. package/dist/harness/pico3/kinds/collapse.d.ts.map +1 -0
  58. package/dist/harness/pico3/kinds/collapse.js +191 -0
  59. package/dist/harness/pico3/kinds/collapse.js.map +1 -0
  60. package/dist/harness/pico3/kinds/entries.d.ts +78 -0
  61. package/dist/harness/pico3/kinds/entries.d.ts.map +1 -0
  62. package/dist/harness/pico3/kinds/entries.js +13 -0
  63. package/dist/harness/pico3/kinds/entries.js.map +1 -0
  64. package/dist/harness/pico3/kinds/frames.d.ts +9 -0
  65. package/dist/harness/pico3/kinds/frames.d.ts.map +1 -0
  66. package/dist/harness/pico3/kinds/frames.js +75 -0
  67. package/dist/harness/pico3/kinds/frames.js.map +1 -0
  68. package/dist/harness/pico3/kinds/generation.d.ts +94 -0
  69. package/dist/harness/pico3/kinds/generation.d.ts.map +1 -0
  70. package/dist/harness/pico3/kinds/generation.js +504 -0
  71. package/dist/harness/pico3/kinds/generation.js.map +1 -0
  72. package/dist/harness/pico3/kinds/job.d.ts +44 -0
  73. package/dist/harness/pico3/kinds/job.d.ts.map +1 -0
  74. package/dist/harness/pico3/kinds/job.js +143 -0
  75. package/dist/harness/pico3/kinds/job.js.map +1 -0
  76. package/dist/harness/pico3/kinds/plugin.d.ts +15 -0
  77. package/dist/harness/pico3/kinds/plugin.d.ts.map +1 -0
  78. package/dist/harness/pico3/kinds/plugin.js +35 -0
  79. package/dist/harness/pico3/kinds/plugin.js.map +1 -0
  80. package/dist/harness/pico3/kinds/post-tools.d.ts +22 -0
  81. package/dist/harness/pico3/kinds/post-tools.d.ts.map +1 -0
  82. package/dist/harness/pico3/kinds/post-tools.js +145 -0
  83. package/dist/harness/pico3/kinds/post-tools.js.map +1 -0
  84. package/dist/harness/pico3/kinds/task-api.d.ts +3 -0
  85. package/dist/harness/pico3/kinds/task-api.d.ts.map +1 -0
  86. package/dist/harness/pico3/kinds/task-api.js +45 -0
  87. package/dist/harness/pico3/kinds/task-api.js.map +1 -0
  88. package/dist/harness/pico3/kinds/tool.d.ts +43 -0
  89. package/dist/harness/pico3/kinds/tool.d.ts.map +1 -0
  90. package/dist/harness/pico3/kinds/tool.js +373 -0
  91. package/dist/harness/pico3/kinds/tool.js.map +1 -0
  92. package/dist/harness/pico3/membrane.d.ts +23 -0
  93. package/dist/harness/pico3/membrane.d.ts.map +1 -0
  94. package/dist/harness/pico3/membrane.js +141 -0
  95. package/dist/harness/pico3/membrane.js.map +1 -0
  96. package/dist/harness/pico3/memory.d.ts +53 -0
  97. package/dist/harness/pico3/memory.d.ts.map +1 -0
  98. package/dist/harness/pico3/memory.js +264 -0
  99. package/dist/harness/pico3/memory.js.map +1 -0
  100. package/dist/harness/pico3/scheduler.d.ts +46 -0
  101. package/dist/harness/pico3/scheduler.d.ts.map +1 -0
  102. package/dist/harness/pico3/scheduler.js +438 -0
  103. package/dist/harness/pico3/scheduler.js.map +1 -0
  104. package/dist/harness/pico3/session.d.ts +263 -0
  105. package/dist/harness/pico3/session.d.ts.map +1 -0
  106. package/dist/harness/pico3/session.js +1347 -0
  107. package/dist/harness/pico3/session.js.map +1 -0
  108. package/dist/harness/pico3/system.d.ts +126 -0
  109. package/dist/harness/pico3/system.d.ts.map +1 -0
  110. package/dist/harness/pico3/system.js +244 -0
  111. package/dist/harness/pico3/system.js.map +1 -0
  112. package/dist/harness/pico3/types.d.ts +973 -0
  113. package/dist/harness/pico3/types.d.ts.map +1 -0
  114. package/dist/harness/pico3/types.js +96 -0
  115. package/dist/harness/pico3/types.js.map +1 -0
  116. package/dist/harness/pico3/view.d.ts +34 -0
  117. package/dist/harness/pico3/view.d.ts.map +1 -0
  118. package/dist/harness/pico3/view.js +417 -0
  119. package/dist/harness/pico3/view.js.map +1 -0
  120. package/dist/harness/runtime/drive/boundary.d.ts.map +1 -1
  121. package/dist/harness/runtime/drive/boundary.js +6 -3
  122. package/dist/harness/runtime/drive/boundary.js.map +1 -1
  123. package/dist/harness/runtime/drive/response.d.ts.map +1 -1
  124. package/dist/harness/runtime/drive/response.js +4 -4
  125. package/dist/harness/runtime/drive/response.js.map +1 -1
  126. package/dist/harness/runtime/drive/retry.d.ts +2 -2
  127. package/dist/harness/runtime/drive/retry.d.ts.map +1 -1
  128. package/dist/harness/runtime/drive/retry.js +3 -6
  129. package/dist/harness/runtime/drive/retry.js.map +1 -1
  130. package/dist/harness/runtime/drive/structural.d.ts.map +1 -1
  131. package/dist/harness/runtime/drive/structural.js +5 -5
  132. package/dist/harness/runtime/drive/structural.js.map +1 -1
  133. package/dist/harness/runtime/drive/tool-placement.d.ts.map +1 -1
  134. package/dist/harness/runtime/drive/tool-placement.js +2 -27
  135. package/dist/harness/runtime/drive/tool-placement.js.map +1 -1
  136. package/dist/harness/runtime/drive/tools.d.ts.map +1 -1
  137. package/dist/harness/runtime/drive/tools.js.map +1 -1
  138. package/dist/harness/session/fork-policy.d.ts +20 -12
  139. package/dist/harness/session/fork-policy.d.ts.map +1 -1
  140. package/dist/harness/session/fork-policy.js +45 -12
  141. package/dist/harness/session/fork-policy.js.map +1 -1
  142. package/dist/harness/session/fork.d.ts +0 -2
  143. package/dist/harness/session/fork.d.ts.map +1 -1
  144. package/dist/harness/session/fork.js +20 -68
  145. package/dist/harness/session/fork.js.map +1 -1
  146. package/dist/harness/session/in-memory-storage-state.d.ts +5 -5
  147. package/dist/harness/session/in-memory-storage-state.d.ts.map +1 -1
  148. package/dist/harness/session/in-memory-storage-state.js +99 -39
  149. package/dist/harness/session/in-memory-storage-state.js.map +1 -1
  150. package/dist/harness/session/index.d.ts +1 -1
  151. package/dist/harness/session/index.d.ts.map +1 -1
  152. package/dist/harness/session/index.js +1 -1
  153. package/dist/harness/session/index.js.map +1 -1
  154. package/dist/harness/session/jsonl/fork.d.ts +38 -0
  155. package/dist/harness/session/jsonl/fork.d.ts.map +1 -0
  156. package/dist/harness/session/jsonl/fork.js +264 -0
  157. package/dist/harness/session/jsonl/fork.js.map +1 -0
  158. package/dist/harness/session/jsonl/io.d.ts +14 -0
  159. package/dist/harness/session/jsonl/io.d.ts.map +1 -0
  160. package/dist/harness/session/jsonl/io.js +86 -0
  161. package/dist/harness/session/jsonl/io.js.map +1 -0
  162. package/dist/harness/session/jsonl/legacy-v3.d.ts +33 -8
  163. package/dist/harness/session/jsonl/legacy-v3.d.ts.map +1 -1
  164. package/dist/harness/session/jsonl/legacy-v3.js +285 -206
  165. package/dist/harness/session/jsonl/legacy-v3.js.map +1 -1
  166. package/dist/harness/session/jsonl/repo.d.ts +2 -1
  167. package/dist/harness/session/jsonl/repo.d.ts.map +1 -1
  168. package/dist/harness/session/jsonl/repo.js +36 -20
  169. package/dist/harness/session/jsonl/repo.js.map +1 -1
  170. package/dist/harness/session/jsonl/storage.d.ts +4 -5
  171. package/dist/harness/session/jsonl/storage.d.ts.map +1 -1
  172. package/dist/harness/session/jsonl/storage.js +39 -113
  173. package/dist/harness/session/jsonl/storage.js.map +1 -1
  174. package/dist/harness/session/memory.d.ts +3 -5
  175. package/dist/harness/session/memory.d.ts.map +1 -1
  176. package/dist/harness/session/memory.js +9 -14
  177. package/dist/harness/session/memory.js.map +1 -1
  178. package/dist/harness/session/testing/conformance/session-repo.d.ts +2 -0
  179. package/dist/harness/session/testing/conformance/session-repo.d.ts.map +1 -1
  180. package/dist/harness/session/testing/conformance/session-repo.js +220 -1
  181. package/dist/harness/session/testing/conformance/session-repo.js.map +1 -1
  182. package/dist/harness/session/testing/index.d.ts +1 -1
  183. package/dist/harness/session/testing/index.d.ts.map +1 -1
  184. package/dist/harness/session/testing/index.js +1 -1
  185. package/dist/harness/session/testing/index.js.map +1 -1
  186. package/dist/harness/session/types.d.ts +1 -0
  187. package/dist/harness/session/types.d.ts.map +1 -1
  188. package/dist/harness/session/types.js.map +1 -1
  189. package/dist/harness/types.d.ts +14 -0
  190. package/dist/harness/types.d.ts.map +1 -1
  191. package/dist/harness/types.js.map +1 -1
  192. package/dist/proxy.d.ts +2 -2
  193. package/dist/proxy.d.ts.map +1 -1
  194. package/dist/proxy.js.map +1 -1
  195. package/dist/types.d.ts +30 -14
  196. package/dist/types.d.ts.map +1 -1
  197. package/dist/types.js.map +1 -1
  198. package/package.json +10 -6
@@ -1 +1 @@
1
- {"version":3,"file":"legacy-v3.js","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/legacy-v3.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent, TextContent, Usage } from \"@earendil-works/pi-ai\";\nimport { uuidv7 } from \"@earendil-works/pi-ai/utils/uuid\";\nimport type { AgentMessage, ThinkingLevel } from \"../../../types.ts\";\nimport type { Context } from \"../../context.ts\";\nimport { createBranchSummaryMessage, createCompactionSummaryMessage } from \"../../messages.ts\";\nimport type { FileSystem } from \"../../types.ts\";\nimport { addUsage, emptyUsage } from \"../../utils/usage.ts\";\nimport type { CommittedEntryWrite, CommittedValueSetWrite, CommittedWrite } from \"../commit.ts\";\nimport type { JsonValue, LaneConfiguration } from \"../types.ts\";\nimport { branchTip, entryLabel, laneConfig, laneState, sessionName } from \"../values.ts\";\nimport { type LegacyV3SessionHeader, parseJsonlSessionHeader } from \"./codec.ts\";\nimport {\n\tJSONL_FORMAT_VERSION,\n\tJSONL_STORAGE_VERSION,\n\ttype JsonlSessionMetadata,\n\ttype JsonlStorageHeader,\n} from \"./types.ts\";\n\ninterface LegacyV3EntryBase {\n\ttype: string;\n\tid: string;\n\tparentId: string | null;\n\ttimestamp: string;\n}\n\ninterface LegacyV3MessageEntry extends LegacyV3EntryBase {\n\ttype: \"message\";\n\tmessage: AgentMessage;\n}\n\ninterface LegacyV3CustomEntry extends LegacyV3EntryBase {\n\ttype: \"custom\";\n\tcustomType: string;\n\tdata?: JsonValue;\n}\n\ninterface LegacyV3CustomMessageEntry extends LegacyV3EntryBase {\n\ttype: \"custom_message\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdetails?: unknown;\n\tdisplay: boolean;\n}\n\ninterface LegacyV3BranchSummaryEntry extends LegacyV3EntryBase {\n\ttype: \"branch_summary\";\n\tfromId: string;\n\tsummary: string;\n\tdetails?: JsonValue;\n\tusage?: Usage;\n\tfromHook?: boolean;\n}\n\ninterface LegacyV3CompactionEntry extends LegacyV3EntryBase {\n\ttype: \"compaction\";\n\tsummary: string;\n\tfirstKeptEntryId: string;\n\ttokensBefore: number;\n\tdetails?: JsonValue;\n\tusage?: Usage;\n\tfromHook?: boolean;\n}\n\ninterface LegacyV3ModelChangeEntry extends LegacyV3EntryBase {\n\ttype: \"model_change\";\n\tprovider: string;\n\tmodelId: string;\n}\n\ninterface LegacyV3ThinkingLevelChangeEntry extends LegacyV3EntryBase {\n\ttype: \"thinking_level_change\";\n\tthinkingLevel: string;\n}\n\ninterface LegacyV3ActiveToolsChangeEntry extends LegacyV3EntryBase {\n\ttype: \"active_tools_change\";\n\tactiveToolNames: string[];\n}\n\ninterface LegacyV3SessionInfoEntry extends LegacyV3EntryBase {\n\ttype: \"session_info\";\n\tname?: string;\n}\n\ninterface LegacyV3LabelEntry extends LegacyV3EntryBase {\n\ttype: \"label\";\n\ttargetId: string;\n\tlabel?: string;\n}\n\ninterface ImportedCustomMessage {\n\trole: \"custom\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdetails?: unknown;\n\tdisplay: boolean;\n\ttimestamp: number;\n}\n\ntype RetainedLegacyV3Entry =\n\t| LegacyV3MessageEntry\n\t| LegacyV3CustomEntry\n\t| LegacyV3CustomMessageEntry\n\t| LegacyV3BranchSummaryEntry\n\t| LegacyV3CompactionEntry;\n\ntype DiscardedLegacyV3Entry =\n\t| LegacyV3ModelChangeEntry\n\t| LegacyV3ThinkingLevelChangeEntry\n\t| LegacyV3ActiveToolsChangeEntry\n\t| LegacyV3SessionInfoEntry\n\t| LegacyV3LabelEntry;\n\ntype LegacyV3Entry = RetainedLegacyV3Entry | DiscardedLegacyV3Entry;\n\nexport interface NormalizedLegacyV3Records {\n\twrites: CommittedWrite[];\n\timportedUsage: Usage;\n\tnextSeq: number;\n}\n\ntype JsonlSessionMetadataBase = Omit<JsonlSessionMetadata, \"path\" | \"modifiedAt\">;\n\nasync function resolveLegacyV3ParentSessionId(\n\tfileSystem: FileSystem,\n\tparentSessionPath: string,\n\tcontext: Context,\n): Promise<string | undefined> {\n\tconst lines = await fileSystem.readTextLines(parentSessionPath, { maxLines: 1 }, context);\n\tif (!lines.ok || lines.value[0] === undefined) return undefined;\n\tconst parsed = parseJsonlSessionHeader(lines.value[0]);\n\treturn parsed.ok ? parsed.value.header.id : undefined;\n}\n\nexport async function metadataFromLegacyV3Header(\n\tfileSystem: FileSystem,\n\theader: LegacyV3SessionHeader,\n\tcontext: Context,\n): Promise<JsonlSessionMetadataBase> {\n\tconst metadata: JsonlSessionMetadataBase = {\n\t\tid: header.id,\n\t\tcreatedAt: Date.parse(header.timestamp),\n\t\tstorageVersion: JSONL_STORAGE_VERSION,\n\t\tcwd: header.cwd,\n\t};\n\tif (header.parentSession !== undefined) {\n\t\tconst parentSessionId = await resolveLegacyV3ParentSessionId(fileSystem, header.parentSession, context);\n\t\tif (parentSessionId !== undefined) metadata.parentSessionId = parentSessionId;\n\t\telse metadata.legacyParentSessionPath = header.parentSession;\n\t}\n\treturn metadata;\n}\n\nexport async function normalizeLegacyV3Header(\n\tfileSystem: FileSystem,\n\theader: LegacyV3SessionHeader,\n\tcontext: Context,\n): Promise<JsonlStorageHeader> {\n\treturn {\n\t\tv: JSONL_FORMAT_VERSION,\n\t\tkind: \"header\",\n\t\t...(await metadataFromLegacyV3Header(fileSystem, header, context)),\n\t};\n}\n\nfunction parseLegacyV3Entry(line: string, lineNumber: number): LegacyV3Entry {\n\tlet entry: LegacyV3Entry;\n\ttry {\n\t\tentry = JSON.parse(line) as LegacyV3Entry;\n\t} catch (error) {\n\t\tthrow new Error(`Invalid legacy v3 JSONL record at line ${lineNumber}: not valid JSON`, { cause: error });\n\t}\n\tconst recordType: unknown = entry.type;\n\tif (\n\t\trecordType !== \"message\" &&\n\t\trecordType !== \"custom\" &&\n\t\trecordType !== \"custom_message\" &&\n\t\trecordType !== \"branch_summary\" &&\n\t\trecordType !== \"compaction\" &&\n\t\trecordType !== \"model_change\" &&\n\t\trecordType !== \"thinking_level_change\" &&\n\t\trecordType !== \"active_tools_change\" &&\n\t\trecordType !== \"session_info\" &&\n\t\trecordType !== \"label\"\n\t) {\n\t\tthrow new Error(`Unsupported legacy v3 record type at line ${lineNumber}: ${String(recordType)}`);\n\t}\n\treturn entry;\n}\n\nfunction importedCustomMessage(entry: LegacyV3CustomMessageEntry): AgentMessage {\n\tconst message: ImportedCustomMessage = {\n\t\trole: \"custom\",\n\t\tcustomType: entry.customType,\n\t\tcontent: entry.content,\n\t\tdetails: entry.details,\n\t\tdisplay: entry.display,\n\t\ttimestamp: Date.parse(entry.timestamp),\n\t};\n\t// The coding-agent CustomAgentMessages declaration merge is not visible in this package.\n\treturn message as unknown as AgentMessage;\n}\n\nfunction isRetainedEntry(entry: LegacyV3Entry): entry is RetainedLegacyV3Entry {\n\treturn (\n\t\tentry.type !== \"model_change\" &&\n\t\tentry.type !== \"thinking_level_change\" &&\n\t\tentry.type !== \"active_tools_change\" &&\n\t\tentry.type !== \"session_info\" &&\n\t\tentry.type !== \"label\"\n\t);\n}\n\nclass RetainedIdResolver {\n\t/** Caches the reminted ID of each discarded legacy node's nearest retained ancestor, or null. */\n\tprivate resolvedIds = new Map<string, string | null>();\n\tprivate entriesById: Map<string, LegacyV3Entry>;\n\tprivate remintedIds: Map<string, string>;\n\n\t/**\n\t * @param entriesById Complete inventory of legacy physical nodes, including discarded nodes.\n\t * @param remintedIds Legacy-to-current ID map containing retained nodes only.\n\t */\n\tconstructor(entriesById: Map<string, LegacyV3Entry>, remintedIds: Map<string, string>) {\n\t\tthis.entriesById = entriesById;\n\t\tthis.remintedIds = remintedIds;\n\t}\n\n\t/**\n\t * Resolve a legacy node to its reminted ID, or to its nearest retained ancestor when discarded.\n\t * Returns null when the reference is null or no retained ancestor exists.\n\t */\n\tresolve(legacyId: string | null): string | null {\n\t\tconst traversedIds: string[] = [];\n\t\tconst visitedIds = new Set<string>();\n\t\tlet currentId = legacyId;\n\t\tlet resolvedId: string | null = null;\n\n\t\twhile (currentId !== null) {\n\t\t\tconst remintedId = this.remintedIds.get(currentId);\n\t\t\tif (remintedId !== undefined) {\n\t\t\t\tresolvedId = remintedId;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (this.resolvedIds.has(currentId)) {\n\t\t\t\tresolvedId = this.resolvedIds.get(currentId) ?? null;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (visitedIds.has(currentId)) throw new Error(`Cycle in legacy v3 parent chain at entry: ${currentId}`);\n\t\t\tvisitedIds.add(currentId);\n\t\t\tconst entry = this.entriesById.get(currentId);\n\t\t\tif (entry === undefined) throw new Error(`Missing legacy v3 entry reference: ${currentId}`);\n\t\t\ttraversedIds.push(currentId);\n\t\t\tcurrentId = entry.parentId;\n\t\t}\n\n\t\tfor (const traversedId of traversedIds) this.resolvedIds.set(traversedId, resolvedId);\n\t\treturn resolvedId;\n\t}\n}\n\nfunction requireRetainedId(resolver: RetainedIdResolver, legacyId: string): string {\n\tconst importedId = resolver.resolve(legacyId);\n\tif (importedId === null) throw new Error(`Legacy v3 entry reference has no retained ancestor: ${legacyId}`);\n\treturn importedId;\n}\n\nfunction resolveBranchSummaryFromId(resolver: RetainedIdResolver, legacyFromId: string): string | null {\n\t// Legacy branchWithSummary() encoded a root source as the \"root\" sentinel instead of null.\n\treturn legacyFromId === \"root\" ? null : resolver.resolve(legacyFromId);\n}\n\nfunction projectContextMessages(entry: LegacyV3Entry, resolver: RetainedIdResolver): AgentMessage[] {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\treturn [entry.message];\n\t\tcase \"custom_message\":\n\t\t\treturn [importedCustomMessage(entry)];\n\t\tcase \"branch_summary\":\n\t\t\treturn entry.summary\n\t\t\t\t? [\n\t\t\t\t\t\tcreateBranchSummaryMessage(\n\t\t\t\t\t\t\tentry.summary,\n\t\t\t\t\t\t\tresolveBranchSummaryFromId(resolver, entry.fromId),\n\t\t\t\t\t\t\tentry.timestamp,\n\t\t\t\t\t\t),\n\t\t\t\t\t]\n\t\t\t\t: [];\n\t\tcase \"compaction\":\n\t\t\treturn [createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp)];\n\t\tcase \"custom\":\n\t\tcase \"model_change\":\n\t\tcase \"thinking_level_change\":\n\t\tcase \"active_tools_change\":\n\t\tcase \"session_info\":\n\t\tcase \"label\":\n\t\t\treturn [];\n\t}\n}\n\nfunction materializeRetainedTail(\n\tcompaction: LegacyV3CompactionEntry,\n\tentriesById: ReadonlyMap<string, LegacyV3Entry>,\n\tresolver: RetainedIdResolver,\n): AgentMessage[] {\n\tconst reversedTail: LegacyV3Entry[] = [];\n\tconst visited = new Set<string>();\n\tlet currentId = compaction.parentId;\n\twhile (currentId !== null) {\n\t\tif (visited.has(currentId)) throw new Error(`Cycle in legacy v3 parent chain at entry: ${currentId}`);\n\t\tvisited.add(currentId);\n\t\tconst entry = entriesById.get(currentId);\n\t\tif (entry === undefined) throw new Error(`Missing legacy v3 parent entry: ${currentId}`);\n\t\treversedTail.push(entry);\n\t\tif (currentId === compaction.firstKeptEntryId) {\n\t\t\treturn reversedTail.reverse().flatMap((tailEntry) => projectContextMessages(tailEntry, resolver));\n\t\t}\n\t\tcurrentId = entry.parentId;\n\t}\n\tthrow new Error(\n\t\t`Legacy v3 compaction ${compaction.id} firstKeptEntryId is not on its parent branch: ${compaction.firstKeptEntryId}`,\n\t);\n}\n\nfunction normalizeRetainedEntry(\n\tentry: RetainedLegacyV3Entry,\n\tseq: number,\n\tentriesById: ReadonlyMap<string, LegacyV3Entry>,\n\tresolver: RetainedIdResolver,\n): CommittedEntryWrite {\n\tconst committedBase = {\n\t\tkind: \"entry\" as const,\n\t\tid: requireRetainedId(resolver, entry.id),\n\t\tparentId: resolver.resolve(entry.parentId),\n\t\tseq,\n\t\ttimestamp: Date.parse(entry.timestamp),\n\t};\n\tif (entry.type === \"message\") {\n\t\treturn { ...committedBase, type: \"message\", message: entry.message };\n\t}\n\tif (entry.type === \"custom_message\") {\n\t\treturn {\n\t\t\t...committedBase,\n\t\t\ttype: \"message\",\n\t\t\tmessage: importedCustomMessage(entry),\n\t\t};\n\t}\n\tif (entry.type === \"branch_summary\") {\n\t\treturn {\n\t\t\t...committedBase,\n\t\t\ttype: \"branch_summary\",\n\t\t\tfromId: resolveBranchSummaryFromId(resolver, entry.fromId),\n\t\t\tsummary: entry.summary,\n\t\t\tdetails: entry.details,\n\t\t\tusage: entry.usage,\n\t\t\tfromHook: entry.fromHook ?? false,\n\t\t};\n\t}\n\tif (entry.type === \"compaction\") {\n\t\treturn {\n\t\t\t...committedBase,\n\t\t\ttype: \"compaction\",\n\t\t\tsummary: entry.summary,\n\t\t\tretainedTail: materializeRetainedTail(entry, entriesById, resolver),\n\t\t\ttokensBefore: entry.tokensBefore,\n\t\t\tdetails: entry.details,\n\t\t\tusage: entry.usage,\n\t\t\tfromHook: entry.fromHook ?? false,\n\t\t};\n\t}\n\treturn {\n\t\t...committedBase,\n\t\ttype: \"custom\",\n\t\tcustomType: entry.customType,\n\t\tdata: entry.data,\n\t};\n}\n\nconst THINKING_LEVELS = new Set<ThinkingLevel>([\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"]);\n\nfunction selectedConfiguration(\n\tentriesById: ReadonlyMap<string, LegacyV3Entry>,\n\tselectedId: string | null,\n): LaneConfiguration | undefined {\n\tlet model: LaneConfiguration[\"model\"] | undefined;\n\tlet thinkingLevel: ThinkingLevel | undefined;\n\tlet activeToolNames: string[] | undefined;\n\tlet sawModel = false;\n\tlet sawThinkingLevel = false;\n\tlet sawActiveToolNames = false;\n\tconst visited = new Set<string>();\n\tlet currentId = selectedId;\n\twhile (currentId !== null && (!sawModel || !sawThinkingLevel || !sawActiveToolNames)) {\n\t\tif (visited.has(currentId)) throw new Error(`Cycle in legacy v3 parent chain at entry: ${currentId}`);\n\t\tvisited.add(currentId);\n\t\tconst entry = entriesById.get(currentId);\n\t\tif (entry === undefined) throw new Error(`Missing legacy v3 entry reference: ${currentId}`);\n\t\tif (entry.type === \"model_change\" && !sawModel) {\n\t\t\tsawModel = true;\n\t\t\tif (\n\t\t\t\ttypeof entry.provider === \"string\" &&\n\t\t\t\tentry.provider.length !== 0 &&\n\t\t\t\ttypeof entry.modelId === \"string\" &&\n\t\t\t\tentry.modelId.length !== 0\n\t\t\t) {\n\t\t\t\tmodel = { provider: entry.provider, modelId: entry.modelId };\n\t\t\t}\n\t\t} else if (entry.type === \"thinking_level_change\" && !sawThinkingLevel) {\n\t\t\tsawThinkingLevel = true;\n\t\t\tif (typeof entry.thinkingLevel === \"string\" && THINKING_LEVELS.has(entry.thinkingLevel as ThinkingLevel)) {\n\t\t\t\tthinkingLevel = entry.thinkingLevel as ThinkingLevel;\n\t\t\t}\n\t\t} else if (entry.type === \"active_tools_change\" && !sawActiveToolNames) {\n\t\t\tsawActiveToolNames = true;\n\t\t\tif (Array.isArray(entry.activeToolNames) && entry.activeToolNames.every((name) => typeof name === \"string\")) {\n\t\t\t\tactiveToolNames = [...entry.activeToolNames];\n\t\t\t}\n\t\t}\n\t\tcurrentId = entry.parentId;\n\t}\n\tif (model === undefined || thinkingLevel === undefined) return undefined;\n\treturn { model, thinkingLevel, activeToolNames: activeToolNames ?? [] };\n}\n\nfunction normalizeLegacyV3Values(\n\tentries: readonly LegacyV3Entry[],\n\tentriesById: ReadonlyMap<string, LegacyV3Entry>,\n\tresolver: RetainedIdResolver,\n\tfirstSeq: number,\n): CommittedValueSetWrite[] {\n\tconst writes: CommittedValueSetWrite[] = [];\n\tlet latestSessionInfo: LegacyV3SessionInfoEntry | undefined;\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"session_info\") latestSessionInfo = entry;\n\t}\n\tif (latestSessionInfo?.name) {\n\t\twrites.push({\n\t\t\tkind: \"value\",\n\t\t\top: \"set\",\n\t\t\tseq: firstSeq + writes.length,\n\t\t\tnamespace: sessionName.namespace,\n\t\t\tkey: sessionName.key,\n\t\t\tvalue: latestSessionInfo.name,\n\t\t});\n\t}\n\n\tconst labels = new Map<string, string>();\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"label\") continue;\n\t\tconst targetId = resolver.resolve(entry.targetId);\n\t\t// Labels have no current address when their target has no retained ancestor.\n\t\tif (targetId === null) continue;\n\t\t// Legacy v3 treated both undefined and the empty string as clearing a label.\n\t\tif (entry.label) labels.set(targetId, entry.label);\n\t\telse labels.delete(targetId);\n\t}\n\tfor (const [targetId, label] of labels) {\n\t\tconst address = entryLabel(targetId);\n\t\twrites.push({\n\t\t\tkind: \"value\",\n\t\t\top: \"set\",\n\t\t\tseq: firstSeq + writes.length,\n\t\t\tnamespace: address.namespace,\n\t\t\tkey: address.key,\n\t\t\tvalue: label,\n\t\t});\n\t}\n\n\tconst finalEntry = entries.at(-1);\n\tconst tipAddress = branchTip(\"main\");\n\twrites.push({\n\t\tkind: \"value\",\n\t\top: \"set\",\n\t\tseq: firstSeq + writes.length,\n\t\tnamespace: tipAddress.namespace,\n\t\tkey: tipAddress.key,\n\t\tvalue: finalEntry === undefined ? null : resolver.resolve(finalEntry.id),\n\t});\n\tconst configuration = selectedConfiguration(entriesById, finalEntry?.id ?? null);\n\tif (configuration !== undefined) {\n\t\tconst configAddress = laneConfig(\"main\");\n\t\twrites.push({\n\t\t\tkind: \"value\",\n\t\t\top: \"set\",\n\t\t\tseq: firstSeq + writes.length,\n\t\t\tnamespace: configAddress.namespace,\n\t\t\tkey: configAddress.key,\n\t\t\tvalue: configuration,\n\t\t});\n\t\tconst stateAddress = laneState(\"main\");\n\t\twrites.push({\n\t\t\tkind: \"value\",\n\t\t\top: \"set\",\n\t\t\tseq: firstSeq + writes.length,\n\t\t\tnamespace: stateAddress.namespace,\n\t\t\tkey: stateAddress.key,\n\t\t\tvalue: { currentOperationId: null, lastOperationId: null, inbox: [] },\n\t\t});\n\t}\n\treturn writes;\n}\n\nfunction aggregateImportedUsage(entries: readonly LegacyV3Entry[]): Usage {\n\tlet aggregate = emptyUsage();\n\tfor (const entry of entries) {\n\t\tlet usage: Usage | undefined;\n\t\tif (entry.type === \"message\") {\n\t\t\tif (entry.message.role === \"assistant\") usage = entry.message.usage;\n\t\t\telse if (entry.message.role === \"toolResult\") usage = entry.message.usage;\n\t\t} else if (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\tusage = entry.usage;\n\t\t}\n\t\tif (usage !== undefined) aggregate = addUsage(aggregate, usage);\n\t}\n\treturn aggregate;\n}\n\n/** Normalize the currently supported v3 records without touching their source file. */\nexport function normalizeLegacyV3Records(recordLines: readonly string[]): NormalizedLegacyV3Records {\n\tconst entries = recordLines.map((line, index) => parseLegacyV3Entry(line, index + 2));\n\tconst entriesById = new Map<string, LegacyV3Entry>();\n\tfor (const entry of entries) {\n\t\tif (entriesById.has(entry.id)) throw new Error(`Duplicate legacy v3 entry id: ${entry.id}`);\n\t\tentriesById.set(entry.id, entry);\n\t}\n\tconst retainedEntries = entries.filter(isRetainedEntry);\n\tconst remintedIds = new Map(retainedEntries.map((entry) => [entry.id, uuidv7(Date.parse(entry.timestamp))]));\n\tconst resolver = new RetainedIdResolver(entriesById, remintedIds);\n\tconst entryWrites = retainedEntries.map((entry, index) =>\n\t\tnormalizeRetainedEntry(entry, index + 1, entriesById, resolver),\n\t);\n\tconst valueWrites = normalizeLegacyV3Values(entries, entriesById, resolver, entryWrites.length + 1);\n\tconst writes: CommittedWrite[] = [...entryWrites, ...valueWrites];\n\treturn {\n\t\twrites,\n\t\timportedUsage: aggregateImportedUsage(entries),\n\t\tnextSeq: writes.length + 1,\n\t};\n}\n"]}
1
+ {"version":3,"file":"legacy-v3.js","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/legacy-v3.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ImageContent, TextContent, Usage } from \"@earendil-works/pi-ai\";\nimport { uuidv7 } from \"@earendil-works/pi-ai/utils/uuid\";\nimport type { AgentMessage, ThinkingLevel } from \"../../../types.ts\";\nimport type { Context } from \"../../context.ts\";\nimport { createBranchSummaryMessage, createCompactionSummaryMessage } from \"../../messages.ts\";\nimport type { FileSystem, TextLineReader } from \"../../types.ts\";\nimport { addUsage, emptyUsage } from \"../../utils/usage.ts\";\nimport type { CommittedEntryWrite, CommittedValueSetWrite } from \"../commit.ts\";\nimport type { JsonValue, LaneConfiguration } from \"../types.ts\";\nimport { branchTip, entryLabel, laneConfig, laneState, sessionName, setValue } from \"../values.ts\";\nimport { type LegacyV3SessionHeader, parseJsonlSessionHeader } from \"./codec.ts\";\nimport { fileValue, readJsonlHeader } from \"./io.ts\";\nimport {\n\tJSONL_FORMAT_VERSION,\n\tJSONL_STORAGE_VERSION,\n\ttype JsonlSessionMetadata,\n\ttype JsonlStorageHeader,\n} from \"./types.ts\";\n\ninterface LegacyV3EntryBase {\n\ttype: string;\n\tid: string;\n\tparentId: string | null;\n\ttimestamp: string;\n}\n\ninterface LegacyV3MessageEntry extends LegacyV3EntryBase {\n\ttype: \"message\";\n\tmessage: AgentMessage;\n}\n\ninterface LegacyV3CustomEntry extends LegacyV3EntryBase {\n\ttype: \"custom\";\n\tcustomType: string;\n\tdata?: JsonValue;\n}\n\ninterface LegacyV3CustomMessageEntry extends LegacyV3EntryBase {\n\ttype: \"custom_message\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdetails?: unknown;\n\tdisplay: boolean;\n}\n\ninterface LegacyV3BranchSummaryEntry extends LegacyV3EntryBase {\n\ttype: \"branch_summary\";\n\tfromId: string;\n\tsummary: string;\n\tdetails?: JsonValue;\n\tusage?: Usage;\n\tfromHook?: boolean;\n}\n\ninterface LegacyV3CompactionEntry extends LegacyV3EntryBase {\n\ttype: \"compaction\";\n\tsummary: string;\n\tfirstKeptEntryId: string;\n\ttokensBefore: number;\n\tdetails?: JsonValue;\n\tusage?: Usage;\n\tfromHook?: boolean;\n}\n\ninterface LegacyV3ModelChangeEntry extends LegacyV3EntryBase {\n\ttype: \"model_change\";\n\tprovider: string;\n\tmodelId: string;\n}\n\ninterface LegacyV3ThinkingLevelChangeEntry extends LegacyV3EntryBase {\n\ttype: \"thinking_level_change\";\n\tthinkingLevel: ThinkingLevel;\n}\n\ninterface LegacyV3ActiveToolsChangeEntry extends LegacyV3EntryBase {\n\ttype: \"active_tools_change\";\n\tactiveToolNames: string[];\n}\n\ninterface LegacyV3SessionInfoEntry extends LegacyV3EntryBase {\n\ttype: \"session_info\";\n\tname?: string;\n}\n\ninterface LegacyV3LabelEntry extends LegacyV3EntryBase {\n\ttype: \"label\";\n\ttargetId: string;\n\tlabel?: string;\n}\n\ninterface ImportedCustomMessage {\n\trole: \"custom\";\n\tcustomType: string;\n\tcontent: string | (TextContent | ImageContent)[];\n\tdetails?: unknown;\n\tdisplay: boolean;\n\ttimestamp: number;\n}\n\ntype RetainedLegacyV3Entry =\n\t| LegacyV3MessageEntry\n\t| LegacyV3CustomEntry\n\t| LegacyV3CustomMessageEntry\n\t| LegacyV3BranchSummaryEntry\n\t| LegacyV3CompactionEntry;\n\ntype DiscardedLegacyV3Entry =\n\t| LegacyV3ModelChangeEntry\n\t| LegacyV3ThinkingLevelChangeEntry\n\t| LegacyV3ActiveToolsChangeEntry\n\t| LegacyV3SessionInfoEntry\n\t| LegacyV3LabelEntry;\n\ntype LegacyV3Entry = RetainedLegacyV3Entry | DiscardedLegacyV3Entry;\n\ninterface LegacyV3IndexBase {\n\tid: string;\n\tparentId: string | null;\n\t/** This node's new ID, or its parent's mapped ID when the node is discarded. */\n\tmappedId: string | null;\n}\n\ntype RetainedLegacyV3IndexEntry = LegacyV3IndexBase & { mappedId: string; seq: number } & (\n\t\t| { type: \"message\" | \"custom\" | \"custom_message\" }\n\t\t| { type: \"branch_summary\"; fromId: string }\n\t\t| { type: \"compaction\"; firstKeptEntryId: string }\n\t);\n\n/** Keep structure, labels, and configuration changes, but not conversation payloads. */\ntype LegacyV3IndexEntry =\n\t| RetainedLegacyV3IndexEntry\n\t| (LegacyV3IndexBase &\n\t\t\t(\n\t\t\t\t| Pick<LegacyV3LabelEntry, \"type\" | \"targetId\" | \"label\">\n\t\t\t\t| Pick<LegacyV3ModelChangeEntry, \"type\" | \"provider\" | \"modelId\">\n\t\t\t\t| Pick<LegacyV3ThinkingLevelChangeEntry, \"type\" | \"thinkingLevel\">\n\t\t\t\t| Pick<LegacyV3ActiveToolsChangeEntry, \"type\" | \"activeToolNames\">\n\t\t\t\t| { type: \"session_info\" }\n\t\t\t));\n\ntype LegacyV3CompactionIndexEntry = Extract<RetainedLegacyV3IndexEntry, { type: \"compaction\" }>;\n\ninterface LegacyV3Inventory {\n\tentries: ReadonlyMap<string, LegacyV3IndexEntry>;\n\timportedUsage: Usage;\n\tname: string | undefined;\n\tfinalId: string | null;\n\tnextSeq: number;\n}\n\ntype JsonlSessionMetadataBase = Omit<JsonlSessionMetadata, \"path\" | \"modifiedAt\">;\n\nasync function resolveLegacyV3ParentSessionId(\n\tfileSystem: FileSystem,\n\tparentSessionPath: string,\n\tcontext: Context,\n): Promise<string | undefined> {\n\tconst lines = await fileSystem.readTextLines(parentSessionPath, { maxLines: 1 }, context);\n\tif (!lines.ok || lines.value[0] === undefined) return undefined;\n\tconst parsed = parseJsonlSessionHeader(lines.value[0]);\n\treturn parsed.ok ? parsed.value.header.id : undefined;\n}\n\nexport async function metadataFromLegacyV3Header(\n\tfileSystem: FileSystem,\n\theader: LegacyV3SessionHeader,\n\tcontext: Context,\n): Promise<JsonlSessionMetadataBase> {\n\tconst metadata: JsonlSessionMetadataBase = {\n\t\tid: header.id,\n\t\tcreatedAt: Date.parse(header.timestamp),\n\t\tstorageVersion: JSONL_STORAGE_VERSION,\n\t\tcwd: header.cwd,\n\t};\n\tif (header.parentSession !== undefined) {\n\t\tconst parentSessionId = await resolveLegacyV3ParentSessionId(fileSystem, header.parentSession, context);\n\t\tif (parentSessionId !== undefined) metadata.parentSessionId = parentSessionId;\n\t\telse metadata.legacyParentSessionPath = header.parentSession;\n\t}\n\treturn metadata;\n}\n\nexport async function normalizeLegacyV3Header(\n\tfileSystem: FileSystem,\n\theader: LegacyV3SessionHeader,\n\tcontext: Context,\n): Promise<JsonlStorageHeader> {\n\treturn {\n\t\tv: JSONL_FORMAT_VERSION,\n\t\tkind: \"header\",\n\t\t...(await metadataFromLegacyV3Header(fileSystem, header, context)),\n\t};\n}\n\nfunction parseLegacyV3Entry(line: string): LegacyV3Entry {\n\tlet entry: LegacyV3Entry;\n\ttry {\n\t\tentry = JSON.parse(line) as LegacyV3Entry;\n\t} catch (error) {\n\t\tthrow new Error(\"Invalid legacy v3 JSONL record: not valid JSON\", { cause: error });\n\t}\n\tconst recordType: unknown = entry?.type;\n\tif (\n\t\trecordType !== \"message\" &&\n\t\trecordType !== \"custom\" &&\n\t\trecordType !== \"custom_message\" &&\n\t\trecordType !== \"branch_summary\" &&\n\t\trecordType !== \"compaction\" &&\n\t\trecordType !== \"model_change\" &&\n\t\trecordType !== \"thinking_level_change\" &&\n\t\trecordType !== \"active_tools_change\" &&\n\t\trecordType !== \"session_info\" &&\n\t\trecordType !== \"label\"\n\t) {\n\t\tthrow new Error(`Unsupported legacy v3 record type: ${String(recordType)}`);\n\t}\n\treturn entry;\n}\n\nfunction importedCustomMessage(entry: LegacyV3CustomMessageEntry): AgentMessage {\n\tconst message: ImportedCustomMessage = {\n\t\trole: \"custom\",\n\t\tcustomType: entry.customType,\n\t\tcontent: entry.content,\n\t\tdetails: entry.details,\n\t\tdisplay: entry.display,\n\t\ttimestamp: Date.parse(entry.timestamp),\n\t};\n\t// The coding-agent CustomAgentMessages declaration merge is not visible in this package.\n\treturn message as unknown as AgentMessage;\n}\n\nfunction isRetainedEntry<T extends LegacyV3Entry | LegacyV3IndexEntry>(\n\tentry: T,\n): entry is Extract<T, { type: RetainedLegacyV3Entry[\"type\"] }> {\n\treturn (\n\t\tentry.type !== \"model_change\" &&\n\t\tentry.type !== \"thinking_level_change\" &&\n\t\tentry.type !== \"active_tools_change\" &&\n\t\tentry.type !== \"session_info\" &&\n\t\tentry.type !== \"label\"\n\t);\n}\n\n/**\n * Resolve a legacy ID to its imported ID. Discarded records resolve to the minted ID of their\n * nearest retained ancestor.\n */\ntype ResolveLegacyId = (legacyId: string | null) => string | null;\n\n/** Parent mappings are already folded during the scan; later references need only a lookup. */\nfunction createLegacyIdResolver(entries: ReadonlyMap<string, LegacyV3IndexEntry>): ResolveLegacyId {\n\treturn (legacyId) => {\n\t\tif (legacyId === null) return null;\n\t\tconst mappedId = entries.get(legacyId)?.mappedId;\n\t\tif (mappedId === undefined) throw new Error(`Missing legacy v3 entry reference: ${legacyId}`);\n\t\treturn mappedId;\n\t};\n}\n\nfunction resolveBranchSummaryFromId(resolveLegacyId: ResolveLegacyId, legacyFromId: string): string | null {\n\t// Legacy branchWithSummary() encoded a root source as the \"root\" sentinel instead of null.\n\treturn legacyFromId === \"root\" ? null : resolveLegacyId(legacyFromId);\n}\n\nfunction projectContextMessage(entry: LegacyV3Entry, resolveLegacyId: ResolveLegacyId): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\treturn entry.message;\n\t\tcase \"custom_message\":\n\t\t\treturn importedCustomMessage(entry);\n\t\tcase \"branch_summary\":\n\t\t\treturn entry.summary\n\t\t\t\t? createBranchSummaryMessage(\n\t\t\t\t\t\tentry.summary,\n\t\t\t\t\t\tresolveBranchSummaryFromId(resolveLegacyId, entry.fromId),\n\t\t\t\t\t\tentry.timestamp,\n\t\t\t\t\t)\n\t\t\t\t: undefined;\n\t\tcase \"compaction\":\n\t\t\treturn createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);\n\t\tcase \"custom\":\n\t\tcase \"model_change\":\n\t\tcase \"thinking_level_change\":\n\t\tcase \"active_tools_change\":\n\t\tcase \"session_info\":\n\t\tcase \"label\":\n\t\t\treturn undefined;\n\t}\n}\n\n/** Walk physical ancestry, including discarded nodes and the exact kept boundary. */\nfunction* retainedTailStructure(\n\tcompaction: LegacyV3CompactionIndexEntry,\n\tentriesById: ReadonlyMap<string, LegacyV3IndexEntry>,\n): Iterable<LegacyV3IndexEntry> {\n\tlet currentId = compaction.parentId;\n\twhile (currentId !== null) {\n\t\t// The scan guarantees that every parent exists earlier in the file, so cycles are impossible.\n\t\tconst entry = entriesById.get(currentId)!;\n\t\tyield entry;\n\t\tif (currentId === compaction.firstKeptEntryId) return;\n\t\tcurrentId = entry.parentId;\n\t}\n\tthrow new Error(\n\t\t`Legacy v3 compaction ${compaction.id} firstKeptEntryId is not on its parent branch: ${compaction.firstKeptEntryId}`,\n\t);\n}\n\nfunction normalizeRetainedEntry(\n\tentry: RetainedLegacyV3Entry,\n\tindexed: RetainedLegacyV3IndexEntry,\n\tretainedTail: AgentMessage[],\n\tresolveLegacyId: ResolveLegacyId,\n): CommittedEntryWrite {\n\tconst committedBase = {\n\t\tkind: \"entry\" as const,\n\t\tid: indexed.mappedId,\n\t\tparentId: resolveLegacyId(indexed.parentId),\n\t\tseq: indexed.seq,\n\t\ttimestamp: Date.parse(entry.timestamp),\n\t};\n\tif (entry.type === \"message\") {\n\t\treturn { ...committedBase, type: \"message\", message: entry.message };\n\t}\n\tif (entry.type === \"custom_message\") {\n\t\treturn {\n\t\t\t...committedBase,\n\t\t\ttype: \"message\",\n\t\t\tmessage: importedCustomMessage(entry),\n\t\t};\n\t}\n\tif (entry.type === \"branch_summary\") {\n\t\treturn {\n\t\t\t...committedBase,\n\t\t\ttype: \"branch_summary\",\n\t\t\tfromId: resolveBranchSummaryFromId(resolveLegacyId, entry.fromId),\n\t\t\tsummary: entry.summary,\n\t\t\tdetails: entry.details,\n\t\t\tusage: entry.usage,\n\t\t\tfromHook: entry.fromHook ?? false,\n\t\t};\n\t}\n\tif (entry.type === \"compaction\") {\n\t\treturn {\n\t\t\t...committedBase,\n\t\t\ttype: \"compaction\",\n\t\t\tsummary: entry.summary,\n\t\t\tretainedTail,\n\t\t\ttokensBefore: entry.tokensBefore,\n\t\t\tdetails: entry.details,\n\t\t\tusage: entry.usage,\n\t\t\tfromHook: entry.fromHook ?? false,\n\t\t};\n\t}\n\treturn {\n\t\t...committedBase,\n\t\ttype: \"custom\",\n\t\tcustomType: entry.customType,\n\t\tdata: entry.data,\n\t};\n}\n\nfunction selectedConfiguration(\n\tentriesById: ReadonlyMap<string, LegacyV3IndexEntry>,\n\tselectedId: string | null,\n): LaneConfiguration | undefined {\n\tconst remaining = new Set<LegacyV3IndexEntry[\"type\"]>([\n\t\t\"model_change\",\n\t\t\"thinking_level_change\",\n\t\t\"active_tools_change\",\n\t]);\n\tlet model: LaneConfiguration[\"model\"] | undefined;\n\tlet thinkingLevel: ThinkingLevel | undefined;\n\tlet activeToolNames: string[] | undefined;\n\tlet currentId = selectedId;\n\twhile (currentId !== null && remaining.size !== 0) {\n\t\tconst entry = entriesById.get(currentId)!;\n\t\t// Consume the nearest change even when invalid: older values must not become fallbacks.\n\t\tif (remaining.delete(entry.type)) {\n\t\t\tswitch (entry.type) {\n\t\t\t\tcase \"model_change\":\n\t\t\t\t\tmodel = { provider: entry.provider, modelId: entry.modelId };\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"thinking_level_change\":\n\t\t\t\t\tthinkingLevel = entry.thinkingLevel;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"active_tools_change\":\n\t\t\t\t\tactiveToolNames = [...entry.activeToolNames];\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcurrentId = entry.parentId;\n\t}\n\tif (model === undefined || thinkingLevel === undefined) return undefined;\n\treturn { model, thinkingLevel, activeToolNames: activeToolNames ?? [] };\n}\n\nfunction indexLegacyV3Entry(\n\tentry: LegacyV3Entry,\n\tlineNumber: number,\n\tseq: number,\n\tentries: ReadonlyMap<string, LegacyV3IndexEntry>,\n): LegacyV3IndexEntry {\n\t// SessionManager appends after an existing leaf and writes extracted branches in parent order.\n\tconst mappedParentId = entry.parentId === null ? null : entries.get(entry.parentId)?.mappedId;\n\tif (mappedParentId === undefined) {\n\t\tthrow new Error(\n\t\t\t`Legacy v3 entry ${entry.id} has a missing or forward parent at line ${lineNumber}: ${entry.parentId}`,\n\t\t);\n\t}\n\tconst structure: LegacyV3IndexBase = {\n\t\tid: entry.id,\n\t\tparentId: entry.parentId,\n\t\tmappedId: mappedParentId,\n\t};\n\tif (!isRetainedEntry(entry)) {\n\t\tswitch (entry.type) {\n\t\t\tcase \"label\":\n\t\t\t\treturn { ...structure, type: entry.type, targetId: entry.targetId, label: entry.label };\n\t\t\tcase \"model_change\":\n\t\t\t\treturn { ...structure, type: entry.type, provider: entry.provider, modelId: entry.modelId };\n\t\t\tcase \"thinking_level_change\":\n\t\t\t\treturn { ...structure, type: entry.type, thinkingLevel: entry.thinkingLevel };\n\t\t\tcase \"active_tools_change\":\n\t\t\t\treturn { ...structure, type: entry.type, activeToolNames: entry.activeToolNames };\n\t\t\tcase \"session_info\":\n\t\t\t\treturn { ...structure, type: entry.type };\n\t\t}\n\t}\n\t// Null denotes the root, not a retained node identity that can be reminted.\n\tif (entry.id === null) throw new Error(\"Legacy v3 entry reference has no retained ancestor: null\");\n\tconst retained = {\n\t\t...structure,\n\t\tmappedId: uuidv7(Date.parse(entry.timestamp)),\n\t\tseq,\n\t};\n\tswitch (entry.type) {\n\t\tcase \"branch_summary\":\n\t\t\treturn { ...retained, type: entry.type, fromId: entry.fromId };\n\t\tcase \"compaction\":\n\t\t\treturn { ...retained, type: entry.type, firstKeptEntryId: entry.firstKeptEntryId };\n\t\tdefault:\n\t\t\treturn { ...retained, type: entry.type };\n\t}\n}\n\nfunction legacyEntryUsage(entry: LegacyV3Entry): Usage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\treturn entry.message.role === \"assistant\" || entry.message.role === \"toolResult\"\n\t\t\t\t? entry.message.usage\n\t\t\t\t: undefined;\n\t\tcase \"compaction\":\n\t\tcase \"branch_summary\":\n\t\t\treturn entry.usage;\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nasync function readLegacyV3Inventory(reader: TextLineReader, context: Context): Promise<LegacyV3Inventory> {\n\tconst entries = new Map<string, LegacyV3IndexEntry>();\n\tlet nextSeq = 1;\n\tlet importedUsage = emptyUsage();\n\tlet name: string | undefined;\n\tlet finalId: string | null = null;\n\twhile (true) {\n\t\tconst line = fileValue(await reader.readLine(context), \"Failed to read legacy v3 source\");\n\t\tif (line === undefined || !line.terminated) break;\n\t\tconst lineNumber = entries.size + 2;\n\t\tconst entry = parseLegacyV3Entry(line.text);\n\t\tif (entries.has(entry.id)) throw new Error(`Duplicate legacy v3 entry id: ${entry.id}`);\n\t\tconst indexed = indexLegacyV3Entry(entry, lineNumber, nextSeq, entries);\n\t\tentries.set(entry.id, indexed);\n\t\tif (isRetainedEntry(indexed)) nextSeq++;\n\t\tfinalId = entry.id;\n\t\tif (entry.type === \"session_info\") name = entry.name;\n\t\tconst usage = legacyEntryUsage(entry);\n\t\tif (usage !== undefined) importedUsage = addUsage(importedUsage, usage);\n\t}\n\treturn { entries, nextSeq, importedUsage, name, finalId };\n}\n\nfunction normalizeLegacyV3Values(inventory: LegacyV3Inventory): CommittedValueSetWrite[] {\n\tconst { entries, name, finalId } = inventory;\n\tconst resolveLegacyId = createLegacyIdResolver(entries);\n\tlet nextSeq = inventory.nextSeq;\n\tconst values: CommittedValueSetWrite[] = [];\n\n\t// session name\n\tif (name) values.push({ ...setValue(sessionName, name), seq: nextSeq++ });\n\n\t// labels\n\tconst labels = new Map<string, string>();\n\tfor (const entry of entries.values()) {\n\t\tif (entry.type !== \"label\") continue;\n\t\tconst targetId = resolveLegacyId(entry.targetId);\n\t\tif (targetId === null) continue;\n\t\tif (entry.label) labels.set(targetId, entry.label);\n\t\telse labels.delete(targetId);\n\t}\n\tfor (const [targetId, label] of labels) {\n\t\tvalues.push({ ...setValue(entryLabel(targetId), label), seq: nextSeq++ });\n\t}\n\n\t// branch tip\n\tvalues.push({ ...setValue(branchTip(\"main\"), resolveLegacyId(finalId)), seq: nextSeq++ });\n\n\t// configuration\n\tconst configuration = selectedConfiguration(entries, finalId);\n\tif (configuration !== undefined) {\n\t\tvalues.push({ ...setValue(laneConfig(\"main\"), configuration), seq: nextSeq++ });\n\t\tvalues.push({\n\t\t\t...setValue(laneState(\"main\"), { currentOperationId: null, lastOperationId: null, inbox: [] }),\n\t\t\tseq: nextSeq++,\n\t\t});\n\t}\n\treturn values;\n}\n\n/**\n * A captured legacy file exposed as repeatable logical v4 writes.\n * Each pass reopens the path; callers must not replace or edit the source between passes.\n * Structural indexes, label/configuration metadata, and derived current values survive between scans.\n */\nexport class LegacyV3Source {\n\treadonly header: JsonlStorageHeader;\n\treadonly importedUsage: Usage;\n\treadonly nextSeq: number;\n\treadonly values: readonly CommittedValueSetWrite[];\n\tprivate readonly fileSystem: FileSystem;\n\tprivate readonly path: string;\n\tprivate readonly entries: ReadonlyMap<string, LegacyV3IndexEntry>;\n\tprivate readonly resolveLegacyId: ResolveLegacyId;\n\n\tprivate constructor(\n\t\tfileSystem: FileSystem,\n\t\tpath: string,\n\t\theader: JsonlStorageHeader,\n\t\tentries: ReadonlyMap<string, LegacyV3IndexEntry>,\n\t\timportedUsage: Usage,\n\t\tvalues: readonly CommittedValueSetWrite[],\n\t\tnextSeq: number,\n\t) {\n\t\tthis.fileSystem = fileSystem;\n\t\tthis.path = path;\n\t\tthis.header = header;\n\t\tthis.entries = entries;\n\t\tthis.resolveLegacyId = createLegacyIdResolver(entries);\n\t\tthis.importedUsage = importedUsage;\n\t\tthis.values = values;\n\t\tthis.nextSeq = nextSeq;\n\t}\n\n\t/**\n\t * Scan complete v3 records without modifying the file, ignoring an unterminated final line.\n\t * Build parent mappings, assign IDs stable for this source instance, and derive current values\n\t * and imported usage. Retain metadata, not conversation payloads or an open reader. writes()\n\t * reopens the path to materialize captured records and resolve their payload-specific references.\n\t */\n\tstatic async read(fileSystem: FileSystem, path: string, context: Context): Promise<LegacyV3Source> {\n\t\tconst reader = fileValue(\n\t\t\tawait fileSystem.openTextLineReader(path, context),\n\t\t\t`Failed to open legacy v3 source ${path}`,\n\t\t);\n\t\ttry {\n\t\t\tconst parsed = await readJsonlHeader(reader, path, context);\n\t\t\tif (parsed.format !== \"v3-legacy\") {\n\t\t\t\tthrow new Error(`Invalid legacy v3 JSONL storage ${path}: expected format 3 header`);\n\t\t\t}\n\t\t\tconst inventory = await readLegacyV3Inventory(reader, context);\n\t\t\tconst values = normalizeLegacyV3Values(inventory);\n\t\t\treturn new LegacyV3Source(\n\t\t\t\tfileSystem,\n\t\t\t\tpath,\n\t\t\t\tawait normalizeLegacyV3Header(fileSystem, parsed.header, context),\n\t\t\t\tinventory.entries,\n\t\t\t\tinventory.importedUsage,\n\t\t\t\tvalues,\n\t\t\t\tinventory.nextSeq + values.length,\n\t\t\t);\n\t\t} finally {\n\t\t\tawait reader.close(context);\n\t\t}\n\t}\n\n\t*entryStructures(): Iterable<Pick<CommittedEntryWrite, \"id\" | \"parentId\" | \"seq\">> {\n\t\tfor (const entry of this.entries.values()) {\n\t\t\tif (!isRetainedEntry(entry)) continue;\n\t\t\tyield { id: entry.mappedId, parentId: this.resolveLegacyId(entry.parentId), seq: entry.seq };\n\t\t}\n\t}\n\n\ttranslateForkEntryId(legacyId: string): string {\n\t\tconst entry = this.entries.get(legacyId);\n\t\tif (entry === undefined) throw new Error(`Legacy v3 fork entry does not exist: ${legacyId}`);\n\t\tif (!isRetainedEntry(entry)) throw new Error(`Legacy v3 fork entry is not a retained entry: ${legacyId}`);\n\t\treturn entry.mappedId;\n\t}\n\n\tprivate collectRequiredTailMessageIds(isEntrySelected?: (id: string) => boolean): Set<string> {\n\t\tconst requiredIds = new Set<string>();\n\t\tfor (const entry of this.entries.values()) {\n\t\t\tif (entry.type !== \"compaction\") continue;\n\t\t\tconst compactionIsSelected = isEntrySelected === undefined || isEntrySelected(entry.mappedId);\n\t\t\tif (!compactionIsSelected) continue;\n\n\t\t\t// Walk from the compaction's parent through firstKeptEntryId, inclusive.\n\t\t\tfor (const tailEntry of retainedTailStructure(entry, this.entries)) {\n\t\t\t\tconst canProduceContextMessage = isRetainedEntry(tailEntry) && tailEntry.type !== \"custom\";\n\t\t\t\tif (canProduceContextMessage) requiredIds.add(tailEntry.id);\n\t\t\t}\n\t\t}\n\t\treturn requiredIds;\n\t}\n\n\t/**\n\t * Stream normalized v4 entries, optionally filtered by reminted ID, followed by derived current values.\n\t * Each pass owns its reader and message cache, sharing only the captured IDs and metadata.\n\t */\n\tasync *writes(\n\t\tcontext: Context,\n\t\tisEntrySelected?: (id: string) => boolean,\n\t): AsyncIterable<CommittedEntryWrite | CommittedValueSetWrite> {\n\t\tconst requiredTailMessageIds = this.collectRequiredTailMessageIds(isEntrySelected);\n\t\t// Keep needed context messages for this entire pass; tails may revisit old or shared branches.\n\t\tconst tailMessagesByLegacyId = new Map<string, AgentMessage>();\n\t\tfor await (const { entry, indexed } of this.readCapturedEntries(context)) {\n\t\t\tif (requiredTailMessageIds.has(entry.id)) {\n\t\t\t\tconst message = projectContextMessage(entry, this.resolveLegacyId);\n\t\t\t\tif (message !== undefined) tailMessagesByLegacyId.set(entry.id, message);\n\t\t\t}\n\t\t\tif (!isRetainedEntry(indexed) || !isRetainedEntry(entry)) continue;\n\t\t\tif (isEntrySelected !== undefined && !isEntrySelected(indexed.mappedId)) continue;\n\t\t\tconst retainedTail: AgentMessage[] = [];\n\t\t\tif (indexed.type === \"compaction\") {\n\t\t\t\tfor (const ancestor of retainedTailStructure(indexed, this.entries)) {\n\t\t\t\t\tconst message = tailMessagesByLegacyId.get(ancestor.id);\n\t\t\t\t\tif (message !== undefined) retainedTail.push(message);\n\t\t\t\t}\n\t\t\t\tretainedTail.reverse();\n\t\t\t}\n\t\t\tyield normalizeRetainedEntry(entry, indexed, retainedTail, this.resolveLegacyId);\n\t\t}\n\t\tyield* this.values;\n\t}\n\n\t/** Replay only the captured prefix and verify its physical identities before materialization. */\n\tprivate async *readCapturedEntries(\n\t\tcontext: Context,\n\t): AsyncIterable<{ entry: LegacyV3Entry; indexed: LegacyV3IndexEntry }> {\n\t\tconst reader = fileValue(\n\t\t\tawait this.fileSystem.openTextLineReader(this.path, context),\n\t\t\t`Failed to reopen legacy v3 source ${this.path}`,\n\t\t);\n\t\ttry {\n\t\t\tconst parsed = await readJsonlHeader(reader, this.path, context);\n\t\t\tif (\n\t\t\t\tparsed.format !== \"v3-legacy\" ||\n\t\t\t\tparsed.header.id !== this.header.id ||\n\t\t\t\tparsed.header.cwd !== this.header.cwd\n\t\t\t) {\n\t\t\t\tthrow new Error(\"Legacy v3 source header changed\");\n\t\t\t}\n\t\t\tfor (const indexed of this.entries.values()) {\n\t\t\t\tconst line = fileValue(await reader.readLine(context), \"Failed to reread legacy v3 source\");\n\t\t\t\tif (line === undefined || !line.terminated)\n\t\t\t\t\tthrow new Error(\"Legacy v3 source ended before captured entries\");\n\t\t\t\tconst entry = parseLegacyV3Entry(line.text);\n\t\t\t\tif (entry.id !== indexed.id || entry.type !== indexed.type) {\n\t\t\t\t\tthrow new Error(\"Legacy v3 source changed\");\n\t\t\t\t}\n\t\t\t\tyield { entry, indexed };\n\t\t\t}\n\t\t} finally {\n\t\t\tawait reader.close(context);\n\t\t}\n\t}\n}\n"]}
@@ -24,7 +24,8 @@ export declare class JsonlSessionRepo implements SessionRepo<JsonlSessionMetadat
24
24
  private sessionDirectory;
25
25
  private resolveNewSessionPath;
26
26
  private assertSessionIdAvailable;
27
- private loadClosedForkSourceSnapshot;
27
+ private resolveForkInput;
28
+ private isLegacyV3ForkSource;
28
29
  private publishOpenSession;
29
30
  private sessionKey;
30
31
  private loadStorage;
@@ -1 +1 @@
1
- {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/repo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAIhD,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAIrE,OAAO,EAGN,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAE5B,MAAM,YAAY,CAAC;AA+BpB,yDAAyD;AACzD,qBAAa,gBACZ,YAAW,WAAW,CAAC,oBAAoB,EAAE,yBAAyB,EAAE,uBAAuB,CAAC;IAEhG,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmC;IAChE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAA4B;IAEhD,YAAY,OAAO,EAAE,uBAAuB,EAI3C;IAEK,MAAM,CAAC,OAAO,EAAE,yBAAyB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CA8BzG;IAEK,IAAI,CAAC,QAAQ,EAAE,oBAAoB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAYnG;IAEK,IAAI,CAAC,OAAO,EAAE,uBAAuB,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAoB1G;IAEK,MAAM,CAAC,QAAQ,EAAE,oBAAoB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAa5E;IAEK,IAAI,CACT,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CA2CxC;IAED,KAAK,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAMtC;YAEa,wBAAwB;YAcxB,aAAa;YAwBb,mBAAmB;YAenB,kBAAkB;YAMlB,gBAAgB;YAOhB,qBAAqB;YAarB,wBAAwB;YAcxB,4BAA4B;IAY1C,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,UAAU;YAIJ,WAAW;IA4BzB,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,UAAU;CAGlB","sourcesContent":["import { uuidv7 } from \"@earendil-works/pi-ai/utils/uuid\";\nimport type { Context } from \"../../context.ts\";\nimport type { FileError, FileInfo, FileSystem, Result } from \"../../types.ts\";\nimport { createForkSnapshot, type ForkSourceSnapshot } from \"../fork.ts\";\nimport { StorageBackedSession } from \"../session.ts\";\nimport type { ForkOptions, Session, SessionRepo } from \"../types.ts\";\nimport { parseJsonlSessionHeader } from \"./codec.ts\";\nimport { metadataFromLegacyV3Header } from \"./legacy-v3.ts\";\nimport { JsonlStorage } from \"./storage.ts\";\nimport {\n\tJSONL_FORMAT_VERSION,\n\tJSONL_STORAGE_VERSION,\n\ttype JsonlSessionCreateOptions,\n\ttype JsonlSessionListOptions,\n\ttype JsonlSessionMetadata,\n\ttype JsonlSessionRepoOptions,\n\ttype JsonlStorageHeader,\n} from \"./types.ts\";\n\nfunction fileValue<T>(result: Result<T, FileError>, action: string): T {\n\tif (!result.ok) throw new Error(`${action}: ${result.error.message}`, { cause: result.error });\n\treturn result.value;\n}\n\nfunction metadataFromHeader(header: JsonlStorageHeader, path: string, modifiedAt: number): JsonlSessionMetadata {\n\treturn {\n\t\tid: header.id,\n\t\tcreatedAt: header.createdAt,\n\t\tstorageVersion: header.storageVersion,\n\t\tcwd: header.cwd,\n\t\tpath,\n\t\tmodifiedAt,\n\t\t...(header.parentSessionId === undefined ? {} : { parentSessionId: header.parentSessionId }),\n\t\t...(header.legacyParentSessionPath === undefined\n\t\t\t? {}\n\t\t\t: { legacyParentSessionPath: header.legacyParentSessionPath }),\n\t};\n}\n\nfunction sessionDirectoryName(cwd: string): string {\n\treturn `--${cwd.replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n}\n\nfunction sessionFileName(createdAt: number, id: string): string {\n\tconst timestamp = new Date(createdAt).toISOString().replace(/[:.]/g, \"-\");\n\treturn `${timestamp}_${encodeURIComponent(id)}.jsonl`;\n}\n\n/** File-backed format-4 session repository lifecycle. */\nexport class JsonlSessionRepo\n\timplements SessionRepo<JsonlSessionMetadata, JsonlSessionCreateOptions, JsonlSessionListOptions>\n{\n\tprivate readonly fileSystem: FileSystem;\n\tprivate readonly sessionsRootInput: string;\n\tprivate readonly now: () => number;\n\tprivate readonly openSessions = new Map<string, JsonlStorage>();\n\tprivate readonly pendingCreates = new Set<string>();\n\tprivate closed = false;\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(options: JsonlSessionRepoOptions) {\n\t\tthis.fileSystem = options.fileSystem;\n\t\tthis.sessionsRootInput = options.sessionsRoot;\n\t\tthis.now = options.now ?? Date.now;\n\t}\n\n\tasync create(options: JsonlSessionCreateOptions, context: Context): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst createdAt = this.now();\n\t\tconst { cwd, id } = await this.resolveCreateDestination(options.cwd, options.id, createdAt, context);\n\t\tconst key = this.sessionKey(cwd, id);\n\t\tif (this.openSessions.has(key) || this.pendingCreates.has(key)) throw new Error(`Session already exists: ${id}`);\n\t\tthis.pendingCreates.add(key);\n\t\tlet path: string | undefined;\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tpath = await this.resolveNewSessionPath(cwd, createdAt, id, context);\n\t\t\tconst header: JsonlStorageHeader = {\n\t\t\t\tv: JSONL_FORMAT_VERSION,\n\t\t\t\tkind: \"header\",\n\t\t\t\tid,\n\t\t\t\tstorageVersion: JSONL_STORAGE_VERSION,\n\t\t\t\tcreatedAt,\n\t\t\t\tcwd,\n\t\t\t\t...(options.parentSessionId === undefined ? {} : { parentSessionId: options.parentSessionId }),\n\t\t\t};\n\t\t\tstorage = await JsonlStorage.create({ fileSystem: this.fileSystem, path, now: this.now }, header, [], context);\n\t\t\tconst info = fileValue(await this.fileSystem.fileInfo(path, context), `Failed to read session ${path}`);\n\t\t\treturn this.publishOpenSession(metadataFromHeader(header, path, info.mtimeMs), storage, key);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context).catch(() => undefined);\n\t\t\tif (path !== undefined) await this.fileSystem.remove(path, { force: true }, context);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingCreates.delete(key);\n\t\t}\n\t}\n\n\tasync open(metadata: JsonlSessionMetadata, context: Context): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst key = this.sessionKey(metadata.cwd, metadata.id);\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is already open: ${metadata.id}`);\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tstorage = await this.loadStorage(metadata, context);\n\t\t\treturn this.publishOpenSession(metadata, storage, key);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync list(options: JsonlSessionListOptions | undefined, context: Context): Promise<JsonlSessionMetadata[]> {\n\t\toptions ??= {};\n\t\tthis.assertOpen();\n\t\tconst cwd =\n\t\t\toptions.cwd === undefined\n\t\t\t\t? undefined\n\t\t\t\t: fileValue(\n\t\t\t\t\t\tawait this.fileSystem.absolutePath(options.cwd, context),\n\t\t\t\t\t\t`Failed to resolve session cwd ${options.cwd}`,\n\t\t\t\t\t);\n\t\tconst root = await this.root(context);\n\t\tif (!fileValue(await this.fileSystem.exists(root, context), `Failed to check sessions root ${root}`)) return [];\n\t\tconst directories =\n\t\t\tcwd === undefined ? await this.sessionDirectories(root, context) : [await this.sessionDirectory(cwd, context)];\n\t\tconst metadata: JsonlSessionMetadata[] = [];\n\t\tfor (const directory of directories) metadata.push(...(await this.listDirectory(directory, cwd, context)));\n\t\treturn metadata.sort(\n\t\t\t(left, right) =>\n\t\t\t\tright.createdAt - left.createdAt || left.id.localeCompare(right.id) || left.cwd.localeCompare(right.cwd),\n\t\t);\n\t}\n\n\tasync delete(metadata: JsonlSessionMetadata, context: Context): Promise<void> {\n\t\tthis.assertOpen();\n\t\tconst key = this.sessionKey(metadata.cwd, metadata.id);\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is open: ${metadata.id}`);\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(metadata.path, context), `Failed to check session ${metadata.path}`)\n\t\t) {\n\t\t\tthrow new Error(`Session file does not exist: ${metadata.path}`);\n\t\t}\n\t\tfileValue(\n\t\t\tawait this.fileSystem.remove(metadata.path, undefined, context),\n\t\t\t`Failed to delete session ${metadata.path}`,\n\t\t);\n\t}\n\n\tasync fork(\n\t\tsource: JsonlSessionMetadata,\n\t\toptions: ForkOptions,\n\t\tcontext: Context,\n\t): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst createdAt = this.now();\n\t\tconst sourceStorage = this.openSessions.get(this.sessionKey(source.cwd, source.id));\n\t\tconst sourceSnapshot = await (sourceStorage === undefined\n\t\t\t? this.loadClosedForkSourceSnapshot(source, context)\n\t\t\t: sourceStorage.captureForkSource(context));\n\t\tconst { cwd, id } = await this.resolveCreateDestination(source.cwd, options.id, createdAt, context);\n\t\tconst destinationKey = this.sessionKey(cwd, id);\n\t\tif (this.openSessions.has(destinationKey) || this.pendingCreates.has(destinationKey)) {\n\t\t\tthrow new Error(`Session already exists: ${id}`);\n\t\t}\n\t\tthis.pendingCreates.add(destinationKey);\n\n\t\tlet path: string | undefined;\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tpath = await this.resolveNewSessionPath(cwd, createdAt, id, context);\n\t\t\tconst snapshot = createForkSnapshot(sourceSnapshot, options);\n\t\t\tconst header: JsonlStorageHeader = {\n\t\t\t\tv: JSONL_FORMAT_VERSION,\n\t\t\t\tkind: \"header\",\n\t\t\t\tid,\n\t\t\t\tstorageVersion: JSONL_STORAGE_VERSION,\n\t\t\t\tcreatedAt,\n\t\t\t\tcwd,\n\t\t\t\tparentSessionId: source.id,\n\t\t\t};\n\t\t\tstorage = await JsonlStorage.createFromForkSnapshot(\n\t\t\t\t{ fileSystem: this.fileSystem, path, now: this.now },\n\t\t\t\theader,\n\t\t\t\tsnapshot,\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tconst info = fileValue(await this.fileSystem.fileInfo(path, context), `Failed to read session ${path}`);\n\t\t\treturn this.publishOpenSession(metadataFromHeader(header, path, info.mtimeMs), storage, destinationKey);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context).catch(() => undefined);\n\t\t\tif (path !== undefined) await this.fileSystem.remove(path, { force: true }, context);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingCreates.delete(destinationKey);\n\t\t}\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.closed = true;\n\t\t// TODO: Define ownership semantics before deciding whether repository close should close session handles.\n\t\tthis.closePromise = Promise.resolve();\n\t\treturn this.closePromise;\n\t}\n\n\tprivate async resolveCreateDestination(\n\t\tcwdInput: string,\n\t\tid: string | undefined,\n\t\tcreatedAt: number,\n\t\tcontext: Context,\n\t): Promise<{ cwd: string; id: string }> {\n\t\tconst destinationId = id ?? uuidv7(createdAt);\n\t\tconst cwd = fileValue(\n\t\t\tawait this.fileSystem.absolutePath(cwdInput, context),\n\t\t\t`Failed to resolve session cwd ${cwdInput}`,\n\t\t);\n\t\treturn { cwd, id: destinationId };\n\t}\n\n\tprivate async listDirectory(\n\t\tdirectory: string,\n\t\tcwd: string | undefined,\n\t\tcontext: Context,\n\t): Promise<JsonlSessionMetadata[]> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(directory, context), `Failed to check sessions directory ${directory}`)\n\t\t) {\n\t\t\treturn [];\n\t\t}\n\t\tconst files = fileValue(\n\t\t\tawait this.fileSystem.listDir(directory, context),\n\t\t\t`Failed to list sessions directory ${directory}`,\n\t\t).filter((file) => file.kind !== \"directory\" && file.name.endsWith(\".jsonl\"));\n\t\tconst metadata: JsonlSessionMetadata[] = [];\n\t\tfor (const file of files) {\n\t\t\tconst discovered = await this.readSessionMetadata(file, context);\n\t\t\tif (discovered === undefined) continue;\n\t\t\t// Directory encoding is lossy: /a/b and /a-b both map to --a-b--.\n\t\t\tif (cwd === undefined || discovered.cwd === cwd) metadata.push(discovered);\n\t\t}\n\t\treturn metadata;\n\t}\n\n\tprivate async readSessionMetadata(file: FileInfo, context: Context): Promise<JsonlSessionMetadata | undefined> {\n\t\tconst lines = fileValue(\n\t\t\tawait this.fileSystem.readTextLines(file.path, { maxLines: 1 }, context),\n\t\t\t`Failed to read session header ${file.path}`,\n\t\t);\n\t\tif (lines[0] === undefined) return undefined;\n\t\tconst parsedHeader = parseJsonlSessionHeader(lines[0]);\n\t\tif (!parsedHeader.ok) return undefined;\n\t\tif (parsedHeader.value.format === \"v3-legacy\") {\n\t\t\tconst metadata = await metadataFromLegacyV3Header(this.fileSystem, parsedHeader.value.header, context);\n\t\t\treturn { ...metadata, path: file.path, modifiedAt: file.mtimeMs };\n\t\t}\n\t\treturn metadataFromHeader(parsedHeader.value.header, file.path, file.mtimeMs);\n\t}\n\n\tprivate async sessionDirectories(root: string, context: Context): Promise<string[]> {\n\t\treturn fileValue(await this.fileSystem.listDir(root, context), `Failed to list sessions root ${root}`)\n\t\t\t.filter((entry) => entry.kind === \"directory\")\n\t\t\t.map((entry) => entry.path);\n\t}\n\n\tprivate async sessionDirectory(cwd: string, context: Context): Promise<string> {\n\t\treturn fileValue(\n\t\t\tawait this.fileSystem.joinPath([await this.root(context), sessionDirectoryName(cwd)], context),\n\t\t\t`Failed to resolve sessions directory for ${cwd}`,\n\t\t);\n\t}\n\n\tprivate async resolveNewSessionPath(cwd: string, createdAt: number, id: string, context: Context): Promise<string> {\n\t\tconst directory = await this.sessionDirectory(cwd, context);\n\t\tawait this.assertSessionIdAvailable(directory, id, context);\n\t\tfileValue(\n\t\t\tawait this.fileSystem.createDir(directory, undefined, context),\n\t\t\t`Failed to create sessions directory ${directory}`,\n\t\t);\n\t\treturn fileValue(\n\t\t\tawait this.fileSystem.joinPath([directory, sessionFileName(createdAt, id)], context),\n\t\t\t`Failed to resolve path for session ${id}`,\n\t\t);\n\t}\n\n\tprivate async assertSessionIdAvailable(directory: string, id: string, context: Context): Promise<void> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(directory, context), `Failed to check sessions directory ${directory}`)\n\t\t)\n\t\t\treturn;\n\n\t\tconst suffix = `_${encodeURIComponent(id)}.jsonl`;\n\t\tconst idExists = fileValue(\n\t\t\tawait this.fileSystem.listDir(directory, context),\n\t\t\t`Failed to list sessions directory ${directory}`,\n\t\t).some((entry) => entry.kind !== \"directory\" && entry.name.endsWith(suffix));\n\t\tif (idExists) throw new Error(`Session already exists: ${id}`);\n\t}\n\n\tprivate async loadClosedForkSourceSnapshot(\n\t\tsource: JsonlSessionMetadata,\n\t\tcontext: Context,\n\t): Promise<ForkSourceSnapshot> {\n\t\tconst storage = await this.loadStorage(source, context);\n\t\ttry {\n\t\t\treturn await storage.captureForkSource(context);\n\t\t} finally {\n\t\t\tawait storage.close(context);\n\t\t}\n\t}\n\n\tprivate publishOpenSession(\n\t\tmetadata: JsonlSessionMetadata,\n\t\tstorage: JsonlStorage,\n\t\tkey: string,\n\t): StorageBackedSession<JsonlSessionMetadata> {\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is already open: ${metadata.id}`);\n\t\tconst session = new StorageBackedSession(metadata, storage, {\n\t\t\tonClose: () => {\n\t\t\t\tif (this.openSessions.get(key) === storage) this.openSessions.delete(key);\n\t\t\t},\n\t\t});\n\t\tthis.openSessions.set(key, storage);\n\t\treturn session;\n\t}\n\n\tprivate sessionKey(cwd: string, id: string): string {\n\t\treturn `${cwd}\\0${id}`;\n\t}\n\n\tprivate async loadStorage(metadata: JsonlSessionMetadata, context: Context): Promise<JsonlStorage> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(metadata.path, context), `Failed to check session ${metadata.path}`)\n\t\t) {\n\t\t\tthrow new Error(`Session file does not exist: ${metadata.path}`);\n\t\t}\n\t\tconst storage = await JsonlStorage.open(\n\t\t\t{\n\t\t\t\tfileSystem: this.fileSystem,\n\t\t\t\tpath: metadata.path,\n\t\t\t\tnow: this.now,\n\t\t\t},\n\t\t\tcontext,\n\t\t);\n\t\ttry {\n\t\t\tif (storage.header.id !== metadata.id || storage.header.cwd !== metadata.cwd) {\n\t\t\t\tthrow new Error(`Session identity does not match header: ${metadata.id}`);\n\t\t\t}\n\t\t\tif (storage.header.storageVersion !== JSONL_STORAGE_VERSION) {\n\t\t\t\tthrow new Error(`Session ${metadata.id} uses unsupported storage version ${storage.header.storageVersion}`);\n\t\t\t}\n\t\t\treturn storage;\n\t\t} catch (error) {\n\t\t\tawait storage.close(context);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate root(context: Context): Promise<string> {\n\t\treturn this.fileSystem\n\t\t\t.absolutePath(this.sessionsRootInput, context)\n\t\t\t.then((result) => fileValue(result, `Failed to resolve sessions root ${this.sessionsRootInput}`));\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"JsonlSessionRepo is closed\");\n\t}\n}\n"]}
1
+ {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/repo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAMrE,OAAO,EAGN,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAE5B,MAAM,YAAY,CAAC;AA0BpB,yDAAyD;AACzD,qBAAa,gBACZ,YAAW,WAAW,CAAC,oBAAoB,EAAE,yBAAyB,EAAE,uBAAuB,CAAC;IAEhG,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmC;IAChE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAA4B;IAEhD,YAAY,OAAO,EAAE,uBAAuB,EAI3C;IAEK,MAAM,CAAC,OAAO,EAAE,yBAAyB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CA8BzG;IAEK,IAAI,CAAC,QAAQ,EAAE,oBAAoB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAYnG;IAEK,IAAI,CAAC,OAAO,EAAE,uBAAuB,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAoB1G;IAEK,MAAM,CAAC,QAAQ,EAAE,oBAAoB,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAa5E;IAEK,IAAI,CACT,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CA8CxC;IAED,KAAK,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAMtC;YAEa,wBAAwB;YAcxB,aAAa;YAwBb,mBAAmB;YAenB,kBAAkB;YAMlB,gBAAgB;YAOhB,qBAAqB;YAarB,wBAAwB;YAcxB,gBAAgB;YAwBhB,oBAAoB;IAUlC,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,UAAU;YAIJ,WAAW;IA4BzB,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,UAAU;CAGlB","sourcesContent":["import { uuidv7 } from \"@earendil-works/pi-ai/utils/uuid\";\nimport type { Context } from \"../../context.ts\";\nimport type { FileInfo, FileSystem } from \"../../types.ts\";\nimport { StorageBackedSession } from \"../session.ts\";\nimport type { ForkOptions, Session, SessionRepo } from \"../types.ts\";\nimport { parseJsonlSessionHeader } from \"./codec.ts\";\nimport { type JsonlForkInput, runJsonlFork } from \"./fork.ts\";\nimport { fileValue } from \"./io.ts\";\nimport { LegacyV3Source, metadataFromLegacyV3Header } from \"./legacy-v3.ts\";\nimport { JsonlStorage } from \"./storage.ts\";\nimport {\n\tJSONL_FORMAT_VERSION,\n\tJSONL_STORAGE_VERSION,\n\ttype JsonlSessionCreateOptions,\n\ttype JsonlSessionListOptions,\n\ttype JsonlSessionMetadata,\n\ttype JsonlSessionRepoOptions,\n\ttype JsonlStorageHeader,\n} from \"./types.ts\";\n\nfunction metadataFromHeader(header: JsonlStorageHeader, path: string, modifiedAt: number): JsonlSessionMetadata {\n\treturn {\n\t\tid: header.id,\n\t\tcreatedAt: header.createdAt,\n\t\tstorageVersion: header.storageVersion,\n\t\tcwd: header.cwd,\n\t\tpath,\n\t\tmodifiedAt,\n\t\t...(header.parentSessionId === undefined ? {} : { parentSessionId: header.parentSessionId }),\n\t\t...(header.legacyParentSessionPath === undefined\n\t\t\t? {}\n\t\t\t: { legacyParentSessionPath: header.legacyParentSessionPath }),\n\t};\n}\n\nfunction sessionDirectoryName(cwd: string): string {\n\treturn `--${cwd.replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n}\n\nfunction sessionFileName(createdAt: number, id: string): string {\n\tconst timestamp = new Date(createdAt).toISOString().replace(/[:.]/g, \"-\");\n\treturn `${timestamp}_${encodeURIComponent(id)}.jsonl`;\n}\n\n/** File-backed format-4 session repository lifecycle. */\nexport class JsonlSessionRepo\n\timplements SessionRepo<JsonlSessionMetadata, JsonlSessionCreateOptions, JsonlSessionListOptions>\n{\n\tprivate readonly fileSystem: FileSystem;\n\tprivate readonly sessionsRootInput: string;\n\tprivate readonly now: () => number;\n\tprivate readonly openSessions = new Map<string, JsonlStorage>();\n\tprivate readonly pendingCreates = new Set<string>();\n\tprivate closed = false;\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(options: JsonlSessionRepoOptions) {\n\t\tthis.fileSystem = options.fileSystem;\n\t\tthis.sessionsRootInput = options.sessionsRoot;\n\t\tthis.now = options.now ?? Date.now;\n\t}\n\n\tasync create(options: JsonlSessionCreateOptions, context: Context): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst createdAt = this.now();\n\t\tconst { cwd, id } = await this.resolveCreateDestination(options.cwd, options.id, createdAt, context);\n\t\tconst key = this.sessionKey(cwd, id);\n\t\tif (this.openSessions.has(key) || this.pendingCreates.has(key)) throw new Error(`Session already exists: ${id}`);\n\t\tthis.pendingCreates.add(key);\n\t\tlet path: string | undefined;\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tpath = await this.resolveNewSessionPath(cwd, createdAt, id, context);\n\t\t\tconst header: JsonlStorageHeader = {\n\t\t\t\tv: JSONL_FORMAT_VERSION,\n\t\t\t\tkind: \"header\",\n\t\t\t\tid,\n\t\t\t\tstorageVersion: JSONL_STORAGE_VERSION,\n\t\t\t\tcreatedAt,\n\t\t\t\tcwd,\n\t\t\t\t...(options.parentSessionId === undefined ? {} : { parentSessionId: options.parentSessionId }),\n\t\t\t};\n\t\t\tstorage = await JsonlStorage.create({ fileSystem: this.fileSystem, path, now: this.now }, header, [], context);\n\t\t\tconst info = fileValue(await this.fileSystem.fileInfo(path, context), `Failed to read session ${path}`);\n\t\t\treturn this.publishOpenSession(metadataFromHeader(header, path, info.mtimeMs), storage, key);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context).catch(() => undefined);\n\t\t\tif (path !== undefined) await this.fileSystem.remove(path, { force: true }, context);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingCreates.delete(key);\n\t\t}\n\t}\n\n\tasync open(metadata: JsonlSessionMetadata, context: Context): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst key = this.sessionKey(metadata.cwd, metadata.id);\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is already open: ${metadata.id}`);\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tstorage = await this.loadStorage(metadata, context);\n\t\t\treturn this.publishOpenSession(metadata, storage, key);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync list(options: JsonlSessionListOptions | undefined, context: Context): Promise<JsonlSessionMetadata[]> {\n\t\toptions ??= {};\n\t\tthis.assertOpen();\n\t\tconst cwd =\n\t\t\toptions.cwd === undefined\n\t\t\t\t? undefined\n\t\t\t\t: fileValue(\n\t\t\t\t\t\tawait this.fileSystem.absolutePath(options.cwd, context),\n\t\t\t\t\t\t`Failed to resolve session cwd ${options.cwd}`,\n\t\t\t\t\t);\n\t\tconst root = await this.root(context);\n\t\tif (!fileValue(await this.fileSystem.exists(root, context), `Failed to check sessions root ${root}`)) return [];\n\t\tconst directories =\n\t\t\tcwd === undefined ? await this.sessionDirectories(root, context) : [await this.sessionDirectory(cwd, context)];\n\t\tconst metadata: JsonlSessionMetadata[] = [];\n\t\tfor (const directory of directories) metadata.push(...(await this.listDirectory(directory, cwd, context)));\n\t\treturn metadata.sort(\n\t\t\t(left, right) =>\n\t\t\t\tright.createdAt - left.createdAt || left.id.localeCompare(right.id) || left.cwd.localeCompare(right.cwd),\n\t\t);\n\t}\n\n\tasync delete(metadata: JsonlSessionMetadata, context: Context): Promise<void> {\n\t\tthis.assertOpen();\n\t\tconst key = this.sessionKey(metadata.cwd, metadata.id);\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is open: ${metadata.id}`);\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(metadata.path, context), `Failed to check session ${metadata.path}`)\n\t\t) {\n\t\t\tthrow new Error(`Session file does not exist: ${metadata.path}`);\n\t\t}\n\t\tfileValue(\n\t\t\tawait this.fileSystem.remove(metadata.path, undefined, context),\n\t\t\t`Failed to delete session ${metadata.path}`,\n\t\t);\n\t}\n\n\tasync fork(\n\t\tsource: JsonlSessionMetadata,\n\t\toptions: ForkOptions,\n\t\tcontext: Context,\n\t): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst createdAt = this.now();\n\t\tconst cwd = source.cwd;\n\t\tconst id = options.id ?? uuidv7(createdAt);\n\t\tconst destinationKey = this.sessionKey(cwd, id);\n\t\tif (this.openSessions.has(destinationKey) || this.pendingCreates.has(destinationKey)) {\n\t\t\tthrow new Error(`Session already exists: ${id}`);\n\t\t}\n\t\tthis.pendingCreates.add(destinationKey);\n\n\t\tconst sourceStorage = this.openSessions.get(this.sessionKey(source.cwd, source.id));\n\t\tlet path: string | undefined;\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tconst input = await this.resolveForkInput(source, sourceStorage, context);\n\t\t\tpath = await this.resolveNewSessionPath(cwd, createdAt, id, context);\n\t\t\tconst header: Omit<JsonlStorageHeader, \"nextSeq\"> = {\n\t\t\t\tv: JSONL_FORMAT_VERSION,\n\t\t\t\tkind: \"header\",\n\t\t\t\tid,\n\t\t\t\tstorageVersion: JSONL_STORAGE_VERSION,\n\t\t\t\tcreatedAt,\n\t\t\t\tcwd,\n\t\t\t\tparentSessionId: source.id,\n\t\t\t};\n\t\t\tawait runJsonlFork(\n\t\t\t\t{\n\t\t\t\t\tinput,\n\t\t\t\t\tfileSystem: this.fileSystem,\n\t\t\t\t\tdestinationPath: path,\n\t\t\t\t\tdestinationHeader: header,\n\t\t\t\t\tfork: options,\n\t\t\t\t},\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tstorage = await JsonlStorage.open({ fileSystem: this.fileSystem, path, now: this.now }, context);\n\t\t\tconst info = fileValue(await this.fileSystem.fileInfo(path, context), `Failed to read session ${path}`);\n\t\t\treturn this.publishOpenSession(metadataFromHeader(header, path, info.mtimeMs), storage, destinationKey);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context).catch(() => undefined);\n\t\t\tif (path !== undefined) await this.fileSystem.remove(path, { force: true }, context);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingCreates.delete(destinationKey);\n\t\t}\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.closed = true;\n\t\t// TODO: Define ownership semantics before deciding whether repository close should close session handles.\n\t\tthis.closePromise = Promise.resolve();\n\t\treturn this.closePromise;\n\t}\n\n\tprivate async resolveCreateDestination(\n\t\tcwdInput: string,\n\t\tid: string | undefined,\n\t\tcreatedAt: number,\n\t\tcontext: Context,\n\t): Promise<{ cwd: string; id: string }> {\n\t\tconst destinationId = id ?? uuidv7(createdAt);\n\t\tconst cwd = fileValue(\n\t\t\tawait this.fileSystem.absolutePath(cwdInput, context),\n\t\t\t`Failed to resolve session cwd ${cwdInput}`,\n\t\t);\n\t\treturn { cwd, id: destinationId };\n\t}\n\n\tprivate async listDirectory(\n\t\tdirectory: string,\n\t\tcwd: string | undefined,\n\t\tcontext: Context,\n\t): Promise<JsonlSessionMetadata[]> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(directory, context), `Failed to check sessions directory ${directory}`)\n\t\t) {\n\t\t\treturn [];\n\t\t}\n\t\tconst files = fileValue(\n\t\t\tawait this.fileSystem.listDir(directory, context),\n\t\t\t`Failed to list sessions directory ${directory}`,\n\t\t).filter((file) => file.kind !== \"directory\" && file.name.endsWith(\".jsonl\"));\n\t\tconst metadata: JsonlSessionMetadata[] = [];\n\t\tfor (const file of files) {\n\t\t\tconst discovered = await this.readSessionMetadata(file, context);\n\t\t\tif (discovered === undefined) continue;\n\t\t\t// Directory encoding is lossy: /a/b and /a-b both map to --a-b--.\n\t\t\tif (cwd === undefined || discovered.cwd === cwd) metadata.push(discovered);\n\t\t}\n\t\treturn metadata;\n\t}\n\n\tprivate async readSessionMetadata(file: FileInfo, context: Context): Promise<JsonlSessionMetadata | undefined> {\n\t\tconst lines = fileValue(\n\t\t\tawait this.fileSystem.readTextLines(file.path, { maxLines: 1 }, context),\n\t\t\t`Failed to read session header ${file.path}`,\n\t\t);\n\t\tif (lines[0] === undefined) return undefined;\n\t\tconst parsedHeader = parseJsonlSessionHeader(lines[0]);\n\t\tif (!parsedHeader.ok) return undefined;\n\t\tif (parsedHeader.value.format === \"v3-legacy\") {\n\t\t\tconst metadata = await metadataFromLegacyV3Header(this.fileSystem, parsedHeader.value.header, context);\n\t\t\treturn { ...metadata, path: file.path, modifiedAt: file.mtimeMs };\n\t\t}\n\t\treturn metadataFromHeader(parsedHeader.value.header, file.path, file.mtimeMs);\n\t}\n\n\tprivate async sessionDirectories(root: string, context: Context): Promise<string[]> {\n\t\treturn fileValue(await this.fileSystem.listDir(root, context), `Failed to list sessions root ${root}`)\n\t\t\t.filter((entry) => entry.kind === \"directory\")\n\t\t\t.map((entry) => entry.path);\n\t}\n\n\tprivate async sessionDirectory(cwd: string, context: Context): Promise<string> {\n\t\treturn fileValue(\n\t\t\tawait this.fileSystem.joinPath([await this.root(context), sessionDirectoryName(cwd)], context),\n\t\t\t`Failed to resolve sessions directory for ${cwd}`,\n\t\t);\n\t}\n\n\tprivate async resolveNewSessionPath(cwd: string, createdAt: number, id: string, context: Context): Promise<string> {\n\t\tconst directory = await this.sessionDirectory(cwd, context);\n\t\tawait this.assertSessionIdAvailable(directory, id, context);\n\t\tfileValue(\n\t\t\tawait this.fileSystem.createDir(directory, undefined, context),\n\t\t\t`Failed to create sessions directory ${directory}`,\n\t\t);\n\t\treturn fileValue(\n\t\t\tawait this.fileSystem.joinPath([directory, sessionFileName(createdAt, id)], context),\n\t\t\t`Failed to resolve path for session ${id}`,\n\t\t);\n\t}\n\n\tprivate async assertSessionIdAvailable(directory: string, id: string, context: Context): Promise<void> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(directory, context), `Failed to check sessions directory ${directory}`)\n\t\t)\n\t\t\treturn;\n\n\t\tconst suffix = `_${encodeURIComponent(id)}.jsonl`;\n\t\tconst idExists = fileValue(\n\t\t\tawait this.fileSystem.listDir(directory, context),\n\t\t\t`Failed to list sessions directory ${directory}`,\n\t\t).some((entry) => entry.kind !== \"directory\" && entry.name.endsWith(suffix));\n\t\tif (idExists) throw new Error(`Session already exists: ${id}`);\n\t}\n\n\tprivate async resolveForkInput(\n\t\tsource: JsonlSessionMetadata,\n\t\tstorage: JsonlStorage | undefined,\n\t\tcontext: Context,\n\t): Promise<JsonlForkInput> {\n\t\tif (storage !== undefined) {\n\t\t\tif (storage.isLegacyV3()) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Cannot fork an open legacy v3 JSONL session; commit a non-empty transaction to upgrade it to format 4 first\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst nextSeq = await storage.captureForkNextSeq(context);\n\t\t\treturn { kind: \"open\", metadata: source, nextSeq };\n\t\t}\n\t\tif (await this.isLegacyV3ForkSource(source, context)) {\n\t\t\tconst normalized = await LegacyV3Source.read(this.fileSystem, source.path, context);\n\t\t\tif (normalized.header.id !== source.id || normalized.header.cwd !== source.cwd) {\n\t\t\t\tthrow new Error(`Session identity does not match header: ${source.id}`);\n\t\t\t}\n\t\t\treturn { kind: \"legacy-v3\", normalized };\n\t\t}\n\t\treturn { kind: \"closed\", metadata: source };\n\t}\n\n\tprivate async isLegacyV3ForkSource(source: JsonlSessionMetadata, context: Context): Promise<boolean> {\n\t\tconst lines = fileValue(\n\t\t\tawait this.fileSystem.readTextLines(source.path, { maxLines: 1 }, context),\n\t\t\t`Failed to read session header ${source.path}`,\n\t\t);\n\t\tif (lines[0] === undefined) return false;\n\t\tconst parsed = parseJsonlSessionHeader(lines[0]);\n\t\treturn parsed.ok && parsed.value.format === \"v3-legacy\";\n\t}\n\n\tprivate publishOpenSession(\n\t\tmetadata: JsonlSessionMetadata,\n\t\tstorage: JsonlStorage,\n\t\tkey: string,\n\t): StorageBackedSession<JsonlSessionMetadata> {\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is already open: ${metadata.id}`);\n\t\tconst session = new StorageBackedSession(metadata, storage, {\n\t\t\tonClose: () => {\n\t\t\t\tif (this.openSessions.get(key) === storage) this.openSessions.delete(key);\n\t\t\t},\n\t\t});\n\t\tthis.openSessions.set(key, storage);\n\t\treturn session;\n\t}\n\n\tprivate sessionKey(cwd: string, id: string): string {\n\t\treturn `${cwd}\\0${id}`;\n\t}\n\n\tprivate async loadStorage(metadata: JsonlSessionMetadata, context: Context): Promise<JsonlStorage> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(metadata.path, context), `Failed to check session ${metadata.path}`)\n\t\t) {\n\t\t\tthrow new Error(`Session file does not exist: ${metadata.path}`);\n\t\t}\n\t\tconst storage = await JsonlStorage.open(\n\t\t\t{\n\t\t\t\tfileSystem: this.fileSystem,\n\t\t\t\tpath: metadata.path,\n\t\t\t\tnow: this.now,\n\t\t\t},\n\t\t\tcontext,\n\t\t);\n\t\ttry {\n\t\t\tif (storage.header.id !== metadata.id || storage.header.cwd !== metadata.cwd) {\n\t\t\t\tthrow new Error(`Session identity does not match header: ${metadata.id}`);\n\t\t\t}\n\t\t\tif (storage.header.storageVersion !== JSONL_STORAGE_VERSION) {\n\t\t\t\tthrow new Error(`Session ${metadata.id} uses unsupported storage version ${storage.header.storageVersion}`);\n\t\t\t}\n\t\t\treturn storage;\n\t\t} catch (error) {\n\t\t\tawait storage.close(context);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate root(context: Context): Promise<string> {\n\t\treturn this.fileSystem\n\t\t\t.absolutePath(this.sessionsRootInput, context)\n\t\t\t.then((result) => fileValue(result, `Failed to resolve sessions root ${this.sessionsRootInput}`));\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"JsonlSessionRepo is closed\");\n\t}\n}\n"]}
@@ -1,15 +1,11 @@
1
1
  import { uuidv7 } from "@earendil-works/pi-ai/utils/uuid";
2
- import { createForkSnapshot } from "../fork.js";
3
2
  import { StorageBackedSession } from "../session.js";
4
3
  import { parseJsonlSessionHeader } from "./codec.js";
5
- import { metadataFromLegacyV3Header } from "./legacy-v3.js";
4
+ import { runJsonlFork } from "./fork.js";
5
+ import { fileValue } from "./io.js";
6
+ import { LegacyV3Source, metadataFromLegacyV3Header } from "./legacy-v3.js";
6
7
  import { JsonlStorage } from "./storage.js";
7
8
  import { JSONL_FORMAT_VERSION, JSONL_STORAGE_VERSION, } from "./types.js";
8
- function fileValue(result, action) {
9
- if (!result.ok)
10
- throw new Error(`${action}: ${result.error.message}`, { cause: result.error });
11
- return result.value;
12
- }
13
9
  function metadataFromHeader(header, path, modifiedAt) {
14
10
  return {
15
11
  id: header.id,
@@ -123,21 +119,19 @@ export class JsonlSessionRepo {
123
119
  async fork(source, options, context) {
124
120
  this.assertOpen();
125
121
  const createdAt = this.now();
126
- const sourceStorage = this.openSessions.get(this.sessionKey(source.cwd, source.id));
127
- const sourceSnapshot = await (sourceStorage === undefined
128
- ? this.loadClosedForkSourceSnapshot(source, context)
129
- : sourceStorage.captureForkSource(context));
130
- const { cwd, id } = await this.resolveCreateDestination(source.cwd, options.id, createdAt, context);
122
+ const cwd = source.cwd;
123
+ const id = options.id ?? uuidv7(createdAt);
131
124
  const destinationKey = this.sessionKey(cwd, id);
132
125
  if (this.openSessions.has(destinationKey) || this.pendingCreates.has(destinationKey)) {
133
126
  throw new Error(`Session already exists: ${id}`);
134
127
  }
135
128
  this.pendingCreates.add(destinationKey);
129
+ const sourceStorage = this.openSessions.get(this.sessionKey(source.cwd, source.id));
136
130
  let path;
137
131
  let storage;
138
132
  try {
133
+ const input = await this.resolveForkInput(source, sourceStorage, context);
139
134
  path = await this.resolveNewSessionPath(cwd, createdAt, id, context);
140
- const snapshot = createForkSnapshot(sourceSnapshot, options);
141
135
  const header = {
142
136
  v: JSONL_FORMAT_VERSION,
143
137
  kind: "header",
@@ -147,7 +141,14 @@ export class JsonlSessionRepo {
147
141
  cwd,
148
142
  parentSessionId: source.id,
149
143
  };
150
- storage = await JsonlStorage.createFromForkSnapshot({ fileSystem: this.fileSystem, path, now: this.now }, header, snapshot, context);
144
+ await runJsonlFork({
145
+ input,
146
+ fileSystem: this.fileSystem,
147
+ destinationPath: path,
148
+ destinationHeader: header,
149
+ fork: options,
150
+ }, context);
151
+ storage = await JsonlStorage.open({ fileSystem: this.fileSystem, path, now: this.now }, context);
151
152
  const info = fileValue(await this.fileSystem.fileInfo(path, context), `Failed to read session ${path}`);
152
153
  return this.publishOpenSession(metadataFromHeader(header, path, info.mtimeMs), storage, destinationKey);
153
154
  }
@@ -225,14 +226,29 @@ export class JsonlSessionRepo {
225
226
  if (idExists)
226
227
  throw new Error(`Session already exists: ${id}`);
227
228
  }
228
- async loadClosedForkSourceSnapshot(source, context) {
229
- const storage = await this.loadStorage(source, context);
230
- try {
231
- return await storage.captureForkSource(context);
229
+ async resolveForkInput(source, storage, context) {
230
+ if (storage !== undefined) {
231
+ if (storage.isLegacyV3()) {
232
+ throw new Error("Cannot fork an open legacy v3 JSONL session; commit a non-empty transaction to upgrade it to format 4 first");
233
+ }
234
+ const nextSeq = await storage.captureForkNextSeq(context);
235
+ return { kind: "open", metadata: source, nextSeq };
232
236
  }
233
- finally {
234
- await storage.close(context);
237
+ if (await this.isLegacyV3ForkSource(source, context)) {
238
+ const normalized = await LegacyV3Source.read(this.fileSystem, source.path, context);
239
+ if (normalized.header.id !== source.id || normalized.header.cwd !== source.cwd) {
240
+ throw new Error(`Session identity does not match header: ${source.id}`);
241
+ }
242
+ return { kind: "legacy-v3", normalized };
235
243
  }
244
+ return { kind: "closed", metadata: source };
245
+ }
246
+ async isLegacyV3ForkSource(source, context) {
247
+ const lines = fileValue(await this.fileSystem.readTextLines(source.path, { maxLines: 1 }, context), `Failed to read session header ${source.path}`);
248
+ if (lines[0] === undefined)
249
+ return false;
250
+ const parsed = parseJsonlSessionHeader(lines[0]);
251
+ return parsed.ok && parsed.value.format === "v3-legacy";
236
252
  }
237
253
  publishOpenSession(metadata, storage, key) {
238
254
  if (this.openSessions.has(key))
@@ -1 +1 @@
1
- {"version":3,"file":"repo.js","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/repo.ts"],"names":[],"mappings":"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","sourcesContent":["import { uuidv7 } from \"@earendil-works/pi-ai/utils/uuid\";\nimport type { Context } from \"../../context.ts\";\nimport type { FileError, FileInfo, FileSystem, Result } from \"../../types.ts\";\nimport { createForkSnapshot, type ForkSourceSnapshot } from \"../fork.ts\";\nimport { StorageBackedSession } from \"../session.ts\";\nimport type { ForkOptions, Session, SessionRepo } from \"../types.ts\";\nimport { parseJsonlSessionHeader } from \"./codec.ts\";\nimport { metadataFromLegacyV3Header } from \"./legacy-v3.ts\";\nimport { JsonlStorage } from \"./storage.ts\";\nimport {\n\tJSONL_FORMAT_VERSION,\n\tJSONL_STORAGE_VERSION,\n\ttype JsonlSessionCreateOptions,\n\ttype JsonlSessionListOptions,\n\ttype JsonlSessionMetadata,\n\ttype JsonlSessionRepoOptions,\n\ttype JsonlStorageHeader,\n} from \"./types.ts\";\n\nfunction fileValue<T>(result: Result<T, FileError>, action: string): T {\n\tif (!result.ok) throw new Error(`${action}: ${result.error.message}`, { cause: result.error });\n\treturn result.value;\n}\n\nfunction metadataFromHeader(header: JsonlStorageHeader, path: string, modifiedAt: number): JsonlSessionMetadata {\n\treturn {\n\t\tid: header.id,\n\t\tcreatedAt: header.createdAt,\n\t\tstorageVersion: header.storageVersion,\n\t\tcwd: header.cwd,\n\t\tpath,\n\t\tmodifiedAt,\n\t\t...(header.parentSessionId === undefined ? {} : { parentSessionId: header.parentSessionId }),\n\t\t...(header.legacyParentSessionPath === undefined\n\t\t\t? {}\n\t\t\t: { legacyParentSessionPath: header.legacyParentSessionPath }),\n\t};\n}\n\nfunction sessionDirectoryName(cwd: string): string {\n\treturn `--${cwd.replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n}\n\nfunction sessionFileName(createdAt: number, id: string): string {\n\tconst timestamp = new Date(createdAt).toISOString().replace(/[:.]/g, \"-\");\n\treturn `${timestamp}_${encodeURIComponent(id)}.jsonl`;\n}\n\n/** File-backed format-4 session repository lifecycle. */\nexport class JsonlSessionRepo\n\timplements SessionRepo<JsonlSessionMetadata, JsonlSessionCreateOptions, JsonlSessionListOptions>\n{\n\tprivate readonly fileSystem: FileSystem;\n\tprivate readonly sessionsRootInput: string;\n\tprivate readonly now: () => number;\n\tprivate readonly openSessions = new Map<string, JsonlStorage>();\n\tprivate readonly pendingCreates = new Set<string>();\n\tprivate closed = false;\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(options: JsonlSessionRepoOptions) {\n\t\tthis.fileSystem = options.fileSystem;\n\t\tthis.sessionsRootInput = options.sessionsRoot;\n\t\tthis.now = options.now ?? Date.now;\n\t}\n\n\tasync create(options: JsonlSessionCreateOptions, context: Context): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst createdAt = this.now();\n\t\tconst { cwd, id } = await this.resolveCreateDestination(options.cwd, options.id, createdAt, context);\n\t\tconst key = this.sessionKey(cwd, id);\n\t\tif (this.openSessions.has(key) || this.pendingCreates.has(key)) throw new Error(`Session already exists: ${id}`);\n\t\tthis.pendingCreates.add(key);\n\t\tlet path: string | undefined;\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tpath = await this.resolveNewSessionPath(cwd, createdAt, id, context);\n\t\t\tconst header: JsonlStorageHeader = {\n\t\t\t\tv: JSONL_FORMAT_VERSION,\n\t\t\t\tkind: \"header\",\n\t\t\t\tid,\n\t\t\t\tstorageVersion: JSONL_STORAGE_VERSION,\n\t\t\t\tcreatedAt,\n\t\t\t\tcwd,\n\t\t\t\t...(options.parentSessionId === undefined ? {} : { parentSessionId: options.parentSessionId }),\n\t\t\t};\n\t\t\tstorage = await JsonlStorage.create({ fileSystem: this.fileSystem, path, now: this.now }, header, [], context);\n\t\t\tconst info = fileValue(await this.fileSystem.fileInfo(path, context), `Failed to read session ${path}`);\n\t\t\treturn this.publishOpenSession(metadataFromHeader(header, path, info.mtimeMs), storage, key);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context).catch(() => undefined);\n\t\t\tif (path !== undefined) await this.fileSystem.remove(path, { force: true }, context);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingCreates.delete(key);\n\t\t}\n\t}\n\n\tasync open(metadata: JsonlSessionMetadata, context: Context): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst key = this.sessionKey(metadata.cwd, metadata.id);\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is already open: ${metadata.id}`);\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tstorage = await this.loadStorage(metadata, context);\n\t\t\treturn this.publishOpenSession(metadata, storage, key);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync list(options: JsonlSessionListOptions | undefined, context: Context): Promise<JsonlSessionMetadata[]> {\n\t\toptions ??= {};\n\t\tthis.assertOpen();\n\t\tconst cwd =\n\t\t\toptions.cwd === undefined\n\t\t\t\t? undefined\n\t\t\t\t: fileValue(\n\t\t\t\t\t\tawait this.fileSystem.absolutePath(options.cwd, context),\n\t\t\t\t\t\t`Failed to resolve session cwd ${options.cwd}`,\n\t\t\t\t\t);\n\t\tconst root = await this.root(context);\n\t\tif (!fileValue(await this.fileSystem.exists(root, context), `Failed to check sessions root ${root}`)) return [];\n\t\tconst directories =\n\t\t\tcwd === undefined ? await this.sessionDirectories(root, context) : [await this.sessionDirectory(cwd, context)];\n\t\tconst metadata: JsonlSessionMetadata[] = [];\n\t\tfor (const directory of directories) metadata.push(...(await this.listDirectory(directory, cwd, context)));\n\t\treturn metadata.sort(\n\t\t\t(left, right) =>\n\t\t\t\tright.createdAt - left.createdAt || left.id.localeCompare(right.id) || left.cwd.localeCompare(right.cwd),\n\t\t);\n\t}\n\n\tasync delete(metadata: JsonlSessionMetadata, context: Context): Promise<void> {\n\t\tthis.assertOpen();\n\t\tconst key = this.sessionKey(metadata.cwd, metadata.id);\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is open: ${metadata.id}`);\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(metadata.path, context), `Failed to check session ${metadata.path}`)\n\t\t) {\n\t\t\tthrow new Error(`Session file does not exist: ${metadata.path}`);\n\t\t}\n\t\tfileValue(\n\t\t\tawait this.fileSystem.remove(metadata.path, undefined, context),\n\t\t\t`Failed to delete session ${metadata.path}`,\n\t\t);\n\t}\n\n\tasync fork(\n\t\tsource: JsonlSessionMetadata,\n\t\toptions: ForkOptions,\n\t\tcontext: Context,\n\t): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst createdAt = this.now();\n\t\tconst sourceStorage = this.openSessions.get(this.sessionKey(source.cwd, source.id));\n\t\tconst sourceSnapshot = await (sourceStorage === undefined\n\t\t\t? this.loadClosedForkSourceSnapshot(source, context)\n\t\t\t: sourceStorage.captureForkSource(context));\n\t\tconst { cwd, id } = await this.resolveCreateDestination(source.cwd, options.id, createdAt, context);\n\t\tconst destinationKey = this.sessionKey(cwd, id);\n\t\tif (this.openSessions.has(destinationKey) || this.pendingCreates.has(destinationKey)) {\n\t\t\tthrow new Error(`Session already exists: ${id}`);\n\t\t}\n\t\tthis.pendingCreates.add(destinationKey);\n\n\t\tlet path: string | undefined;\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tpath = await this.resolveNewSessionPath(cwd, createdAt, id, context);\n\t\t\tconst snapshot = createForkSnapshot(sourceSnapshot, options);\n\t\t\tconst header: JsonlStorageHeader = {\n\t\t\t\tv: JSONL_FORMAT_VERSION,\n\t\t\t\tkind: \"header\",\n\t\t\t\tid,\n\t\t\t\tstorageVersion: JSONL_STORAGE_VERSION,\n\t\t\t\tcreatedAt,\n\t\t\t\tcwd,\n\t\t\t\tparentSessionId: source.id,\n\t\t\t};\n\t\t\tstorage = await JsonlStorage.createFromForkSnapshot(\n\t\t\t\t{ fileSystem: this.fileSystem, path, now: this.now },\n\t\t\t\theader,\n\t\t\t\tsnapshot,\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tconst info = fileValue(await this.fileSystem.fileInfo(path, context), `Failed to read session ${path}`);\n\t\t\treturn this.publishOpenSession(metadataFromHeader(header, path, info.mtimeMs), storage, destinationKey);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context).catch(() => undefined);\n\t\t\tif (path !== undefined) await this.fileSystem.remove(path, { force: true }, context);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingCreates.delete(destinationKey);\n\t\t}\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.closed = true;\n\t\t// TODO: Define ownership semantics before deciding whether repository close should close session handles.\n\t\tthis.closePromise = Promise.resolve();\n\t\treturn this.closePromise;\n\t}\n\n\tprivate async resolveCreateDestination(\n\t\tcwdInput: string,\n\t\tid: string | undefined,\n\t\tcreatedAt: number,\n\t\tcontext: Context,\n\t): Promise<{ cwd: string; id: string }> {\n\t\tconst destinationId = id ?? uuidv7(createdAt);\n\t\tconst cwd = fileValue(\n\t\t\tawait this.fileSystem.absolutePath(cwdInput, context),\n\t\t\t`Failed to resolve session cwd ${cwdInput}`,\n\t\t);\n\t\treturn { cwd, id: destinationId };\n\t}\n\n\tprivate async listDirectory(\n\t\tdirectory: string,\n\t\tcwd: string | undefined,\n\t\tcontext: Context,\n\t): Promise<JsonlSessionMetadata[]> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(directory, context), `Failed to check sessions directory ${directory}`)\n\t\t) {\n\t\t\treturn [];\n\t\t}\n\t\tconst files = fileValue(\n\t\t\tawait this.fileSystem.listDir(directory, context),\n\t\t\t`Failed to list sessions directory ${directory}`,\n\t\t).filter((file) => file.kind !== \"directory\" && file.name.endsWith(\".jsonl\"));\n\t\tconst metadata: JsonlSessionMetadata[] = [];\n\t\tfor (const file of files) {\n\t\t\tconst discovered = await this.readSessionMetadata(file, context);\n\t\t\tif (discovered === undefined) continue;\n\t\t\t// Directory encoding is lossy: /a/b and /a-b both map to --a-b--.\n\t\t\tif (cwd === undefined || discovered.cwd === cwd) metadata.push(discovered);\n\t\t}\n\t\treturn metadata;\n\t}\n\n\tprivate async readSessionMetadata(file: FileInfo, context: Context): Promise<JsonlSessionMetadata | undefined> {\n\t\tconst lines = fileValue(\n\t\t\tawait this.fileSystem.readTextLines(file.path, { maxLines: 1 }, context),\n\t\t\t`Failed to read session header ${file.path}`,\n\t\t);\n\t\tif (lines[0] === undefined) return undefined;\n\t\tconst parsedHeader = parseJsonlSessionHeader(lines[0]);\n\t\tif (!parsedHeader.ok) return undefined;\n\t\tif (parsedHeader.value.format === \"v3-legacy\") {\n\t\t\tconst metadata = await metadataFromLegacyV3Header(this.fileSystem, parsedHeader.value.header, context);\n\t\t\treturn { ...metadata, path: file.path, modifiedAt: file.mtimeMs };\n\t\t}\n\t\treturn metadataFromHeader(parsedHeader.value.header, file.path, file.mtimeMs);\n\t}\n\n\tprivate async sessionDirectories(root: string, context: Context): Promise<string[]> {\n\t\treturn fileValue(await this.fileSystem.listDir(root, context), `Failed to list sessions root ${root}`)\n\t\t\t.filter((entry) => entry.kind === \"directory\")\n\t\t\t.map((entry) => entry.path);\n\t}\n\n\tprivate async sessionDirectory(cwd: string, context: Context): Promise<string> {\n\t\treturn fileValue(\n\t\t\tawait this.fileSystem.joinPath([await this.root(context), sessionDirectoryName(cwd)], context),\n\t\t\t`Failed to resolve sessions directory for ${cwd}`,\n\t\t);\n\t}\n\n\tprivate async resolveNewSessionPath(cwd: string, createdAt: number, id: string, context: Context): Promise<string> {\n\t\tconst directory = await this.sessionDirectory(cwd, context);\n\t\tawait this.assertSessionIdAvailable(directory, id, context);\n\t\tfileValue(\n\t\t\tawait this.fileSystem.createDir(directory, undefined, context),\n\t\t\t`Failed to create sessions directory ${directory}`,\n\t\t);\n\t\treturn fileValue(\n\t\t\tawait this.fileSystem.joinPath([directory, sessionFileName(createdAt, id)], context),\n\t\t\t`Failed to resolve path for session ${id}`,\n\t\t);\n\t}\n\n\tprivate async assertSessionIdAvailable(directory: string, id: string, context: Context): Promise<void> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(directory, context), `Failed to check sessions directory ${directory}`)\n\t\t)\n\t\t\treturn;\n\n\t\tconst suffix = `_${encodeURIComponent(id)}.jsonl`;\n\t\tconst idExists = fileValue(\n\t\t\tawait this.fileSystem.listDir(directory, context),\n\t\t\t`Failed to list sessions directory ${directory}`,\n\t\t).some((entry) => entry.kind !== \"directory\" && entry.name.endsWith(suffix));\n\t\tif (idExists) throw new Error(`Session already exists: ${id}`);\n\t}\n\n\tprivate async loadClosedForkSourceSnapshot(\n\t\tsource: JsonlSessionMetadata,\n\t\tcontext: Context,\n\t): Promise<ForkSourceSnapshot> {\n\t\tconst storage = await this.loadStorage(source, context);\n\t\ttry {\n\t\t\treturn await storage.captureForkSource(context);\n\t\t} finally {\n\t\t\tawait storage.close(context);\n\t\t}\n\t}\n\n\tprivate publishOpenSession(\n\t\tmetadata: JsonlSessionMetadata,\n\t\tstorage: JsonlStorage,\n\t\tkey: string,\n\t): StorageBackedSession<JsonlSessionMetadata> {\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is already open: ${metadata.id}`);\n\t\tconst session = new StorageBackedSession(metadata, storage, {\n\t\t\tonClose: () => {\n\t\t\t\tif (this.openSessions.get(key) === storage) this.openSessions.delete(key);\n\t\t\t},\n\t\t});\n\t\tthis.openSessions.set(key, storage);\n\t\treturn session;\n\t}\n\n\tprivate sessionKey(cwd: string, id: string): string {\n\t\treturn `${cwd}\\0${id}`;\n\t}\n\n\tprivate async loadStorage(metadata: JsonlSessionMetadata, context: Context): Promise<JsonlStorage> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(metadata.path, context), `Failed to check session ${metadata.path}`)\n\t\t) {\n\t\t\tthrow new Error(`Session file does not exist: ${metadata.path}`);\n\t\t}\n\t\tconst storage = await JsonlStorage.open(\n\t\t\t{\n\t\t\t\tfileSystem: this.fileSystem,\n\t\t\t\tpath: metadata.path,\n\t\t\t\tnow: this.now,\n\t\t\t},\n\t\t\tcontext,\n\t\t);\n\t\ttry {\n\t\t\tif (storage.header.id !== metadata.id || storage.header.cwd !== metadata.cwd) {\n\t\t\t\tthrow new Error(`Session identity does not match header: ${metadata.id}`);\n\t\t\t}\n\t\t\tif (storage.header.storageVersion !== JSONL_STORAGE_VERSION) {\n\t\t\t\tthrow new Error(`Session ${metadata.id} uses unsupported storage version ${storage.header.storageVersion}`);\n\t\t\t}\n\t\t\treturn storage;\n\t\t} catch (error) {\n\t\t\tawait storage.close(context);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate root(context: Context): Promise<string> {\n\t\treturn this.fileSystem\n\t\t\t.absolutePath(this.sessionsRootInput, context)\n\t\t\t.then((result) => fileValue(result, `Failed to resolve sessions root ${this.sessionsRootInput}`));\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"JsonlSessionRepo is closed\");\n\t}\n}\n"]}
1
+ {"version":3,"file":"repo.js","sourceRoot":"","sources":["../../../../src/harness/session/jsonl/repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAG1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAuB,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EACN,oBAAoB,EACpB,qBAAqB,GAMrB,MAAM,YAAY,CAAC;AAEpB,SAAS,kBAAkB,CAAC,MAA0B,EAAE,IAAY,EAAE,UAAkB,EAAwB;IAC/G,OAAO;QACN,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,IAAI;QACJ,UAAU;QACV,GAAG,CAAC,MAAM,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE,CAAC;QAC5F,GAAG,CAAC,MAAM,CAAC,uBAAuB,KAAK,SAAS;YAC/C,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,uBAAuB,EAAE,MAAM,CAAC,uBAAuB,EAAE,CAAC;KAC/D,CAAC;AAAA,CACF;AAED,SAAS,oBAAoB,CAAC,GAAW,EAAU;IAClD,OAAO,KAAK,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC;AAAA,CAClE;AAED,SAAS,eAAe,CAAC,SAAiB,EAAE,EAAU,EAAU;IAC/D,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC1E,OAAO,GAAG,SAAS,IAAI,kBAAkB,CAAC,EAAE,CAAC,QAAQ,CAAC;AAAA,CACtD;AAED,yDAAyD;AACzD,MAAM,OAAO,gBAAgB;IAGX,UAAU,CAAa;IACvB,iBAAiB,CAAS;IAC1B,GAAG,CAAe;IAClB,YAAY,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC/C,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5C,MAAM,GAAG,KAAK,CAAC;IACf,YAAY,CAA4B;IAEhD,YAAY,OAAgC,EAAE;QAC7C,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;QAC9C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IAAA,CACnC;IAED,KAAK,CAAC,MAAM,CAAC,OAAkC,EAAE,OAAgB,EAA0C;QAC1G,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QACrG,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACrC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;QACjH,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,IAAwB,CAAC;QAC7B,IAAI,OAAiC,CAAC;QACtC,IAAI,CAAC;YACJ,IAAI,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;YACrE,MAAM,MAAM,GAAuB;gBAClC,CAAC,EAAE,oBAAoB;gBACvB,IAAI,EAAE,QAAQ;gBACd,EAAE;gBACF,cAAc,EAAE,qBAAqB;gBACrC,SAAS;gBACT,GAAG;gBACH,GAAG,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC;aAC9F,CAAC;YACF,OAAO,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;YAC/G,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,0BAA0B,IAAI,EAAE,CAAC,CAAC;YACxG,OAAO,IAAI,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;QAC9F,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YACrD,IAAI,IAAI,KAAK,SAAS;gBAAE,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;YACrF,MAAM,KAAK,CAAC;QACb,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;IAAA,CACD;IAED,KAAK,CAAC,IAAI,CAAC,QAA8B,EAAE,OAAgB,EAA0C;QACpG,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QACvD,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3F,IAAI,OAAiC,CAAC;QACtC,IAAI,CAAC;YACJ,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACpD,OAAO,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YAC9B,MAAM,KAAK,CAAC;QACb,CAAC;IAAA,CACD;IAED,KAAK,CAAC,IAAI,CAAC,OAA4C,EAAE,OAAgB,EAAmC;QAC3G,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,GAAG,GACR,OAAO,CAAC,GAAG,KAAK,SAAS;YACxB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,SAAS,CACT,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,EACxD,iCAAiC,OAAO,CAAC,GAAG,EAAE,CAC9C,CAAC;QACL,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,iCAAiC,IAAI,EAAE,CAAC;YAAE,OAAO,EAAE,CAAC;QAChH,MAAM,WAAW,GAChB,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;QAChH,MAAM,QAAQ,GAA2B,EAAE,CAAC;QAC5C,KAAK,MAAM,SAAS,IAAI,WAAW;YAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAC3G,OAAO,QAAQ,CAAC,IAAI,CACnB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACf,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CACzG,CAAC;IAAA,CACF;IAED,KAAK,CAAC,MAAM,CAAC,QAA8B,EAAE,OAAgB,EAAiB;QAC7E,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QACvD,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;QACnF,IACC,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,2BAA2B,QAAQ,CAAC,IAAI,EAAE,CAAC,EAC3G,CAAC;YACF,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,SAAS,CACR,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,EAC/D,4BAA4B,QAAQ,CAAC,IAAI,EAAE,CAC3C,CAAC;IAAA,CACF;IAED,KAAK,CAAC,IAAI,CACT,MAA4B,EAC5B,OAAoB,EACpB,OAAgB,EACyB;QACzC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;QACvB,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3C,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAChD,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YACtF,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAExC,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACpF,IAAI,IAAwB,CAAC;QAC7B,IAAI,OAAiC,CAAC;QACtC,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;YAC1E,IAAI,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;YACrE,MAAM,MAAM,GAAwC;gBACnD,CAAC,EAAE,oBAAoB;gBACvB,IAAI,EAAE,QAAQ;gBACd,EAAE;gBACF,cAAc,EAAE,qBAAqB;gBACrC,SAAS;gBACT,GAAG;gBACH,eAAe,EAAE,MAAM,CAAC,EAAE;aAC1B,CAAC;YACF,MAAM,YAAY,CACjB;gBACC,KAAK;gBACL,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,eAAe,EAAE,IAAI;gBACrB,iBAAiB,EAAE,MAAM;gBACzB,IAAI,EAAE,OAAO;aACb,EACD,OAAO,CACP,CAAC;YACF,OAAO,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;YACjG,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,0BAA0B,IAAI,EAAE,CAAC,CAAC;YACxG,OAAO,IAAI,CAAC,kBAAkB,CAAC,kBAAkB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;QACzG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YACrD,IAAI,IAAI,KAAK,SAAS;gBAAE,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;YACrF,MAAM,KAAK,CAAC;QACb,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAC5C,CAAC;IAAA,CACD;IAED,KAAK,CAAC,QAAiB,EAAiB;QACvC,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,YAAY,CAAC;QAC9D,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,0GAA0G;QAC1G,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC,YAAY,CAAC;IAAA,CACzB;IAEO,KAAK,CAAC,wBAAwB,CACrC,QAAgB,EAChB,EAAsB,EACtB,SAAiB,EACjB,OAAgB,EACuB;QACvC,MAAM,aAAa,GAAG,EAAE,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,SAAS,CACpB,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,EACrD,iCAAiC,QAAQ,EAAE,CAC3C,CAAC;QACF,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC;IAAA,CAClC;IAEO,KAAK,CAAC,aAAa,CAC1B,SAAiB,EACjB,GAAuB,EACvB,OAAgB,EACkB;QAClC,IACC,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,sCAAsC,SAAS,EAAE,CAAC,EAC9G,CAAC;YACF,OAAO,EAAE,CAAC;QACX,CAAC;QACD,MAAM,KAAK,GAAG,SAAS,CACtB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,EACjD,qCAAqC,SAAS,EAAE,CAChD,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9E,MAAM,QAAQ,GAA2B,EAAE,CAAC;QAC5C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAC1B,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACjE,IAAI,UAAU,KAAK,SAAS;gBAAE,SAAS;YACvC,kEAAkE;YAClE,IAAI,GAAG,KAAK,SAAS,IAAI,UAAU,CAAC,GAAG,KAAK,GAAG;gBAAE,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,QAAQ,CAAC;IAAA,CAChB;IAEO,KAAK,CAAC,mBAAmB,CAAC,IAAc,EAAE,OAAgB,EAA6C;QAC9G,MAAM,KAAK,GAAG,SAAS,CACtB,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,EACxE,iCAAiC,IAAI,CAAC,IAAI,EAAE,CAC5C,CAAC;QACF,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC7C,MAAM,YAAY,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,IAAI,CAAC,YAAY,CAAC,EAAE;YAAE,OAAO,SAAS,CAAC;QACvC,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAC/C,MAAM,QAAQ,GAAG,MAAM,0BAA0B,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACvG,OAAO,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;QACnE,CAAC;QACD,OAAO,kBAAkB,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAAA,CAC9E;IAEO,KAAK,CAAC,kBAAkB,CAAC,IAAY,EAAE,OAAgB,EAAqB;QACnF,OAAO,SAAS,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,gCAAgC,IAAI,EAAE,CAAC;aACpG,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC;aAC7C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAAA,CAC7B;IAEO,KAAK,CAAC,gBAAgB,CAAC,GAAW,EAAE,OAAgB,EAAmB;QAC9E,OAAO,SAAS,CACf,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,EAC9F,4CAA4C,GAAG,EAAE,CACjD,CAAC;IAAA,CACF;IAEO,KAAK,CAAC,qBAAqB,CAAC,GAAW,EAAE,SAAiB,EAAE,EAAU,EAAE,OAAgB,EAAmB;QAClH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC5D,MAAM,IAAI,CAAC,wBAAwB,CAAC,SAAS,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QAC5D,SAAS,CACR,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAC9D,uCAAuC,SAAS,EAAE,CAClD,CAAC;QACF,OAAO,SAAS,CACf,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE,eAAe,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,EACpF,sCAAsC,EAAE,EAAE,CAC1C,CAAC;IAAA,CACF;IAEO,KAAK,CAAC,wBAAwB,CAAC,SAAiB,EAAE,EAAU,EAAE,OAAgB,EAAiB;QACtG,IACC,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,sCAAsC,SAAS,EAAE,CAAC;YAE/G,OAAO;QAER,MAAM,MAAM,GAAG,IAAI,kBAAkB,CAAC,EAAE,CAAC,QAAQ,CAAC;QAClD,MAAM,QAAQ,GAAG,SAAS,CACzB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,EACjD,qCAAqC,SAAS,EAAE,CAChD,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7E,IAAI,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAC;IAAA,CAC/D;IAEO,KAAK,CAAC,gBAAgB,CAC7B,MAA4B,EAC5B,OAAiC,EACjC,OAAgB,EACU;QAC1B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,IAAI,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CACd,6GAA6G,CAC7G,CAAC;YACH,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;YAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QACpD,CAAC;QACD,IAAI,MAAM,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;YACtD,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACpF,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC;gBAChF,MAAM,IAAI,KAAK,CAAC,2CAA2C,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;YACzE,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;QAC1C,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAA,CAC5C;IAEO,KAAK,CAAC,oBAAoB,CAAC,MAA4B,EAAE,OAAgB,EAAoB;QACpG,MAAM,KAAK,GAAG,SAAS,CACtB,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,EAC1E,iCAAiC,MAAM,CAAC,IAAI,EAAE,CAC9C,CAAC;QACF,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QACzC,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACjD,OAAO,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,WAAW,CAAC;IAAA,CACxD;IAEO,kBAAkB,CACzB,QAA8B,EAC9B,OAAqB,EACrB,GAAW,EACkC;QAC7C,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3F,MAAM,OAAO,GAAG,IAAI,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE;YAC3D,OAAO,EAAE,GAAG,EAAE,CAAC;gBACd,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,OAAO;oBAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAAA,CAC1E;SACD,CAAC,CAAC;QACH,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACpC,OAAO,OAAO,CAAC;IAAA,CACf;IAEO,UAAU,CAAC,GAAW,EAAE,EAAU,EAAU;QACnD,OAAO,GAAG,GAAG,KAAK,EAAE,EAAE,CAAC;IAAA,CACvB;IAEO,KAAK,CAAC,WAAW,CAAC,QAA8B,EAAE,OAAgB,EAAyB;QAClG,IACC,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,2BAA2B,QAAQ,CAAC,IAAI,EAAE,CAAC,EAC3G,CAAC;YACF,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,IAAI,CACtC;YACC,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,GAAG,EAAE,IAAI,CAAC,GAAG;SACb,EACD,OAAO,CACP,CAAC;QACF,IAAI,CAAC;YACJ,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG,EAAE,CAAC;gBAC9E,MAAM,IAAI,KAAK,CAAC,2CAA2C,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3E,CAAC;YACD,IAAI,OAAO,CAAC,MAAM,CAAC,cAAc,KAAK,qBAAqB,EAAE,CAAC;gBAC7D,MAAM,IAAI,KAAK,CAAC,WAAW,QAAQ,CAAC,EAAE,qCAAqC,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;YAC7G,CAAC;YACD,OAAO,OAAO,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,MAAM,KAAK,CAAC;QACb,CAAC;IAAA,CACD;IAEO,IAAI,CAAC,OAAgB,EAAmB;QAC/C,OAAO,IAAI,CAAC,UAAU;aACpB,YAAY,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC;aAC7C,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,mCAAmC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;IAAA,CACnG;IAEO,UAAU,GAAS;QAC1B,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAAA,CAC/D;CACD","sourcesContent":["import { uuidv7 } from \"@earendil-works/pi-ai/utils/uuid\";\nimport type { Context } from \"../../context.ts\";\nimport type { FileInfo, FileSystem } from \"../../types.ts\";\nimport { StorageBackedSession } from \"../session.ts\";\nimport type { ForkOptions, Session, SessionRepo } from \"../types.ts\";\nimport { parseJsonlSessionHeader } from \"./codec.ts\";\nimport { type JsonlForkInput, runJsonlFork } from \"./fork.ts\";\nimport { fileValue } from \"./io.ts\";\nimport { LegacyV3Source, metadataFromLegacyV3Header } from \"./legacy-v3.ts\";\nimport { JsonlStorage } from \"./storage.ts\";\nimport {\n\tJSONL_FORMAT_VERSION,\n\tJSONL_STORAGE_VERSION,\n\ttype JsonlSessionCreateOptions,\n\ttype JsonlSessionListOptions,\n\ttype JsonlSessionMetadata,\n\ttype JsonlSessionRepoOptions,\n\ttype JsonlStorageHeader,\n} from \"./types.ts\";\n\nfunction metadataFromHeader(header: JsonlStorageHeader, path: string, modifiedAt: number): JsonlSessionMetadata {\n\treturn {\n\t\tid: header.id,\n\t\tcreatedAt: header.createdAt,\n\t\tstorageVersion: header.storageVersion,\n\t\tcwd: header.cwd,\n\t\tpath,\n\t\tmodifiedAt,\n\t\t...(header.parentSessionId === undefined ? {} : { parentSessionId: header.parentSessionId }),\n\t\t...(header.legacyParentSessionPath === undefined\n\t\t\t? {}\n\t\t\t: { legacyParentSessionPath: header.legacyParentSessionPath }),\n\t};\n}\n\nfunction sessionDirectoryName(cwd: string): string {\n\treturn `--${cwd.replace(/^[/\\\\]/, \"\").replace(/[/\\\\:]/g, \"-\")}--`;\n}\n\nfunction sessionFileName(createdAt: number, id: string): string {\n\tconst timestamp = new Date(createdAt).toISOString().replace(/[:.]/g, \"-\");\n\treturn `${timestamp}_${encodeURIComponent(id)}.jsonl`;\n}\n\n/** File-backed format-4 session repository lifecycle. */\nexport class JsonlSessionRepo\n\timplements SessionRepo<JsonlSessionMetadata, JsonlSessionCreateOptions, JsonlSessionListOptions>\n{\n\tprivate readonly fileSystem: FileSystem;\n\tprivate readonly sessionsRootInput: string;\n\tprivate readonly now: () => number;\n\tprivate readonly openSessions = new Map<string, JsonlStorage>();\n\tprivate readonly pendingCreates = new Set<string>();\n\tprivate closed = false;\n\tprivate closePromise: Promise<void> | undefined;\n\n\tconstructor(options: JsonlSessionRepoOptions) {\n\t\tthis.fileSystem = options.fileSystem;\n\t\tthis.sessionsRootInput = options.sessionsRoot;\n\t\tthis.now = options.now ?? Date.now;\n\t}\n\n\tasync create(options: JsonlSessionCreateOptions, context: Context): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst createdAt = this.now();\n\t\tconst { cwd, id } = await this.resolveCreateDestination(options.cwd, options.id, createdAt, context);\n\t\tconst key = this.sessionKey(cwd, id);\n\t\tif (this.openSessions.has(key) || this.pendingCreates.has(key)) throw new Error(`Session already exists: ${id}`);\n\t\tthis.pendingCreates.add(key);\n\t\tlet path: string | undefined;\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tpath = await this.resolveNewSessionPath(cwd, createdAt, id, context);\n\t\t\tconst header: JsonlStorageHeader = {\n\t\t\t\tv: JSONL_FORMAT_VERSION,\n\t\t\t\tkind: \"header\",\n\t\t\t\tid,\n\t\t\t\tstorageVersion: JSONL_STORAGE_VERSION,\n\t\t\t\tcreatedAt,\n\t\t\t\tcwd,\n\t\t\t\t...(options.parentSessionId === undefined ? {} : { parentSessionId: options.parentSessionId }),\n\t\t\t};\n\t\t\tstorage = await JsonlStorage.create({ fileSystem: this.fileSystem, path, now: this.now }, header, [], context);\n\t\t\tconst info = fileValue(await this.fileSystem.fileInfo(path, context), `Failed to read session ${path}`);\n\t\t\treturn this.publishOpenSession(metadataFromHeader(header, path, info.mtimeMs), storage, key);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context).catch(() => undefined);\n\t\t\tif (path !== undefined) await this.fileSystem.remove(path, { force: true }, context);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingCreates.delete(key);\n\t\t}\n\t}\n\n\tasync open(metadata: JsonlSessionMetadata, context: Context): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst key = this.sessionKey(metadata.cwd, metadata.id);\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is already open: ${metadata.id}`);\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tstorage = await this.loadStorage(metadata, context);\n\t\t\treturn this.publishOpenSession(metadata, storage, key);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync list(options: JsonlSessionListOptions | undefined, context: Context): Promise<JsonlSessionMetadata[]> {\n\t\toptions ??= {};\n\t\tthis.assertOpen();\n\t\tconst cwd =\n\t\t\toptions.cwd === undefined\n\t\t\t\t? undefined\n\t\t\t\t: fileValue(\n\t\t\t\t\t\tawait this.fileSystem.absolutePath(options.cwd, context),\n\t\t\t\t\t\t`Failed to resolve session cwd ${options.cwd}`,\n\t\t\t\t\t);\n\t\tconst root = await this.root(context);\n\t\tif (!fileValue(await this.fileSystem.exists(root, context), `Failed to check sessions root ${root}`)) return [];\n\t\tconst directories =\n\t\t\tcwd === undefined ? await this.sessionDirectories(root, context) : [await this.sessionDirectory(cwd, context)];\n\t\tconst metadata: JsonlSessionMetadata[] = [];\n\t\tfor (const directory of directories) metadata.push(...(await this.listDirectory(directory, cwd, context)));\n\t\treturn metadata.sort(\n\t\t\t(left, right) =>\n\t\t\t\tright.createdAt - left.createdAt || left.id.localeCompare(right.id) || left.cwd.localeCompare(right.cwd),\n\t\t);\n\t}\n\n\tasync delete(metadata: JsonlSessionMetadata, context: Context): Promise<void> {\n\t\tthis.assertOpen();\n\t\tconst key = this.sessionKey(metadata.cwd, metadata.id);\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is open: ${metadata.id}`);\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(metadata.path, context), `Failed to check session ${metadata.path}`)\n\t\t) {\n\t\t\tthrow new Error(`Session file does not exist: ${metadata.path}`);\n\t\t}\n\t\tfileValue(\n\t\t\tawait this.fileSystem.remove(metadata.path, undefined, context),\n\t\t\t`Failed to delete session ${metadata.path}`,\n\t\t);\n\t}\n\n\tasync fork(\n\t\tsource: JsonlSessionMetadata,\n\t\toptions: ForkOptions,\n\t\tcontext: Context,\n\t): Promise<Session<JsonlSessionMetadata>> {\n\t\tthis.assertOpen();\n\t\tconst createdAt = this.now();\n\t\tconst cwd = source.cwd;\n\t\tconst id = options.id ?? uuidv7(createdAt);\n\t\tconst destinationKey = this.sessionKey(cwd, id);\n\t\tif (this.openSessions.has(destinationKey) || this.pendingCreates.has(destinationKey)) {\n\t\t\tthrow new Error(`Session already exists: ${id}`);\n\t\t}\n\t\tthis.pendingCreates.add(destinationKey);\n\n\t\tconst sourceStorage = this.openSessions.get(this.sessionKey(source.cwd, source.id));\n\t\tlet path: string | undefined;\n\t\tlet storage: JsonlStorage | undefined;\n\t\ttry {\n\t\t\tconst input = await this.resolveForkInput(source, sourceStorage, context);\n\t\t\tpath = await this.resolveNewSessionPath(cwd, createdAt, id, context);\n\t\t\tconst header: Omit<JsonlStorageHeader, \"nextSeq\"> = {\n\t\t\t\tv: JSONL_FORMAT_VERSION,\n\t\t\t\tkind: \"header\",\n\t\t\t\tid,\n\t\t\t\tstorageVersion: JSONL_STORAGE_VERSION,\n\t\t\t\tcreatedAt,\n\t\t\t\tcwd,\n\t\t\t\tparentSessionId: source.id,\n\t\t\t};\n\t\t\tawait runJsonlFork(\n\t\t\t\t{\n\t\t\t\t\tinput,\n\t\t\t\t\tfileSystem: this.fileSystem,\n\t\t\t\t\tdestinationPath: path,\n\t\t\t\t\tdestinationHeader: header,\n\t\t\t\t\tfork: options,\n\t\t\t\t},\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tstorage = await JsonlStorage.open({ fileSystem: this.fileSystem, path, now: this.now }, context);\n\t\t\tconst info = fileValue(await this.fileSystem.fileInfo(path, context), `Failed to read session ${path}`);\n\t\t\treturn this.publishOpenSession(metadataFromHeader(header, path, info.mtimeMs), storage, destinationKey);\n\t\t} catch (error) {\n\t\t\tawait storage?.close(context).catch(() => undefined);\n\t\t\tif (path !== undefined) await this.fileSystem.remove(path, { force: true }, context);\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.pendingCreates.delete(destinationKey);\n\t\t}\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closePromise !== undefined) return this.closePromise;\n\t\tthis.closed = true;\n\t\t// TODO: Define ownership semantics before deciding whether repository close should close session handles.\n\t\tthis.closePromise = Promise.resolve();\n\t\treturn this.closePromise;\n\t}\n\n\tprivate async resolveCreateDestination(\n\t\tcwdInput: string,\n\t\tid: string | undefined,\n\t\tcreatedAt: number,\n\t\tcontext: Context,\n\t): Promise<{ cwd: string; id: string }> {\n\t\tconst destinationId = id ?? uuidv7(createdAt);\n\t\tconst cwd = fileValue(\n\t\t\tawait this.fileSystem.absolutePath(cwdInput, context),\n\t\t\t`Failed to resolve session cwd ${cwdInput}`,\n\t\t);\n\t\treturn { cwd, id: destinationId };\n\t}\n\n\tprivate async listDirectory(\n\t\tdirectory: string,\n\t\tcwd: string | undefined,\n\t\tcontext: Context,\n\t): Promise<JsonlSessionMetadata[]> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(directory, context), `Failed to check sessions directory ${directory}`)\n\t\t) {\n\t\t\treturn [];\n\t\t}\n\t\tconst files = fileValue(\n\t\t\tawait this.fileSystem.listDir(directory, context),\n\t\t\t`Failed to list sessions directory ${directory}`,\n\t\t).filter((file) => file.kind !== \"directory\" && file.name.endsWith(\".jsonl\"));\n\t\tconst metadata: JsonlSessionMetadata[] = [];\n\t\tfor (const file of files) {\n\t\t\tconst discovered = await this.readSessionMetadata(file, context);\n\t\t\tif (discovered === undefined) continue;\n\t\t\t// Directory encoding is lossy: /a/b and /a-b both map to --a-b--.\n\t\t\tif (cwd === undefined || discovered.cwd === cwd) metadata.push(discovered);\n\t\t}\n\t\treturn metadata;\n\t}\n\n\tprivate async readSessionMetadata(file: FileInfo, context: Context): Promise<JsonlSessionMetadata | undefined> {\n\t\tconst lines = fileValue(\n\t\t\tawait this.fileSystem.readTextLines(file.path, { maxLines: 1 }, context),\n\t\t\t`Failed to read session header ${file.path}`,\n\t\t);\n\t\tif (lines[0] === undefined) return undefined;\n\t\tconst parsedHeader = parseJsonlSessionHeader(lines[0]);\n\t\tif (!parsedHeader.ok) return undefined;\n\t\tif (parsedHeader.value.format === \"v3-legacy\") {\n\t\t\tconst metadata = await metadataFromLegacyV3Header(this.fileSystem, parsedHeader.value.header, context);\n\t\t\treturn { ...metadata, path: file.path, modifiedAt: file.mtimeMs };\n\t\t}\n\t\treturn metadataFromHeader(parsedHeader.value.header, file.path, file.mtimeMs);\n\t}\n\n\tprivate async sessionDirectories(root: string, context: Context): Promise<string[]> {\n\t\treturn fileValue(await this.fileSystem.listDir(root, context), `Failed to list sessions root ${root}`)\n\t\t\t.filter((entry) => entry.kind === \"directory\")\n\t\t\t.map((entry) => entry.path);\n\t}\n\n\tprivate async sessionDirectory(cwd: string, context: Context): Promise<string> {\n\t\treturn fileValue(\n\t\t\tawait this.fileSystem.joinPath([await this.root(context), sessionDirectoryName(cwd)], context),\n\t\t\t`Failed to resolve sessions directory for ${cwd}`,\n\t\t);\n\t}\n\n\tprivate async resolveNewSessionPath(cwd: string, createdAt: number, id: string, context: Context): Promise<string> {\n\t\tconst directory = await this.sessionDirectory(cwd, context);\n\t\tawait this.assertSessionIdAvailable(directory, id, context);\n\t\tfileValue(\n\t\t\tawait this.fileSystem.createDir(directory, undefined, context),\n\t\t\t`Failed to create sessions directory ${directory}`,\n\t\t);\n\t\treturn fileValue(\n\t\t\tawait this.fileSystem.joinPath([directory, sessionFileName(createdAt, id)], context),\n\t\t\t`Failed to resolve path for session ${id}`,\n\t\t);\n\t}\n\n\tprivate async assertSessionIdAvailable(directory: string, id: string, context: Context): Promise<void> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(directory, context), `Failed to check sessions directory ${directory}`)\n\t\t)\n\t\t\treturn;\n\n\t\tconst suffix = `_${encodeURIComponent(id)}.jsonl`;\n\t\tconst idExists = fileValue(\n\t\t\tawait this.fileSystem.listDir(directory, context),\n\t\t\t`Failed to list sessions directory ${directory}`,\n\t\t).some((entry) => entry.kind !== \"directory\" && entry.name.endsWith(suffix));\n\t\tif (idExists) throw new Error(`Session already exists: ${id}`);\n\t}\n\n\tprivate async resolveForkInput(\n\t\tsource: JsonlSessionMetadata,\n\t\tstorage: JsonlStorage | undefined,\n\t\tcontext: Context,\n\t): Promise<JsonlForkInput> {\n\t\tif (storage !== undefined) {\n\t\t\tif (storage.isLegacyV3()) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Cannot fork an open legacy v3 JSONL session; commit a non-empty transaction to upgrade it to format 4 first\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst nextSeq = await storage.captureForkNextSeq(context);\n\t\t\treturn { kind: \"open\", metadata: source, nextSeq };\n\t\t}\n\t\tif (await this.isLegacyV3ForkSource(source, context)) {\n\t\t\tconst normalized = await LegacyV3Source.read(this.fileSystem, source.path, context);\n\t\t\tif (normalized.header.id !== source.id || normalized.header.cwd !== source.cwd) {\n\t\t\t\tthrow new Error(`Session identity does not match header: ${source.id}`);\n\t\t\t}\n\t\t\treturn { kind: \"legacy-v3\", normalized };\n\t\t}\n\t\treturn { kind: \"closed\", metadata: source };\n\t}\n\n\tprivate async isLegacyV3ForkSource(source: JsonlSessionMetadata, context: Context): Promise<boolean> {\n\t\tconst lines = fileValue(\n\t\t\tawait this.fileSystem.readTextLines(source.path, { maxLines: 1 }, context),\n\t\t\t`Failed to read session header ${source.path}`,\n\t\t);\n\t\tif (lines[0] === undefined) return false;\n\t\tconst parsed = parseJsonlSessionHeader(lines[0]);\n\t\treturn parsed.ok && parsed.value.format === \"v3-legacy\";\n\t}\n\n\tprivate publishOpenSession(\n\t\tmetadata: JsonlSessionMetadata,\n\t\tstorage: JsonlStorage,\n\t\tkey: string,\n\t): StorageBackedSession<JsonlSessionMetadata> {\n\t\tif (this.openSessions.has(key)) throw new Error(`Session is already open: ${metadata.id}`);\n\t\tconst session = new StorageBackedSession(metadata, storage, {\n\t\t\tonClose: () => {\n\t\t\t\tif (this.openSessions.get(key) === storage) this.openSessions.delete(key);\n\t\t\t},\n\t\t});\n\t\tthis.openSessions.set(key, storage);\n\t\treturn session;\n\t}\n\n\tprivate sessionKey(cwd: string, id: string): string {\n\t\treturn `${cwd}\\0${id}`;\n\t}\n\n\tprivate async loadStorage(metadata: JsonlSessionMetadata, context: Context): Promise<JsonlStorage> {\n\t\tif (\n\t\t\t!fileValue(await this.fileSystem.exists(metadata.path, context), `Failed to check session ${metadata.path}`)\n\t\t) {\n\t\t\tthrow new Error(`Session file does not exist: ${metadata.path}`);\n\t\t}\n\t\tconst storage = await JsonlStorage.open(\n\t\t\t{\n\t\t\t\tfileSystem: this.fileSystem,\n\t\t\t\tpath: metadata.path,\n\t\t\t\tnow: this.now,\n\t\t\t},\n\t\t\tcontext,\n\t\t);\n\t\ttry {\n\t\t\tif (storage.header.id !== metadata.id || storage.header.cwd !== metadata.cwd) {\n\t\t\t\tthrow new Error(`Session identity does not match header: ${metadata.id}`);\n\t\t\t}\n\t\t\tif (storage.header.storageVersion !== JSONL_STORAGE_VERSION) {\n\t\t\t\tthrow new Error(`Session ${metadata.id} uses unsupported storage version ${storage.header.storageVersion}`);\n\t\t\t}\n\t\t\treturn storage;\n\t\t} catch (error) {\n\t\t\tawait storage.close(context);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate root(context: Context): Promise<string> {\n\t\treturn this.fileSystem\n\t\t\t.absolutePath(this.sessionsRootInput, context)\n\t\t\t.then((result) => fileValue(result, `Failed to resolve sessions root ${this.sessionsRootInput}`));\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"JsonlSessionRepo is closed\");\n\t}\n}\n"]}
@@ -1,5 +1,4 @@
1
1
  import type { Context } from "../../context.ts";
2
- import { type ForkDestinationSnapshot, type ForkSourceSnapshot } from "../fork.ts";
3
2
  import type { CommitResult, Entry, EntryScan, EntryStructure, SessionStats, Storage, StorageBranchScan, UsageRow, UsageScan, Write } from "../types.ts";
4
3
  import type { ListElement, ListReadOptions, StoredValue, Value, ValueList } from "../values.ts";
5
4
  import { type JsonlStorageHeader, type JsonlStorageOptions } from "./types.ts";
@@ -16,9 +15,8 @@ export declare class JsonlStorage implements Storage {
16
15
  private closePromise;
17
16
  private constructor();
18
17
  static create(options: JsonlStorageOptions, header: JsonlStorageHeader, initialWrites: Write[], context: Context): Promise<JsonlStorage>;
19
- /** Atomically create storage from a complete prepared snapshot. */
20
- static createFromForkSnapshot(options: JsonlStorageOptions, header: JsonlStorageHeader, snapshot: ForkDestinationSnapshot, context: Context): Promise<JsonlStorage>;
21
18
  static open(options: JsonlStorageOptions, context: Context): Promise<JsonlStorage>;
19
+ private static openV4;
22
20
  private static openLegacyV3;
23
21
  private replayCommitted;
24
22
  commit(writes: Write[], context: Context): Promise<CommitResult>;
@@ -34,8 +32,9 @@ export declare class JsonlStorage implements Storage {
34
32
  scanUsage(query: UsageScan, _context: Context): Promise<UsageRow[]>;
35
33
  getStats(_context: Context): Promise<SessionStats>;
36
34
  private withImportedUsage;
37
- /** Capture the state needed to fork at one serialized boundary between commits. */
38
- captureForkSource(_context: Context): Promise<ForkSourceSnapshot>;
35
+ isLegacyV3(): boolean;
36
+ /** Capture the first sequence a later source commit would use. */
37
+ captureForkNextSeq(_context: Context): Promise<number>;
39
38
  close(_context: Context): Promise<void>;
40
39
  }
41
40
  //# sourceMappingURL=storage.d.ts.map