dsh-config-manager 0.1.69 → 0.1.70

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 (719) hide show
  1. package/README.md +59 -18
  2. package/README.zh-CN.md +29 -9
  3. package/lib/adapters/credentials.js +6 -3
  4. package/lib/adapters/file-collection.d.ts +21 -1
  5. package/lib/adapters/file-collection.js +32 -8
  6. package/lib/adapters/mcp.d.ts +12 -2
  7. package/lib/adapters/mcp.js +30 -13
  8. package/lib/adapters/plugin-files.d.ts +8 -0
  9. package/lib/adapters/plugin-files.js +36 -4
  10. package/lib/adapters/plugins.d.ts +28 -2
  11. package/lib/adapters/plugins.js +204 -55
  12. package/lib/adapters/prompts.d.ts +12 -2
  13. package/lib/adapters/prompts.js +34 -19
  14. package/lib/adapters/providers.js +5 -4
  15. package/lib/adapters/self.d.ts +20 -0
  16. package/lib/adapters/self.js +73 -0
  17. package/lib/adapters/sessions.d.ts +8 -0
  18. package/lib/adapters/sessions.js +47 -1
  19. package/lib/adapters/settings.d.ts +21 -3
  20. package/lib/adapters/settings.js +44 -7
  21. package/lib/adapters/skills.d.ts +36 -4
  22. package/lib/adapters/skills.js +222 -3
  23. package/lib/adapters/test-helpers.d.ts +31 -2
  24. package/lib/adapters/test-helpers.js +42 -5
  25. package/lib/adapters/workspaces.js +97 -5
  26. package/lib/cli/actions.d.ts +50 -3
  27. package/lib/cli/actions.js +103 -11
  28. package/lib/cli/help.d.ts +65 -0
  29. package/lib/cli/help.js +517 -0
  30. package/lib/cli/import-source.d.ts +32 -0
  31. package/lib/cli/import-source.js +178 -0
  32. package/lib/cli/index.d.ts +18 -2
  33. package/lib/cli/index.js +118 -90
  34. package/lib/cli/web/client-script.d.ts +8 -0
  35. package/lib/cli/web/client-script.js +11 -0
  36. package/lib/cli/web/http.d.ts +5 -0
  37. package/lib/cli/web/http.js +2 -1
  38. package/lib/cli/web/page.d.ts +16 -6
  39. package/lib/cli/web/page.js +102 -25
  40. package/lib/cli/web/routes.js +24 -5
  41. package/lib/cli/web/server.js +23 -2
  42. package/lib/client.d.ts +1019 -36
  43. package/lib/client.js +5529 -1571
  44. package/lib/core/analyzer.d.ts +15 -1
  45. package/lib/core/analyzer.js +114 -13
  46. package/lib/core/backup-plan.js +17 -1
  47. package/lib/core/backup.d.ts +8 -0
  48. package/lib/core/backup.js +28 -6
  49. package/lib/core/cache-cleaner.d.ts +10 -0
  50. package/lib/core/cache-cleaner.js +63 -22
  51. package/lib/core/checkpoint.d.ts +362 -0
  52. package/lib/core/checkpoint.js +1309 -0
  53. package/lib/core/journal.d.ts +37 -0
  54. package/lib/core/journal.js +69 -0
  55. package/lib/core/messages.d.ts +13 -0
  56. package/lib/core/messages.js +26 -0
  57. package/lib/core/model-tools.js +3 -0
  58. package/lib/core/patch-layers.d.ts +83 -0
  59. package/lib/core/patch-layers.js +110 -0
  60. package/lib/core/restore.d.ts +21 -0
  61. package/lib/core/restore.js +37 -3
  62. package/lib/core/rollback.js +6 -3
  63. package/lib/core/self-update.d.ts +52 -0
  64. package/lib/core/self-update.js +70 -0
  65. package/lib/core/session-health.d.ts +29 -5
  66. package/lib/core/session-health.js +28 -3
  67. package/lib/core/types.d.ts +126 -0
  68. package/lib/foreign/antigravity.d.ts +28 -0
  69. package/lib/foreign/antigravity.js +157 -0
  70. package/lib/foreign/bundle.d.ts +25 -0
  71. package/lib/foreign/bundle.js +79 -0
  72. package/lib/foreign/chatgpt.d.ts +6 -0
  73. package/lib/foreign/chatgpt.js +25 -0
  74. package/lib/foreign/claude-code.d.ts +3 -0
  75. package/lib/foreign/claude-code.js +85 -0
  76. package/lib/foreign/claude-sessions.d.ts +100 -0
  77. package/lib/foreign/claude-sessions.js +291 -0
  78. package/lib/foreign/cline.d.ts +6 -0
  79. package/lib/foreign/cline.js +27 -0
  80. package/lib/foreign/codex.d.ts +83 -0
  81. package/lib/foreign/codex.js +348 -0
  82. package/lib/foreign/continue.d.ts +9 -0
  83. package/lib/foreign/continue.js +65 -0
  84. package/lib/foreign/copilot.d.ts +39 -0
  85. package/lib/foreign/copilot.js +95 -0
  86. package/lib/foreign/crush.d.ts +11 -0
  87. package/lib/foreign/crush.js +57 -0
  88. package/lib/foreign/cursor.d.ts +87 -0
  89. package/lib/foreign/cursor.js +171 -0
  90. package/lib/foreign/dsh.d.ts +30 -0
  91. package/lib/foreign/dsh.js +101 -0
  92. package/lib/foreign/dsh4.d.ts +3 -0
  93. package/lib/foreign/dsh4.js +13 -0
  94. package/lib/foreign/gemini.d.ts +7 -0
  95. package/lib/foreign/gemini.js +44 -0
  96. package/lib/foreign/goose.d.ts +11 -0
  97. package/lib/foreign/goose.js +53 -0
  98. package/lib/foreign/grokbuild.d.ts +8 -0
  99. package/lib/foreign/grokbuild.js +25 -0
  100. package/lib/foreign/hermes.d.ts +2 -0
  101. package/lib/foreign/hermes.js +78 -0
  102. package/lib/foreign/kernel.d.ts +132 -0
  103. package/lib/foreign/kernel.js +569 -0
  104. package/lib/foreign/kilocode.d.ts +11 -0
  105. package/lib/foreign/kilocode.js +51 -0
  106. package/lib/foreign/kimi.d.ts +7 -0
  107. package/lib/foreign/kimi.js +47 -0
  108. package/lib/foreign/mimocode.d.ts +11 -0
  109. package/lib/foreign/mimocode.js +51 -0
  110. package/lib/foreign/openclaw.d.ts +7 -0
  111. package/lib/foreign/openclaw.js +46 -0
  112. package/lib/foreign/opencode.d.ts +11 -0
  113. package/lib/foreign/opencode.js +52 -0
  114. package/lib/foreign/pi.d.ts +7 -0
  115. package/lib/foreign/pi.js +48 -0
  116. package/lib/foreign/platform-paths.d.ts +66 -0
  117. package/lib/foreign/platform-paths.js +141 -0
  118. package/lib/foreign/qoder.d.ts +10 -0
  119. package/lib/foreign/qoder.js +49 -0
  120. package/lib/foreign/qwen.d.ts +7 -0
  121. package/lib/foreign/qwen.js +45 -0
  122. package/lib/foreign/read-antigravity.d.ts +57 -0
  123. package/lib/foreign/read-antigravity.js +504 -0
  124. package/lib/foreign/read-chatgpt.d.ts +20 -0
  125. package/lib/foreign/read-chatgpt.js +509 -0
  126. package/lib/foreign/read-claude-code.d.ts +24 -0
  127. package/lib/foreign/read-claude-code.js +234 -0
  128. package/lib/foreign/read-cline.d.ts +53 -0
  129. package/lib/foreign/read-cline.js +479 -0
  130. package/lib/foreign/read-codex.d.ts +75 -0
  131. package/lib/foreign/read-codex.js +842 -0
  132. package/lib/foreign/read-continue.d.ts +87 -0
  133. package/lib/foreign/read-continue.js +489 -0
  134. package/lib/foreign/read-copilot.d.ts +42 -0
  135. package/lib/foreign/read-copilot.js +267 -0
  136. package/lib/foreign/read-crush.d.ts +54 -0
  137. package/lib/foreign/read-crush.js +478 -0
  138. package/lib/foreign/read-cursor.d.ts +141 -0
  139. package/lib/foreign/read-cursor.js +705 -0
  140. package/lib/foreign/read-dsh.d.ts +43 -0
  141. package/lib/foreign/read-dsh.js +205 -0
  142. package/lib/foreign/read-dsh4.d.ts +14 -0
  143. package/lib/foreign/read-dsh4.js +27 -0
  144. package/lib/foreign/read-gemini.d.ts +55 -0
  145. package/lib/foreign/read-gemini.js +273 -0
  146. package/lib/foreign/read-goose.d.ts +25 -0
  147. package/lib/foreign/read-goose.js +322 -0
  148. package/lib/foreign/read-grokbuild.d.ts +34 -0
  149. package/lib/foreign/read-grokbuild.js +455 -0
  150. package/lib/foreign/read-hermes.d.ts +74 -0
  151. package/lib/foreign/read-hermes.js +690 -0
  152. package/lib/foreign/read-kilocode.d.ts +17 -0
  153. package/lib/foreign/read-kilocode.js +46 -0
  154. package/lib/foreign/read-kimi.d.ts +63 -0
  155. package/lib/foreign/read-kimi.js +719 -0
  156. package/lib/foreign/read-mimocode.d.ts +12 -0
  157. package/lib/foreign/read-mimocode.js +56 -0
  158. package/lib/foreign/read-openclaw.d.ts +51 -0
  159. package/lib/foreign/read-openclaw.js +445 -0
  160. package/lib/foreign/read-opencode.d.ts +150 -0
  161. package/lib/foreign/read-opencode.js +896 -0
  162. package/lib/foreign/read-pi.d.ts +56 -0
  163. package/lib/foreign/read-pi.js +411 -0
  164. package/lib/foreign/read-qoder.d.ts +54 -0
  165. package/lib/foreign/read-qoder.js +317 -0
  166. package/lib/foreign/read-qwen.d.ts +40 -0
  167. package/lib/foreign/read-qwen.js +326 -0
  168. package/lib/foreign/read-reasonix.d.ts +66 -0
  169. package/lib/foreign/read-reasonix.js +537 -0
  170. package/lib/foreign/read-teleagent.d.ts +15 -0
  171. package/lib/foreign/read-teleagent.js +68 -0
  172. package/lib/foreign/read-trae.d.ts +67 -0
  173. package/lib/foreign/read-trae.js +492 -0
  174. package/lib/foreign/read-vibe.d.ts +28 -0
  175. package/lib/foreign/read-vibe.js +364 -0
  176. package/lib/foreign/read-workbuddy.d.ts +49 -0
  177. package/lib/foreign/read-workbuddy.js +346 -0
  178. package/lib/foreign/read-zcode.d.ts +12 -0
  179. package/lib/foreign/read-zcode.js +38 -0
  180. package/lib/foreign/read-zed.d.ts +30 -0
  181. package/lib/foreign/read-zed.js +473 -0
  182. package/lib/foreign/reasonix.d.ts +6 -0
  183. package/lib/foreign/reasonix.js +20 -0
  184. package/lib/foreign/registry.d.ts +196 -0
  185. package/lib/foreign/registry.js +573 -0
  186. package/lib/foreign/session-ir.d.ts +186 -0
  187. package/lib/foreign/session-ir.js +391 -0
  188. package/lib/foreign/session-read.d.ts +102 -0
  189. package/lib/foreign/session-read.js +254 -0
  190. package/lib/foreign/session-source.d.ts +216 -0
  191. package/lib/foreign/session-source.js +453 -0
  192. package/lib/foreign/source-modules.d.ts +45 -0
  193. package/lib/foreign/source-modules.js +52 -0
  194. package/lib/foreign/sqlite.d.ts +61 -0
  195. package/lib/foreign/sqlite.js +404 -0
  196. package/lib/foreign/teleagent.d.ts +11 -0
  197. package/lib/foreign/teleagent.js +53 -0
  198. package/lib/foreign/trae.d.ts +6 -0
  199. package/lib/foreign/trae.js +20 -0
  200. package/lib/foreign/truth-table.d.ts +62 -0
  201. package/lib/foreign/truth-table.js +333 -0
  202. package/lib/foreign/types.d.ts +272 -0
  203. package/lib/foreign/types.js +2 -0
  204. package/lib/foreign/vibe.d.ts +6 -0
  205. package/lib/foreign/vibe.js +23 -0
  206. package/lib/foreign/workbuddy.d.ts +7 -0
  207. package/lib/foreign/workbuddy.js +45 -0
  208. package/lib/foreign/zcode.d.ts +11 -0
  209. package/lib/foreign/zcode.js +51 -0
  210. package/lib/foreign/zed.d.ts +11 -0
  211. package/lib/foreign/zed.js +53 -0
  212. package/lib/index.d.ts +154 -13
  213. package/lib/index.js +661 -84
  214. package/lib/market/github-repos.d.ts +28 -0
  215. package/lib/market/github-repos.js +43 -1
  216. package/lib/market/types.d.ts +1 -3
  217. package/lib/profiles/dsh-profile-manager.d.ts +54 -2
  218. package/lib/profiles/dsh-profile-manager.js +182 -11
  219. package/lib/profiles/dsh-profile-shared.d.ts +47 -0
  220. package/lib/profiles/dsh-profile-shared.js +15 -1
  221. package/lib/profiles/index.d.ts +1 -1
  222. package/lib/profiles/index.js +1 -1
  223. package/lib/routes/consult.js +51 -5
  224. package/lib/routes/foreign-context.d.ts +43 -0
  225. package/lib/routes/foreign-context.js +65 -0
  226. package/lib/routes/foreign.d.ts +11 -0
  227. package/lib/routes/foreign.js +208 -0
  228. package/lib/routes/import.d.ts +8 -0
  229. package/lib/routes/import.js +22 -1
  230. package/lib/routes/index.d.ts +2 -2
  231. package/lib/routes/index.js +4 -0
  232. package/lib/routes/kit.d.ts +4 -3
  233. package/lib/routes/market.js +0 -1
  234. package/lib/routes/prefs.d.ts +2 -1
  235. package/lib/routes/prefs.js +14 -2
  236. package/lib/routes/recovery.js +363 -3
  237. package/lib/routes/session-export.d.ts +117 -0
  238. package/lib/routes/session-export.js +270 -0
  239. package/lib/routes/snapshots.js +12 -2
  240. package/lib/routes/sync.js +82 -10
  241. package/lib/security/redaction.d.ts +14 -0
  242. package/lib/security/redaction.js +24 -9
  243. package/lib/security/secret-scanner.d.ts +27 -0
  244. package/lib/security/secret-scanner.js +54 -1
  245. package/lib/sync/autosync-scheduler.d.ts +13 -1
  246. package/lib/sync/autosync-scheduler.js +49 -26
  247. package/lib/sync/backup-files.js +6 -0
  248. package/lib/sync/gist/gist-transport.d.ts +91 -0
  249. package/lib/sync/gist/gist-transport.js +406 -0
  250. package/lib/sync/gist/messages.d.ts +22 -0
  251. package/lib/sync/gist/messages.js +46 -0
  252. package/lib/sync/s3/messages.d.ts +53 -0
  253. package/lib/sync/s3/messages.js +83 -0
  254. package/lib/sync/s3/s3-providers.d.ts +78 -0
  255. package/lib/sync/s3/s3-providers.js +156 -0
  256. package/lib/sync/s3/s3-transport.d.ts +126 -0
  257. package/lib/sync/s3/s3-transport.js +551 -0
  258. package/lib/sync/s3/sigv4.d.ts +107 -0
  259. package/lib/sync/s3/sigv4.js +196 -0
  260. package/lib/sync/sync-config.d.ts +250 -4
  261. package/lib/sync/sync-config.js +658 -57
  262. package/lib/sync/sync-engine.d.ts +1 -0
  263. package/lib/sync/sync-engine.js +4 -2
  264. package/lib/sync/sync-history.d.ts +1 -1
  265. package/lib/sync/webdav/webdav-transport.d.ts +31 -3
  266. package/lib/sync/webdav/webdav-transport.js +102 -18
  267. package/lib/ui/commands.d.ts +4 -3
  268. package/lib/ui/commands.js +41 -9
  269. package/lib/ui/disk-usage-view.d.ts +44 -0
  270. package/lib/ui/disk-usage-view.js +55 -1
  271. package/lib/ui/dsh-profiles-view.d.ts +53 -0
  272. package/lib/ui/dsh-profiles-view.js +56 -0
  273. package/lib/ui/foreign-view.d.ts +162 -0
  274. package/lib/ui/foreign-view.js +225 -0
  275. package/lib/ui/i18n.d.ts +77 -0
  276. package/lib/ui/i18n.js +164 -0
  277. package/lib/ui/session-inventory-view.d.ts +106 -0
  278. package/lib/ui/session-inventory-view.js +58 -0
  279. package/lib/ui/session-layout-view.d.ts +265 -0
  280. package/lib/ui/session-layout-view.js +271 -0
  281. package/lib/ui/sync-repository-picker.d.ts +98 -0
  282. package/lib/ui/sync-repository-picker.js +145 -0
  283. package/lib/ui/sync-settings-view.d.ts +143 -4
  284. package/lib/ui/sync-settings-view.js +231 -7
  285. package/lib/ui/types.d.ts +47 -0
  286. package/lib/utils/asar-read.d.ts +113 -0
  287. package/lib/utils/asar-read.js +523 -0
  288. package/lib/utils/env-lock.js +7 -2
  289. package/lib/utils/patch-yaml.d.ts +25 -0
  290. package/lib/utils/patch-yaml.js +62 -0
  291. package/lib/utils/paths.d.ts +10 -1
  292. package/lib/utils/paths.js +24 -3
  293. package/lib/utils/recursive-walk.js +12 -13
  294. package/lib/utils/session-format.d.ts +35 -2
  295. package/lib/utils/session-format.js +131 -5
  296. package/lib/utils/session-health-scan.d.ts +7 -1
  297. package/lib/utils/session-health-scan.js +369 -12
  298. package/lib/utils/session-layout-repair-service.d.ts +98 -0
  299. package/lib/utils/session-layout-repair-service.js +457 -0
  300. package/lib/utils/session-log-repair.d.ts +27 -0
  301. package/lib/utils/session-log-repair.js +233 -62
  302. package/lib/utils/session-repair-service.d.ts +32 -3
  303. package/lib/utils/session-repair-service.js +148 -9
  304. package/lib/utils/session-row-facts.d.ts +73 -0
  305. package/lib/utils/session-row-facts.js +182 -0
  306. package/lib/utils/session-verify.d.ts +118 -0
  307. package/lib/utils/session-verify.js +705 -0
  308. package/lib/utils/shared-constants.d.ts +59 -0
  309. package/lib/utils/shared-constants.js +71 -0
  310. package/package.json +1 -1
  311. package/src/adapters/credentials.test.ts +27 -0
  312. package/src/adapters/credentials.ts +6 -3
  313. package/src/adapters/file-collection.ts +33 -8
  314. package/src/adapters/files.test.ts +222 -0
  315. package/src/adapters/mcp.test.ts +43 -0
  316. package/src/adapters/mcp.ts +37 -14
  317. package/src/adapters/plugin-files.ts +34 -4
  318. package/src/adapters/plugins.test.ts +241 -0
  319. package/src/adapters/plugins.ts +201 -53
  320. package/src/adapters/prompts.test.ts +49 -0
  321. package/src/adapters/prompts.ts +41 -20
  322. package/src/adapters/providers.test.ts +16 -0
  323. package/src/adapters/providers.ts +4 -3
  324. package/src/adapters/self.test.ts +77 -0
  325. package/src/adapters/self.ts +75 -0
  326. package/src/adapters/sessions.test.ts +77 -0
  327. package/src/adapters/sessions.ts +47 -1
  328. package/src/adapters/settings.test.ts +78 -0
  329. package/src/adapters/settings.ts +42 -6
  330. package/src/adapters/skills.ts +221 -3
  331. package/src/adapters/test-helpers.ts +43 -5
  332. package/src/adapters/workspaces-dup-id.test.ts +144 -0
  333. package/src/adapters/workspaces.test.ts +10 -0
  334. package/src/adapters/workspaces.ts +97 -5
  335. package/src/cli/actions.test.ts +117 -2
  336. package/src/cli/actions.ts +132 -12
  337. package/src/cli/help.ts +570 -0
  338. package/src/cli/import-source.test.ts +193 -0
  339. package/src/cli/import-source.ts +229 -0
  340. package/src/cli/index.ts +129 -94
  341. package/src/cli/web/client-script.ts +12 -0
  342. package/src/cli/web/console-fixes.test.ts +36 -0
  343. package/src/cli/web/http.ts +7 -1
  344. package/src/cli/web/page.ts +108 -25
  345. package/src/cli/web/routes.ts +23 -4
  346. package/src/cli/web/script-anchor.test.ts +33 -0
  347. package/src/cli/web/server.ts +28 -2
  348. package/src/cli/web/web.test.ts +447 -4
  349. package/src/client/ConfigManagerSection.tsx +118 -63
  350. package/src/client/about/AboutPanel.tsx +42 -3
  351. package/src/client/about/PluginUpdateDialog.tsx +185 -0
  352. package/src/client/about/ReleaseBody.tsx +144 -0
  353. package/src/client/about/ReleaseNotesDialog.tsx +3 -130
  354. package/src/client/about/about-view.ts +7 -5
  355. package/src/client/about/plugin-update-view.test.ts +25 -0
  356. package/src/client/about/plugin-update-view.ts +26 -0
  357. package/src/client/about/release-notes-view.test.ts +33 -0
  358. package/src/client/about/release-notes-view.ts +34 -0
  359. package/src/client/api.ts +145 -1
  360. package/src/client/common/Icon.tsx +3 -0
  361. package/src/client/common/RunsCenter.tsx +8 -2
  362. package/src/client/common/Select.tsx +9 -2
  363. package/src/client/common/info-hint-guard.test.ts +63 -18
  364. package/src/client/common/plan-text-redaction.test.ts +193 -8
  365. package/src/client/common/routes.ts +15 -0
  366. package/src/client/config-manager.module.css +506 -354
  367. package/src/client/css-scale-guard.test.ts +122 -0
  368. package/src/client/css-token-guard.test.ts +82 -0
  369. package/src/client/environment/EnvironmentPanel.tsx +45 -16
  370. package/src/client/{snapshots → environment/maintenance}/DiskUsageCard.tsx +21 -17
  371. package/src/client/environment/profiles-incomplete-ui.test.ts +103 -0
  372. package/src/client/export/ExportView.tsx +9 -2
  373. package/src/client/{snapshots → home}/BackupScheduleCard.tsx +13 -4
  374. package/src/client/home/HomePanel.tsx +69 -157
  375. package/src/client/icon-layer-guard.test.ts +1 -1
  376. package/src/client/import/ForeignImportView.tsx +318 -0
  377. package/src/client/import/ImportWizardView.tsx +3 -1
  378. package/src/client/import/foreign-import-view-guard.test.ts +195 -0
  379. package/src/client/import/import-file-select.test.ts +6 -6
  380. package/src/client/import/import-wizard-steps.tsx +17 -1
  381. package/src/client/import/use-import-wizard-controller.ts +3 -3
  382. package/src/client/index.ts +1 -1
  383. package/src/client/library/LibraryActions.tsx +31 -34
  384. package/src/client/library/LibraryPanel.tsx +4 -1
  385. package/src/client/{snapshots → library}/RestorePlanView.tsx +1 -1
  386. package/src/client/{snapshots → library}/files-layout.test.ts +2 -2
  387. package/src/client/{snapshots → library}/report-dismiss.test.ts +26 -3
  388. package/src/client/library/task-panel-visibility.test.ts +25 -17
  389. package/src/client/locales.ts +278 -36
  390. package/src/client/lucide-icons.d.ts +1 -0
  391. package/src/client/market/MarketPanel.tsx +11 -2
  392. package/src/client/recovery/IncompleteCopiesSection.tsx +132 -0
  393. package/src/client/recovery/RecoveryPanel.tsx +486 -59
  394. package/src/client/recovery/recovery-api.ts +30 -0
  395. package/src/client/recovery/recovery-incomplete-copies.test.ts +151 -0
  396. package/src/client/recovery/recovery-locales.test.ts +88 -0
  397. package/src/client/recovery/recovery-locales.ts +321 -6
  398. package/src/client/recovery/recovery-panel-layout.test.ts +52 -0
  399. package/src/client/recovery/recovery-view.ts +92 -2
  400. package/src/client/run-store.test.ts +201 -89
  401. package/src/client/run-store.ts +114 -143
  402. package/src/client/session-export/session-export-view.test.ts +103 -0
  403. package/src/client/session-export/session-export-view.ts +118 -0
  404. package/src/client/sync/ChannelConfigDialog.tsx +219 -14
  405. package/src/client/sync/SyncChannelEntryCard.tsx +52 -4
  406. package/src/client/sync/SyncLogList.tsx +1 -1
  407. package/src/client/sync/SyncPanel.tsx +166 -102
  408. package/src/client/sync/SyncRepositoryPicker.tsx +216 -0
  409. package/src/client/sync/SyncSettingsView.test.ts +6 -1
  410. package/src/client/sync/history-model.test.ts +94 -57
  411. package/src/client/sync/history-model.ts +44 -25
  412. package/src/client/sync/sync-api.test.ts +56 -0
  413. package/src/client/sync/sync-api.ts +92 -0
  414. package/src/client/sync/sync-locales.ts +162 -2
  415. package/src/client/sync/sync-view.test.ts +3 -8
  416. package/src/client/sync/sync-view.ts +111 -21
  417. package/src/core/analyzer-cache.test.ts +47 -0
  418. package/src/core/analyzer.ts +115 -14
  419. package/src/core/backup-plan.test.ts +35 -0
  420. package/src/core/backup-plan.ts +19 -1
  421. package/src/core/backup.test.ts +37 -1
  422. package/src/core/backup.ts +27 -6
  423. package/src/core/cache-cleaner.test.ts +120 -1
  424. package/src/core/cache-cleaner.ts +59 -22
  425. package/src/core/checkpoint.test.ts +665 -0
  426. package/src/core/checkpoint.ts +1614 -0
  427. package/src/core/credential-plan-consistency.test.ts +93 -0
  428. package/src/core/incident-wiring.test.ts +6 -2
  429. package/src/core/journal.test.ts +70 -0
  430. package/src/core/journal.ts +68 -0
  431. package/src/core/messages.ts +26 -0
  432. package/src/core/model-tools.ts +3 -0
  433. package/src/core/patch-layers.test.ts +94 -0
  434. package/src/core/patch-layers.ts +150 -0
  435. package/src/core/restore.ts +59 -3
  436. package/src/core/rollback.ts +6 -3
  437. package/src/core/section-content-consistency.test.ts +185 -0
  438. package/src/core/self-update.test.ts +110 -0
  439. package/src/core/self-update.ts +118 -0
  440. package/src/core/session-health.test.ts +91 -1
  441. package/src/core/session-health.ts +56 -9
  442. package/src/core/types.ts +127 -1
  443. package/src/foreign/antigravity.test.ts +271 -0
  444. package/src/foreign/antigravity.ts +188 -0
  445. package/src/foreign/bundle.ts +108 -0
  446. package/src/foreign/chatgpt.test.ts +279 -0
  447. package/src/foreign/chatgpt.ts +30 -0
  448. package/src/foreign/claude-code.test.ts +234 -0
  449. package/src/foreign/claude-code.ts +106 -0
  450. package/src/foreign/claude-sessions-bytes.test.ts +214 -0
  451. package/src/foreign/claude-sessions.test.ts +155 -0
  452. package/src/foreign/claude-sessions.ts +453 -0
  453. package/src/foreign/cline.test.ts +274 -0
  454. package/src/foreign/cline.ts +32 -0
  455. package/src/foreign/codex.test.ts +585 -0
  456. package/src/foreign/codex.ts +409 -0
  457. package/src/foreign/continue.test.ts +365 -0
  458. package/src/foreign/continue.ts +73 -0
  459. package/src/foreign/copilot.test.ts +273 -0
  460. package/src/foreign/copilot.ts +133 -0
  461. package/src/foreign/crush.test.ts +234 -0
  462. package/src/foreign/crush.ts +66 -0
  463. package/src/foreign/cursor.test.ts +509 -0
  464. package/src/foreign/cursor.ts +259 -0
  465. package/src/foreign/dsh.test.ts +198 -0
  466. package/src/foreign/dsh.ts +117 -0
  467. package/src/foreign/dsh4.test.ts +127 -0
  468. package/src/foreign/dsh4.ts +15 -0
  469. package/src/foreign/file-budget.test.ts +256 -0
  470. package/src/foreign/fixtures/antigravity/README.md +18 -0
  471. package/src/foreign/fixtures/antigravity/basic/gemini/antigravity/mcp_config.json +13 -0
  472. package/src/foreign/fixtures/antigravity/basic/gemini/config/mcp_config.json +24 -0
  473. package/src/foreign/fixtures/antigravity/empty/gemini/antigravity/mcp_config.json +0 -0
  474. package/src/foreign/fixtures/antigravity/empty/gemini/antigravity/mcp_oauth_tokens.json +0 -0
  475. package/src/foreign/fixtures/antigravity/empty/gemini/config/mcp_config.json +0 -0
  476. package/src/foreign/fixtures/codex/README.md +31 -0
  477. package/src/foreign/fixtures/codex/basic/.agents/skills/hello/SKILL.md +6 -0
  478. package/src/foreign/fixtures/codex/basic/.agents/skills/wrapper/nested/SKILL.md +6 -0
  479. package/src/foreign/fixtures/codex/basic/.codex/AGENTS.md +4 -0
  480. package/src/foreign/fixtures/codex/basic/.codex/config.toml +28 -0
  481. package/src/foreign/fixtures/codex/malformed/.codex/config.toml +3 -0
  482. package/src/foreign/fixtures/codex/override/.codex/AGENTS.md +1 -0
  483. package/src/foreign/fixtures/codex/override/.codex/AGENTS.override.md +3 -0
  484. package/src/foreign/fixtures/codex/sessions/.codex/archived_sessions/rollout-2026-10-05T09-00-00-22222222-2222-4222-8222-222222222222.jsonl +2 -0
  485. package/src/foreign/fixtures/codex/sessions/.codex/sessions/2026/10/06/rollout-2026-10-06T10-00-00-11111111-1111-4111-8111-111111111111.jsonl +15 -0
  486. package/src/foreign/fixtures/codex/sessions/.codex/sessions/2026/10/06/rollout-2026-10-06T11-00-00-33333333-3333-4333-8333-333333333333.jsonl +2 -0
  487. package/src/foreign/fixtures/codex/sessions/.codex/sessions/2026/10/06/rollout-2026-10-06T11-30-00-55555555-5555-4555-8555-555555555555.jsonl +2 -0
  488. package/src/foreign/fixtures/codex/sessions/.codex/sessions/2026/10/06/rollout-2026-10-06T12-00-00-44444444-4444-4444-8444-444444444444.jsonl +2 -0
  489. package/src/foreign/fixtures/codex/sessions/.codex/sessions/notes.jsonl +1 -0
  490. package/src/foreign/fixtures/copilot/README.md +22 -0
  491. package/src/foreign/fixtures/copilot/basic/copilot-instructions.md +3 -0
  492. package/src/foreign/fixtures/copilot/basic/instructions/empty.instructions.md +1 -0
  493. package/src/foreign/fixtures/copilot/basic/instructions/repo.instructions.md +5 -0
  494. package/src/foreign/fixtures/copilot/basic/mcp-config.json +24 -0
  495. package/src/foreign/fixtures/copilot/basic/skills/hello/SKILL.md +6 -0
  496. package/src/foreign/fixtures/copilot/overridden/mcp-config.json +10 -0
  497. package/src/foreign/fixtures/cursor/README.md +17 -0
  498. package/src/foreign/fixtures/cursor/alt/.cursor/mcp.json +5 -0
  499. package/src/foreign/fixtures/cursor/basic/.cursor/mcp.json +18 -0
  500. package/src/foreign/fixtures/cursor/basic/.cursor/rules/agent.mdc +5 -0
  501. package/src/foreign/fixtures/cursor/basic/.cursor/rules/always.mdc +6 -0
  502. package/src/foreign/fixtures/cursor/basic/.cursor/rules/auto.mdc +7 -0
  503. package/src/foreign/fixtures/cursor/basic/.cursor/rules/manual.mdc +3 -0
  504. package/src/foreign/fixtures/cursor/basic/.cursor/skills/.hidden/SKILL.md +6 -0
  505. package/src/foreign/fixtures/cursor/basic/.cursor/skills/hello/SKILL.md +6 -0
  506. package/src/foreign/fixtures/cursor/basic/.cursor/skills/wrapper/nested/SKILL.md +6 -0
  507. package/src/foreign/fixtures/cursor/basic/.cursor/skills/wrapper/nested/notes.md +1 -0
  508. package/src/foreign/fixtures/cursor/basic/.cursorrules +1 -0
  509. package/src/foreign/fixtures/cursor/basic/project/.cursor/mcp.json +9 -0
  510. package/src/foreign/fixtures/cursor/basic/project/.cursor/rules/project-always.mdc +5 -0
  511. package/src/foreign/fixtures/cursor/basic/project/.cursor/skills/hello/SKILL.md +6 -0
  512. package/src/foreign/fixtures/cursor/basic/project/.cursorrules +1 -0
  513. package/src/foreign/fixtures/cursor/empty/.cursor/mcp.json +0 -0
  514. package/src/foreign/fixtures/cursor/malformed/.cursor/mcp.json +3 -0
  515. package/src/foreign/fixtures/cursor/malformed/.cursor/rules/broken.mdc +6 -0
  516. package/src/foreign/fixtures/cursor/shape/.cursor/mcp.json +3 -0
  517. package/src/foreign/fixtures/hermes/README.md +14 -0
  518. package/src/foreign/fixtures/hermes/basic/SOUL.md +3 -0
  519. package/src/foreign/fixtures/hermes/basic/config.yaml +48 -0
  520. package/src/foreign/fixtures/hermes/basic/dotenv.fixture +1 -0
  521. package/src/foreign/fixtures/hermes/basic/memories/MEMORY.md +1 -0
  522. package/src/foreign/fixtures/hermes/basic/memories/USER.md +1 -0
  523. package/src/foreign/fixtures/hermes/basic/skills/se-team-design/SKILL.md +6 -0
  524. package/src/foreign/fixtures/hermes/basic/skills/se-team-design/examples/usage.md +1 -0
  525. package/src/foreign/fixtures/hermes/basic/skills/software-development/dogfood/SKILL.md +6 -0
  526. package/src/foreign/fixtures/hermes/basic/skills/software-development/dogfood/notes.md +1 -0
  527. package/src/foreign/fixtures/hermes/basic/state.db +1 -0
  528. package/src/foreign/fixtures/hermes/empty/config.yaml +0 -0
  529. package/src/foreign/gemini.test.ts +291 -0
  530. package/src/foreign/gemini.ts +52 -0
  531. package/src/foreign/goose.test.ts +196 -0
  532. package/src/foreign/goose.ts +62 -0
  533. package/src/foreign/grokbuild.test.ts +246 -0
  534. package/src/foreign/grokbuild.ts +30 -0
  535. package/src/foreign/hermes.test.ts +545 -0
  536. package/src/foreign/hermes.ts +86 -0
  537. package/src/foreign/kernel-credentials.test.ts +88 -0
  538. package/src/foreign/kernel-workspaces.test.ts +88 -0
  539. package/src/foreign/kernel.ts +584 -0
  540. package/src/foreign/kilocode.test.ts +186 -0
  541. package/src/foreign/kilocode.ts +60 -0
  542. package/src/foreign/kimi.test.ts +259 -0
  543. package/src/foreign/kimi.ts +55 -0
  544. package/src/foreign/mcp-value-shape.test.ts +286 -0
  545. package/src/foreign/mimocode.test.ts +178 -0
  546. package/src/foreign/mimocode.ts +60 -0
  547. package/src/foreign/openclaw.test.ts +248 -0
  548. package/src/foreign/openclaw.ts +54 -0
  549. package/src/foreign/opencode.test.ts +376 -0
  550. package/src/foreign/opencode.ts +61 -0
  551. package/src/foreign/pi.test.ts +275 -0
  552. package/src/foreign/pi.ts +56 -0
  553. package/src/foreign/platform-paths.ts +156 -0
  554. package/src/foreign/qoder.test.ts +266 -0
  555. package/src/foreign/qoder.ts +57 -0
  556. package/src/foreign/qwen.test.ts +203 -0
  557. package/src/foreign/qwen.ts +53 -0
  558. package/src/foreign/read-antigravity.ts +569 -0
  559. package/src/foreign/read-chatgpt.ts +506 -0
  560. package/src/foreign/read-claude-code.ts +264 -0
  561. package/src/foreign/read-cline.ts +517 -0
  562. package/src/foreign/read-codex.ts +823 -0
  563. package/src/foreign/read-continue.ts +557 -0
  564. package/src/foreign/read-copilot.ts +304 -0
  565. package/src/foreign/read-crush.ts +503 -0
  566. package/src/foreign/read-cursor.ts +778 -0
  567. package/src/foreign/read-dsh.ts +215 -0
  568. package/src/foreign/read-dsh4.ts +35 -0
  569. package/src/foreign/read-gemini.ts +306 -0
  570. package/src/foreign/read-goose.ts +333 -0
  571. package/src/foreign/read-grokbuild.ts +475 -0
  572. package/src/foreign/read-hermes.ts +724 -0
  573. package/src/foreign/read-kilocode.ts +55 -0
  574. package/src/foreign/read-kimi.ts +768 -0
  575. package/src/foreign/read-mimocode.ts +66 -0
  576. package/src/foreign/read-openclaw.ts +505 -0
  577. package/src/foreign/read-opencode.ts +994 -0
  578. package/src/foreign/read-pi.ts +459 -0
  579. package/src/foreign/read-qoder.ts +351 -0
  580. package/src/foreign/read-qwen.ts +342 -0
  581. package/src/foreign/read-reasonix.ts +590 -0
  582. package/src/foreign/read-teleagent.ts +82 -0
  583. package/src/foreign/read-trae.ts +488 -0
  584. package/src/foreign/read-vibe.ts +353 -0
  585. package/src/foreign/read-workbuddy.ts +374 -0
  586. package/src/foreign/read-zcode.ts +48 -0
  587. package/src/foreign/read-zed.ts +479 -0
  588. package/src/foreign/reasonix.test.ts +334 -0
  589. package/src/foreign/reasonix.ts +25 -0
  590. package/src/foreign/registry.test.ts +377 -0
  591. package/src/foreign/registry.ts +750 -0
  592. package/src/foreign/session-ir.test.ts +136 -0
  593. package/src/foreign/session-ir.ts +579 -0
  594. package/src/foreign/session-read.ts +295 -0
  595. package/src/foreign/session-source.ts +625 -0
  596. package/src/foreign/skill-file-caps.test.ts +171 -0
  597. package/src/foreign/source-modules.ts +86 -0
  598. package/src/foreign/source-registry.test.ts +190 -0
  599. package/src/foreign/sqlite.test.ts +313 -0
  600. package/src/foreign/sqlite.ts +446 -0
  601. package/src/foreign/teleagent.test.ts +147 -0
  602. package/src/foreign/teleagent.ts +62 -0
  603. package/src/foreign/trae.test.ts +316 -0
  604. package/src/foreign/trae.ts +25 -0
  605. package/src/foreign/truncation-report.test.ts +238 -0
  606. package/src/foreign/truth-table.ts +453 -0
  607. package/src/foreign/types.ts +312 -0
  608. package/src/foreign/vibe.test.ts +209 -0
  609. package/src/foreign/vibe.ts +28 -0
  610. package/src/foreign/workbuddy.test.ts +207 -0
  611. package/src/foreign/workbuddy.ts +53 -0
  612. package/src/foreign/zcode.test.ts +224 -0
  613. package/src/foreign/zcode.ts +60 -0
  614. package/src/foreign/zed.test.ts +240 -0
  615. package/src/foreign/zed.ts +62 -0
  616. package/src/index.facade.test.ts +254 -16
  617. package/src/index.ts +704 -82
  618. package/src/market/github-repos.test.ts +98 -1
  619. package/src/market/github-repos.ts +63 -1
  620. package/src/market/types.ts +3 -3
  621. package/src/profiles/dsh-profile-incomplete-copy.test.ts +177 -0
  622. package/src/profiles/dsh-profile-manager.test.ts +37 -0
  623. package/src/profiles/dsh-profile-manager.ts +188 -13
  624. package/src/profiles/dsh-profile-shared.ts +55 -1
  625. package/src/profiles/index.ts +2 -1
  626. package/src/routes/consult.ts +53 -4
  627. package/src/routes/foreign-context.ts +89 -0
  628. package/src/routes/foreign.test.ts +385 -0
  629. package/src/routes/foreign.ts +226 -0
  630. package/src/routes/import.ts +23 -1
  631. package/src/routes/index.ts +6 -2
  632. package/src/routes/kit.ts +4 -3
  633. package/src/routes/market.ts +0 -1
  634. package/src/routes/prefs.ts +15 -1
  635. package/src/routes/recovery.test.ts +167 -0
  636. package/src/routes/recovery.ts +331 -1
  637. package/src/routes/session-export.ts +308 -0
  638. package/src/routes/snapshots.ts +12 -2
  639. package/src/routes/sync.ts +91 -7
  640. package/src/security/redaction.test.ts +149 -0
  641. package/src/security/redaction.ts +25 -9
  642. package/src/security/secret-scanner.test.ts +186 -0
  643. package/src/security/secret-scanner.ts +57 -1
  644. package/src/sync/autosync-risk-tier.test.ts +61 -0
  645. package/src/sync/autosync-scheduler.test.ts +48 -1
  646. package/src/sync/autosync-scheduler.ts +50 -26
  647. package/src/sync/backup-files.ts +5 -0
  648. package/src/sync/gist/gist-msgkeys-catalog.test.ts +33 -0
  649. package/src/sync/gist/gist-msgkeys.test.ts +71 -0
  650. package/src/sync/gist/gist-transport.test.ts +308 -0
  651. package/src/sync/gist/gist-transport.ts +550 -0
  652. package/src/sync/gist/messages.ts +49 -0
  653. package/src/sync/retention-prune-all-off.test.ts +50 -0
  654. package/src/sync/s3/cloud-config.test.ts +283 -0
  655. package/src/sync/s3/messages.ts +102 -0
  656. package/src/sync/s3/s3-delete-index-404.test.ts +170 -0
  657. package/src/sync/s3/s3-delete-index-unreadable.test.ts +141 -0
  658. package/src/sync/s3/s3-msgkeys.test.ts +101 -0
  659. package/src/sync/s3/s3-providers.ts +213 -0
  660. package/src/sync/s3/s3-transport.test.ts +394 -0
  661. package/src/sync/s3/s3-transport.ts +651 -0
  662. package/src/sync/s3/s3-upload-index-404.test.ts +171 -0
  663. package/src/sync/s3/sigv4.test.ts +219 -0
  664. package/src/sync/s3/sigv4.ts +283 -0
  665. package/src/sync/sync-config.test.ts +237 -5
  666. package/src/sync/sync-config.ts +841 -52
  667. package/src/sync/sync-engine-download-tombstone.test.ts +73 -0
  668. package/src/sync/sync-engine.ts +5 -3
  669. package/src/sync/sync-history.ts +1 -1
  670. package/src/sync/webdav/webdav-delete-index-404.test.ts +178 -0
  671. package/src/sync/webdav/webdav-delete-index-unreadable.test.ts +143 -0
  672. package/src/sync/webdav/webdav-msgkeys.test.ts +53 -0
  673. package/src/sync/webdav/webdav-transport.test.ts +9 -5
  674. package/src/sync/webdav/webdav-transport.ts +99 -17
  675. package/src/sync/webdav/webdav-upload-index-404.test.ts +177 -0
  676. package/src/ui/commands.test.ts +4 -1
  677. package/src/ui/commands.ts +46 -12
  678. package/src/ui/disk-usage-view.test.ts +63 -1
  679. package/src/ui/disk-usage-view.ts +93 -1
  680. package/src/ui/dsh-profiles-incomplete-view.test.ts +102 -0
  681. package/src/ui/dsh-profiles-view.ts +94 -0
  682. package/src/ui/foreign-view.test.ts +241 -0
  683. package/src/ui/foreign-view.ts +362 -0
  684. package/src/ui/i18n.ts +164 -0
  685. package/src/ui/mid-ellipsis.test.ts +5 -10
  686. package/src/ui/session-inventory-view.test.ts +142 -2
  687. package/src/ui/session-inventory-view.ts +127 -0
  688. package/src/ui/session-layout-view.test.ts +361 -0
  689. package/src/ui/session-layout-view.ts +444 -0
  690. package/src/ui/sync-repository-picker.test.ts +130 -0
  691. package/src/ui/sync-repository-picker.ts +180 -0
  692. package/src/ui/sync-settings-view.test.ts +166 -0
  693. package/src/ui/sync-settings-view.ts +319 -9
  694. package/src/ui/types.ts +42 -0
  695. package/src/utils/asar-read.test.ts +330 -0
  696. package/src/utils/asar-read.ts +606 -0
  697. package/src/utils/env-lock.test.ts +55 -0
  698. package/src/utils/env-lock.ts +6 -1
  699. package/src/utils/patch-yaml.test.ts +112 -0
  700. package/src/utils/patch-yaml.ts +72 -0
  701. package/src/utils/paths.test.ts +63 -0
  702. package/src/utils/paths.ts +25 -3
  703. package/src/utils/recursive-walk.test.ts +20 -0
  704. package/src/utils/recursive-walk.ts +12 -13
  705. package/src/utils/session-format.test.ts +113 -2
  706. package/src/utils/session-format.ts +127 -5
  707. package/src/utils/session-health-scan.test.ts +364 -1
  708. package/src/utils/session-health-scan.ts +434 -15
  709. package/src/utils/session-layout-repair-service.test.ts +362 -0
  710. package/src/utils/session-layout-repair-service.ts +568 -0
  711. package/src/utils/session-log-repair.test.ts +260 -1
  712. package/src/utils/session-log-repair.ts +294 -55
  713. package/src/utils/session-repair-service.test.ts +148 -1
  714. package/src/utils/session-repair-service.ts +165 -10
  715. package/src/utils/session-row-facts.test.ts +159 -0
  716. package/src/utils/session-row-facts.ts +187 -0
  717. package/src/utils/session-verify.test.ts +762 -0
  718. package/src/utils/session-verify.ts +784 -0
  719. package/src/utils/shared-constants.ts +82 -0
@@ -0,0 +1,56 @@
1
+ import type { ForeignPlatform } from './platform-paths.ts';
2
+ import type { ParsedTranscript, RootProbeOptions, SessionReadOutcome, TranscriptShape } from './session-source.ts';
3
+ /** 相对用户 home 的位置标签前缀(回给 GUI/CLI 的**只允许路径**) */
4
+ export declare const PI_SESSIONS_REL = ".pi/agent/sessions";
5
+ /** 会话文件(JSONL 是唯一形态) */
6
+ export declare const PI_SESSION_FILE_RE: RegExp;
7
+ /** 会话目录名的包装:`--<cwd>--` */
8
+ export declare const PI_DIR_PREFIX = "--";
9
+ /** Pi 的会话根(三平台同形;真值表没有为它列任何环境变量覆盖) */
10
+ export declare function piSessionsDir(opts: RootProbeOptions): string;
11
+ /**
12
+ * 通用 JSONL 形态(**遗留**:Pi 走专用事件流解析,本常量只为保留既有公开导出名)。
13
+ */
14
+ export declare const PI_SHAPE: TranscriptShape;
15
+ /** 一条已解析的 Pi 会话 */
16
+ export interface PiSessionFile {
17
+ readonly id: string;
18
+ readonly parsed: ParsedTranscript;
19
+ }
20
+ export interface PiReadOptions extends RootProbeOptions {
21
+ readonly maxFileBytes?: number | undefined;
22
+ readonly maxSessionFiles?: number | undefined;
23
+ }
24
+ /**
25
+ * `--<cwd>--` 目录名 → 绝对路径**候选**(按目标平台排序;唯一判据是**存在性**)。
26
+ *
27
+ * 编码是有损的(路径里的 `-` 与分隔符同形),所以本函数只产出候选、**不做判断** ——
28
+ * 由调用方逐个 `isDirectory` 验真。两种编码形态都收:
29
+ * - `C:-Users-u-proj`(posix 形态的 `/`→`-`);
30
+ * - `C--Users-u-proj`(分隔符与冒号一起 → `-`)。
31
+ */
32
+ export declare function piCwdCandidates(dirName: string, platform: ForeignPlatform): string[];
33
+ /** 目录名反解 → 本机真实存在的目录(不存在 = undefined,**绝不猜**) */
34
+ export declare function derivedCwdOfDirName(dirName: string, platform: ForeignPlatform): Promise<string | undefined>;
35
+ /**
36
+ * 会话 id:头的 id > 文件名 `<timestamp>_<uuid>` 的 uuid 段 > 文件名主干。
37
+ * 自证安全性(isSafeIrId)留给下游 `transcodeSessionDraft` —— 不安全就报 session-unsafe-id,
38
+ * **绝不在这里悄悄换一个 id**。
39
+ */
40
+ export declare function piSessionIdOf(header: Record<string, unknown> | undefined, fileStem: string): string;
41
+ export interface PiParseOutcome {
42
+ /** 会话头(`type:"session"`);缺省 = 不是 Pi 会话文件 */
43
+ readonly header?: Record<string, unknown> | undefined;
44
+ readonly parsed: ParsedTranscript;
45
+ }
46
+ /**
47
+ * Pi 会话 JSONL(纯函数:原文 → 已归一记录)。
48
+ *
49
+ * 步骤:① 找会话头(`type:"session"`;没有 → `header` 留空,调用方跳过该文件);
50
+ * ② 其余条目按 `id/parentId` 组树(缺 id 的旧式条目按顺序链接);
51
+ * ③ 从末条目沿 `parentId` 走到根 = **活动分支**(visited 防环),旁支条目丢弃并计数;
52
+ * ④ 沿活动分支把 message 归一成记录,toolResult 挂回声明它的 assistant 记录之后;
53
+ * ⑤ 标题取活动分支上最后一个 `session_info.name`,缺省回退首条用户文本。
54
+ */
55
+ export declare function parsePiTranscript(text: string): PiParseOutcome;
56
+ export declare function readPiSessions(opts: PiReadOptions): Promise<SessionReadOutcome<PiSessionFile>>;
@@ -0,0 +1,411 @@
1
+ /**
2
+ * Pi(~\.pi/agent/sessions)用户目录的**读盘**层(宿主侧,node:fs)。
3
+ *
4
+ * 位置真值(read-chat-import.md §3.1 的 pi 行;交叉核对 read-movein.md 附录 A 与
5
+ * read-vault.md §10.2 —— 三份报告的根逐字一致,无出入):
6
+ * - 根:`<home>/.pi/agent/sessions`(三平台同形,**无环境变量覆盖**)
7
+ * - 布局:`<sessions>/--<cwd>--/<timestamp>_<uuid>.jsonl`
8
+ * - 形态:**首行 = 会话头**(`type:"session"`),其余条目 `id/parentId` 成树(convert/pi.mjs:14-27)
9
+ *
10
+ * 记录形态(本层单独解析,**不走通用 JSONL 解析**):条目是 `{type, id, parentId, …}`,
11
+ * 对话在 `{type:"message", message:{role, content}}` 里 —— role ∈ user / assistant /
12
+ * toolResult;assistant 的 content 块用**驼峰** `toolCall`(入参是 `arguments` 对象)、
13
+ * 思考是 `thinking`。三处与通用词表不同,必须专用解析(convert/pi.mjs)。
14
+ *
15
+ * 两条归一(都在本层做实):
16
+ * ① **活动分支**:从末条目沿 `parentId` 走到根,再反转为时间序(visited 防环);不在该路径上的
17
+ * 旁支条目丢弃并计入 `off-branch`(绝不把旁支内容混进对话)。缺 `id/parentId` 的旧式线性
18
+ * 条目按顺序链接(v1 语义)。
19
+ * ② 工具结果按 `toolCallId` 挂回**声明该调用的 assistant 记录之后**(共享合成器把 tool/result
20
+ * 收进当前打开的 step)。IR 没有 reasoning 块 → `thinking` / `compaction` / `branch_summary`
21
+ * 一律逐类计数,**不伪装成正文**(与 read-opencode / read-gemini 同口径)。
22
+ *
23
+ * cwd 的两档来源(绝不猜):会话头里的 cwd 字段(权威)→ 目录名反解。反解要过
24
+ * **存在性检查**(isDirectory)才落盘,并如实报 `session-cwd-derived`;反解不出真实目录时
25
+ * 不产出会话(下游按 `session-missing-cwd` 跳过)。没有会话头的文件不是 Pi 会话,跳过并报码。
26
+ *
27
+ * 取证强度:**fixture**(真值表 truth-table.ts 的 pi 行)。本机无 ~/.pi,夹具 + 单测端到端跑
28
+ * 同一份布局 —— **真机未验证,不得标 measured**。
29
+ *
30
+ * 读盘纪律:只读固定位置、不跟随符号链接、单文件有字节上限(超限即不读并报码,绝不截断)、
31
+ * 读不到一律记账不抛、结果排序确定。路径函数**显式收 platform**(joinFor)。
32
+ */
33
+ import fs from 'node:fs/promises';
34
+ import { isRecord } from '../utils/guards.js';
35
+ import { isAbsoluteFor, joinFor, normalizePlatform, sepFor } from './platform-paths.js';
36
+ import { DEFAULT_MAX_FILE_BYTES, isDirectory, parseJsonlText, statOrNull, stemOf, walkFiles, } from './session-read.js';
37
+ import { firstUserText, GENERIC_TRANSCRIPT_SHAPE } from './session-source.js';
38
+ import { irBump, irEarlier, irSafeTime, irStr, irTextBlock, irToolCallBlock, irToolResultBlock, } from './session-ir.js';
39
+ /** 相对用户 home 的位置标签前缀(回给 GUI/CLI 的**只允许路径**) */
40
+ export const PI_SESSIONS_REL = '.pi/agent/sessions';
41
+ /** 会话文件(JSONL 是唯一形态) */
42
+ export const PI_SESSION_FILE_RE = /\.jsonl$/;
43
+ /** 会话目录名的包装:`--<cwd>--` */
44
+ export const PI_DIR_PREFIX = '--';
45
+ const MAX_SESSION_FILES = 500;
46
+ /** 会话头里的 cwd 候选键(与记录层用同一族键) */
47
+ const HEADER_CWD_KEYS = ['cwd', 'workdir', 'working_directory', 'workingDir', 'directory'];
48
+ const HEADER_TIME_KEYS = ['timestamp', 'time', 'createdAt', 'created_at', 'startTime'];
49
+ /** Pi 的会话根(三平台同形;真值表没有为它列任何环境变量覆盖) */
50
+ export function piSessionsDir(opts) {
51
+ return joinFor(normalizePlatform(opts.platform), opts.homeDir, '.pi', 'agent', 'sessions');
52
+ }
53
+ /**
54
+ * 通用 JSONL 形态(**遗留**:Pi 走专用事件流解析,本常量只为保留既有公开导出名)。
55
+ */
56
+ export const PI_SHAPE = {
57
+ ...GENERIC_TRANSCRIPT_SHAPE,
58
+ cwdKeys: [...HEADER_CWD_KEYS, 'projectPath', 'project_path', 'workspacePath', 'workspace_path'],
59
+ titleKeys: ['title', 'summary', 'sessionTitle'],
60
+ };
61
+ /** 读一个文件(大小闸门在前,绝不截断);空文件 / 超限 / 读失败都变成稳定机器码 */
62
+ async function readTextGuarded(p, label, maxBytes, findings) {
63
+ const st = await statOrNull(p);
64
+ if (st === null || !st.isFile())
65
+ return null;
66
+ if (st.size > maxBytes) {
67
+ findings.push({ code: 'source-unreadable', origin: label, detail: 'too-large' });
68
+ return null;
69
+ }
70
+ let text;
71
+ try {
72
+ text = await fs.readFile(p, 'utf8');
73
+ }
74
+ catch {
75
+ findings.push({ code: 'source-unreadable', origin: label, detail: 'read-error' });
76
+ return null;
77
+ }
78
+ if (text.trim() === '') {
79
+ findings.push({ code: 'source-empty-file', origin: label });
80
+ return null;
81
+ }
82
+ return text;
83
+ }
84
+ /**
85
+ * `--<cwd>--` 目录名 → 绝对路径**候选**(按目标平台排序;唯一判据是**存在性**)。
86
+ *
87
+ * 编码是有损的(路径里的 `-` 与分隔符同形),所以本函数只产出候选、**不做判断** ——
88
+ * 由调用方逐个 `isDirectory` 验真。两种编码形态都收:
89
+ * - `C:-Users-u-proj`(posix 形态的 `/`→`-`);
90
+ * - `C--Users-u-proj`(分隔符与冒号一起 → `-`)。
91
+ */
92
+ export function piCwdCandidates(dirName, platform) {
93
+ const sep = sepFor(platform);
94
+ let inner = dirName.startsWith(PI_DIR_PREFIX) ? dirName.slice(PI_DIR_PREFIX.length) : dirName;
95
+ if (inner.endsWith(PI_DIR_PREFIX))
96
+ inner = inner.slice(0, inner.length - PI_DIR_PREFIX.length);
97
+ const out = [];
98
+ const driveA = /^([A-Za-z]):-?(.*)$/.exec(inner);
99
+ const driveB = /^([A-Za-z])--(.*)$/.exec(inner);
100
+ const formA = driveA === null ? undefined : driveA[1] + ':' + sep + (driveA[2] ?? '').split('-').join(sep);
101
+ const formB = driveB === null ? undefined : driveB[1] + ':' + sep + (driveB[2] ?? '').split('-').join(sep);
102
+ const posixForm = '/' + inner.split('-').join('/');
103
+ const ordered = platform === 'win32'
104
+ ? [formA, formB, inner, posixForm]
105
+ : [inner, posixForm, formA, formB];
106
+ for (const candidate of ordered) {
107
+ if (candidate === undefined || candidate === '')
108
+ continue;
109
+ if (!isAbsoluteFor(platform, candidate))
110
+ continue;
111
+ if (!out.includes(candidate))
112
+ out.push(candidate);
113
+ }
114
+ return out;
115
+ }
116
+ /** 目录名反解 → 本机真实存在的目录(不存在 = undefined,**绝不猜**) */
117
+ export async function derivedCwdOfDirName(dirName, platform) {
118
+ for (const candidate of piCwdCandidates(dirName, platform)) {
119
+ if (await isDirectory(candidate))
120
+ return candidate;
121
+ }
122
+ return undefined;
123
+ }
124
+ function headerCwd(header) {
125
+ if (header === undefined)
126
+ return undefined;
127
+ for (const key of HEADER_CWD_KEYS) {
128
+ const v = irStr(header[key]);
129
+ if (v !== undefined)
130
+ return v;
131
+ }
132
+ return undefined;
133
+ }
134
+ /**
135
+ * 会话 id:头的 id > 文件名 `<timestamp>_<uuid>` 的 uuid 段 > 文件名主干。
136
+ * 自证安全性(isSafeIrId)留给下游 `transcodeSessionDraft` —— 不安全就报 session-unsafe-id,
137
+ * **绝不在这里悄悄换一个 id**。
138
+ */
139
+ export function piSessionIdOf(header, fileStem) {
140
+ const fromHeader = header === undefined ? undefined : irStr(header['id']);
141
+ if (fromHeader !== undefined)
142
+ return fromHeader;
143
+ const underscore = fileStem.lastIndexOf('_');
144
+ if (underscore > 0 && underscore < fileStem.length - 1)
145
+ return fileStem.slice(underscore + 1);
146
+ return fileStem;
147
+ }
148
+ /* ---------------- 专用事件流解析(纯函数;不读盘) ---------------- */
149
+ /** 用户消息 content → 提问文本(string 原样;块数组取 text,image 降级为占位符) */
150
+ function piUserText(content) {
151
+ if (typeof content === 'string')
152
+ return content;
153
+ if (!Array.isArray(content))
154
+ return '';
155
+ const parts = [];
156
+ for (const block of content) {
157
+ if (!isRecord(block))
158
+ continue;
159
+ if (block['type'] === 'text' && typeof block['text'] === 'string' && block['text'].trim() !== '')
160
+ parts.push(block['text'].trim());
161
+ else if (block['type'] === 'image')
162
+ parts.push('[image: ' + (irStr(block['mimeType']) ?? 'image') + ']');
163
+ }
164
+ return parts.join('\n');
165
+ }
166
+ /** 工具结果 content → 纯文本(块数组取 text;image 降级为占位符) */
167
+ function piToolResultText(content) {
168
+ if (typeof content === 'string')
169
+ return content;
170
+ if (!Array.isArray(content))
171
+ return '';
172
+ const parts = [];
173
+ for (const block of content) {
174
+ if (!isRecord(block))
175
+ continue;
176
+ if (block['type'] === 'text' && typeof block['text'] === 'string')
177
+ parts.push(block['text']);
178
+ else if (block['type'] === 'image')
179
+ parts.push('[image: ' + (irStr(block['mimeType']) ?? 'image') + ']');
180
+ }
181
+ return parts.join('\n');
182
+ }
183
+ /** assistant content → IR 块(text / toolCall;thinking 与其余块逐类计数,IR 无承载块) */
184
+ function piAssistantBlocks(content, ignored, fallbackBase) {
185
+ if (!Array.isArray(content))
186
+ return [];
187
+ const out = [];
188
+ for (const block of content) {
189
+ if (!isRecord(block))
190
+ continue;
191
+ const type = irStr(block['type']);
192
+ if (type === 'text') {
193
+ if (typeof block['text'] === 'string')
194
+ out.push(irTextBlock(block['text']));
195
+ continue;
196
+ }
197
+ if (type === 'thinking') {
198
+ // IR 没有 reasoning 块 → 不伪装成正文,逐类计数(与 read-opencode / read-gemini 同口径)
199
+ irBump(ignored, 'block:thinking');
200
+ continue;
201
+ }
202
+ if (type === 'toolCall') {
203
+ // 驼峰 toolCall:入参是 arguments 对象(convert/pi.mjs 的 piToolCall)
204
+ const id = irStr(block['id']) ?? fallbackBase + '-' + String(out.length);
205
+ out.push(irToolCallBlock(id, irStr(block['name']) ?? 'unknown', block['arguments'] ?? {}));
206
+ continue;
207
+ }
208
+ if (type === 'image') {
209
+ out.push(irTextBlock('[image: ' + (irStr(block['mimeType']) ?? 'image') + ']'));
210
+ irBump(ignored, 'image-degraded');
211
+ continue;
212
+ }
213
+ irBump(ignored, 'block:' + (type ?? 'unmapped'));
214
+ }
215
+ return out;
216
+ }
217
+ /**
218
+ * Pi 会话 JSONL(纯函数:原文 → 已归一记录)。
219
+ *
220
+ * 步骤:① 找会话头(`type:"session"`;没有 → `header` 留空,调用方跳过该文件);
221
+ * ② 其余条目按 `id/parentId` 组树(缺 id 的旧式条目按顺序链接);
222
+ * ③ 从末条目沿 `parentId` 走到根 = **活动分支**(visited 防环),旁支条目丢弃并计数;
223
+ * ④ 沿活动分支把 message 归一成记录,toolResult 挂回声明它的 assistant 记录之后;
224
+ * ⑤ 标题取活动分支上最后一个 `session_info.name`,缺省回退首条用户文本。
225
+ */
226
+ export function parsePiTranscript(text) {
227
+ const { objects, bad } = parseJsonlText(text);
228
+ const ignored = {};
229
+ if (!objects.some((o) => o['type'] === 'session')) {
230
+ return { parsed: { records: [], cwd: undefined, createdAt: undefined, title: '', raw: objects.length, bad, ignored } };
231
+ }
232
+ const header = objects.find((o) => o['type'] === 'session');
233
+ if (header === undefined) {
234
+ return { parsed: { records: [], cwd: undefined, createdAt: undefined, title: '', raw: objects.length, bad, ignored } };
235
+ }
236
+ const entries = [];
237
+ for (const rec of objects) {
238
+ if (rec === header)
239
+ continue;
240
+ const id = irStr(rec['id']) ?? 'e' + String(entries.length);
241
+ const last = entries[entries.length - 1];
242
+ const parentId = typeof rec['parentId'] === 'string' ? rec['parentId'] : (last === undefined ? null : last.id);
243
+ entries.push({ rec, id, parentId });
244
+ }
245
+ // 活动分支:末条目即当前叶,沿 parentId 走到根(visited 防环),再反转为时间序
246
+ const byId = new Map(entries.map((e) => [e.id, e]));
247
+ const active = [];
248
+ let cursor = entries[entries.length - 1];
249
+ const seen = new Set();
250
+ while (cursor !== undefined) {
251
+ if (seen.has(cursor.id))
252
+ break;
253
+ seen.add(cursor.id);
254
+ active.push(cursor);
255
+ if (cursor.parentId === null)
256
+ break;
257
+ cursor = byId.get(cursor.parentId);
258
+ }
259
+ active.reverse();
260
+ const offBranch = entries.length - active.length;
261
+ if (offBranch > 0)
262
+ irBump(ignored, 'off-branch', offBranch);
263
+ const ordered = [];
264
+ const callOwner = new Map();
265
+ const callOrder = new Map();
266
+ const resultsOf = new Map();
267
+ let title = '';
268
+ let createdAt = irEarlier(undefined, headerTimeOf(header));
269
+ for (const entry of active) {
270
+ const rec = entry.rec;
271
+ const time = irSafeTime(rec['timestamp']);
272
+ createdAt = irEarlier(createdAt, time);
273
+ const type = irStr(rec['type']);
274
+ if (type === 'session_info') {
275
+ const name = irStr(rec['name']);
276
+ if (name !== undefined)
277
+ title = name;
278
+ continue;
279
+ }
280
+ if (type !== 'message') {
281
+ // model_change / label / custom / thinking_level_change / compaction / branch_summary …
282
+ // IR 无对等语义(更没有压缩检查点 / reasoning 块)→ 逐类计数,绝不静默
283
+ irBump(ignored, type ?? 'unknown');
284
+ continue;
285
+ }
286
+ const msg = rec['message'];
287
+ if (!isRecord(msg)) {
288
+ irBump(ignored, 'message:no-content');
289
+ continue;
290
+ }
291
+ const role = irStr(msg['role']);
292
+ if (role === 'user') {
293
+ const prompt = piUserText(msg['content']);
294
+ if (prompt.trim() === '') {
295
+ irBump(ignored, 'message:no-content');
296
+ continue;
297
+ }
298
+ ordered.push({ role: 'user', blocks: [irTextBlock(prompt)], time, id: entry.id });
299
+ continue;
300
+ }
301
+ if (role === 'assistant') {
302
+ const blocks = piAssistantBlocks(msg['content'], ignored, 'pi-' + String(ordered.length + 1));
303
+ const record = { role: 'assistant', blocks, time, id: entry.id };
304
+ let order = 0;
305
+ for (const block of blocks) {
306
+ if (block.type !== 'tool_call')
307
+ continue;
308
+ callOwner.set(block.id, record);
309
+ callOrder.set(block.id, order);
310
+ order += 1;
311
+ }
312
+ ordered.push(record);
313
+ continue;
314
+ }
315
+ if (role === 'toolResult') {
316
+ const callId = irStr(msg['toolCallId']);
317
+ const owner = callId === undefined ? undefined : callOwner.get(callId);
318
+ if (callId === undefined || owner === undefined) {
319
+ // 孤儿结果:没有声明它的调用 → 丢弃并计数(绝不塞进别的 step)
320
+ irBump(ignored, 'tool-result-orphan');
321
+ continue;
322
+ }
323
+ const list = resultsOf.get(owner) ?? [];
324
+ list.push({
325
+ record: {
326
+ role: 'user',
327
+ blocks: [irToolResultBlock(callId, piToolResultText(msg['content']), msg['isError'] === true)],
328
+ time,
329
+ id: entry.id,
330
+ },
331
+ order: callOrder.get(callId) ?? Number.MAX_SAFE_INTEGER,
332
+ });
333
+ resultsOf.set(owner, list);
334
+ continue;
335
+ }
336
+ // bashExecution / branchSummary / compactionSummary / custom …
337
+ irBump(ignored, 'role:' + (role ?? 'unknown'));
338
+ }
339
+ const records = [];
340
+ for (const rec of ordered) {
341
+ records.push(rec);
342
+ const results = resultsOf.get(rec);
343
+ if (results === undefined)
344
+ continue;
345
+ results.sort((a, b) => a.order - b.order);
346
+ for (const r of results)
347
+ records.push(r.record);
348
+ }
349
+ return {
350
+ header,
351
+ parsed: {
352
+ records,
353
+ cwd: headerCwd(header),
354
+ createdAt,
355
+ title: title === '' ? firstUserText(records) : title,
356
+ raw: objects.length,
357
+ bad,
358
+ ignored,
359
+ },
360
+ };
361
+ }
362
+ function headerTimeOf(header) {
363
+ for (const key of HEADER_TIME_KEYS) {
364
+ const t = irSafeTime(header[key]);
365
+ if (t !== undefined)
366
+ return t;
367
+ }
368
+ return undefined;
369
+ }
370
+ export async function readPiSessions(opts) {
371
+ const platform = normalizePlatform(opts.platform);
372
+ const sessionsDir = piSessionsDir(opts);
373
+ const maxBytes = opts.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES;
374
+ const maxFiles = opts.maxSessionFiles ?? MAX_SESSION_FILES;
375
+ const findings = [];
376
+ const files = [];
377
+ if (!(await isDirectory(sessionsDir))) {
378
+ return { files, readFindings: findings, extraCounts: { 'sessions.candidates': 0 } };
379
+ }
380
+ // 触顶必须**可见**(audit-foreign F4):候选数超过上限即报码,与是否成功解析无关
381
+ const candidates = await walkFiles(sessionsDir, { match: (n) => PI_SESSION_FILE_RE.test(n) });
382
+ const truncated = candidates.length > maxFiles;
383
+ const chosen = truncated ? candidates.slice(0, maxFiles) : candidates;
384
+ for (const file of chosen) {
385
+ const sep = file.rel.lastIndexOf('/');
386
+ const relDir = sep < 0 ? '' : file.rel.slice(0, sep);
387
+ const label = PI_SESSIONS_REL + (relDir === '' ? '' : '/' + relDir) + '/' + file.name;
388
+ const text = await readTextGuarded(file.abs, label, maxBytes, findings);
389
+ if (text === null)
390
+ continue;
391
+ const { header, parsed } = parsePiTranscript(text);
392
+ if (header === undefined) {
393
+ // 没有会话头 = 不是 Pi 会话文件(convert/pi.mjs:无头行即自拒)→ 跳过并如实报码
394
+ findings.push({ code: 'source-unreadable', origin: label, detail: 'not-a-session' });
395
+ continue;
396
+ }
397
+ const id = piSessionIdOf(header, stemOf(file.name));
398
+ const topDir = file.rel.split('/')[0] ?? '';
399
+ const derivedCwd = parsed.cwd === undefined && topDir.startsWith(PI_DIR_PREFIX)
400
+ ? await derivedCwdOfDirName(topDir, platform)
401
+ : undefined;
402
+ if (parsed.cwd === undefined && derivedCwd !== undefined) {
403
+ findings.push({ code: 'session-cwd-derived', origin: id, detail: 'session-dir-name' });
404
+ }
405
+ files.push({ id, parsed: { ...parsed, cwd: parsed.cwd ?? derivedCwd } });
406
+ }
407
+ if (truncated)
408
+ findings.push({ code: 'source-unreadable', origin: 'pi', detail: 'max-sessions-reached', count: maxFiles });
409
+ return { files, readFindings: findings, extraCounts: { 'sessions.candidates': files.length } };
410
+ }
411
+ //# sourceMappingURL=read-pi.js.map
@@ -0,0 +1,54 @@
1
+ import type { ForeignPlatform } from './platform-paths.ts';
2
+ import type { ParsedTranscript, RootProbeOptions, SessionReadOutcome, TranscriptShape } from './session-source.ts';
3
+ /** 相对用户 home 的位置标签前缀(回给 GUI/CLI 的**只允许路径**,绝不含用户名/盘符) */
4
+ export declare const QODER_PROJECTS_REL = ".qoder/projects";
5
+ /** 会话文件(在该来源里 JSONL 是唯一形态) */
6
+ export declare const QODER_SESSION_FILE_RE: RegExp;
7
+ /** Qoder 的项目根(三平台同形;真值表没有为它列任何环境变量覆盖) */
8
+ export declare function qoderProjectsDir(opts: RootProbeOptions): string;
9
+ /**
10
+ * 记录形态:与通用 JSONL 同族(`{role|type, message|content, timestamp, id}`)。
11
+ *
12
+ * 两处**收紧**(不是美化,而是避免误取):
13
+ * - `titleKeys` 去掉 `name`:JSONL 里的 `name` 常是工具名,拿它当标题会张冠李戴;
14
+ * - `cwdKeys` 加几个同义键(记录里带 cwd 时优先采信记录,见文件头 ①)。
15
+ */
16
+ export declare const QODER_SHAPE: TranscriptShape;
17
+ /** 一条已解析的 Qoder 会话(读盘层的产物;`parsed` 已含 cwd 判定结果) */
18
+ export interface QoderSessionFile {
19
+ readonly id: string;
20
+ readonly parsed: ParsedTranscript;
21
+ }
22
+ export interface QoderReadOptions extends RootProbeOptions {
23
+ /** 单文件读取上限(缺省 8 MiB);超限即不读并如实计入 findings */
24
+ readonly maxFileBytes?: number | undefined;
25
+ /** 本次最多收集多少条会话(缺省 500) */
26
+ readonly maxSessionFiles?: number | undefined;
27
+ }
28
+ /**
29
+ * 目录名(cwd 的 `/`→`-` 编码)→ 本机真实存在的目录;反解不出来就返回 undefined(绝不猜)。
30
+ *
31
+ * 两个候选形态(按平台决定先后,**存在性**是唯一判据):
32
+ * - posix 形态:`-home-u-proj` → `/home/u/proj`;
33
+ * - win32 盘符形态:`C--Users-u-proj` → `C:\Users\u\proj`。
34
+ */
35
+ export declare function derivedCwdOf(encoded: string, platform: ForeignPlatform): Promise<string | undefined>;
36
+ /**
37
+ * Qoder 的 JSONL 比通用 JSONL 多三类**只在本源有**的事实(所以这里不直接用
38
+ * `parseGenericJsonl`,否则要再扫一遍原始行才能拿到):
39
+ * ① `ai-title` / `last-prompt` 记录 —— 标题(ai-title > last-prompt > 首问兜底);
40
+ * ② 记录里的 `sessionId` —— 「文件名 stem == sessionId」的主体判定(辅助 / 子代理 transcript 跳过);
41
+ * ③ `tool_result` 缺 `tool_use_id` 时,按**未决调用顺序**回退配对(参考 convert/qoder.mjs)。
42
+ * `thinking` 块由 `genericBlocksOf` 逐类计数(`block:thinking`)—— 本地 IR 没有 reasoning 承载位,
43
+ * 只显式计数、绝不伪装成正文。
44
+ */
45
+ export interface QoderParseResult {
46
+ readonly parsed: ParsedTranscript;
47
+ /** 记录里自报的 sessionId(有则用于主体判定) */
48
+ readonly sessionId?: string | undefined;
49
+ /** 文件名 stem 与记录 sessionId 不一致(辅助 / 子代理 transcript) */
50
+ readonly stemMismatch: boolean;
51
+ }
52
+ /** 一份 Qoder transcript(JSONL)→ 归一记录 + 主体判定(`fileStem` = 文件名去掉 .jsonl) */
53
+ export declare function parseQoderJsonl(text: string, fileStem?: string): QoderParseResult;
54
+ export declare function readQoderSessions(opts: QoderReadOptions): Promise<SessionReadOutcome<QoderSessionFile>>;