@they-juanreina/compost-cli 0.1.0-rc.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 (362) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/bin/compost.js +7 -0
  4. package/dist/commands/_stub.d.ts +9 -0
  5. package/dist/commands/_stub.d.ts.map +1 -0
  6. package/dist/commands/_stub.js +27 -0
  7. package/dist/commands/_stub.js.map +1 -0
  8. package/dist/commands/blame.d.ts +3 -0
  9. package/dist/commands/blame.d.ts.map +1 -0
  10. package/dist/commands/blame.js +31 -0
  11. package/dist/commands/blame.js.map +1 -0
  12. package/dist/commands/chat.d.ts +8 -0
  13. package/dist/commands/chat.d.ts.map +1 -0
  14. package/dist/commands/chat.js +99 -0
  15. package/dist/commands/chat.js.map +1 -0
  16. package/dist/commands/code.d.ts +3 -0
  17. package/dist/commands/code.d.ts.map +1 -0
  18. package/dist/commands/code.js +70 -0
  19. package/dist/commands/code.js.map +1 -0
  20. package/dist/commands/config.d.ts +3 -0
  21. package/dist/commands/config.d.ts.map +1 -0
  22. package/dist/commands/config.js +76 -0
  23. package/dist/commands/config.js.map +1 -0
  24. package/dist/commands/create.d.ts +20 -0
  25. package/dist/commands/create.d.ts.map +1 -0
  26. package/dist/commands/create.js +148 -0
  27. package/dist/commands/create.js.map +1 -0
  28. package/dist/commands/endorse.d.ts +3 -0
  29. package/dist/commands/endorse.d.ts.map +1 -0
  30. package/dist/commands/endorse.js +31 -0
  31. package/dist/commands/endorse.js.map +1 -0
  32. package/dist/commands/evals.d.ts +3 -0
  33. package/dist/commands/evals.d.ts.map +1 -0
  34. package/dist/commands/evals.js +54 -0
  35. package/dist/commands/evals.js.map +1 -0
  36. package/dist/commands/export.d.ts +3 -0
  37. package/dist/commands/export.d.ts.map +1 -0
  38. package/dist/commands/export.js +54 -0
  39. package/dist/commands/export.js.map +1 -0
  40. package/dist/commands/ingest.d.ts +3 -0
  41. package/dist/commands/ingest.d.ts.map +1 -0
  42. package/dist/commands/ingest.js +26 -0
  43. package/dist/commands/ingest.js.map +1 -0
  44. package/dist/commands/init.d.ts +3 -0
  45. package/dist/commands/init.d.ts.map +1 -0
  46. package/dist/commands/init.js +51 -0
  47. package/dist/commands/init.js.map +1 -0
  48. package/dist/commands/migrate.d.ts +3 -0
  49. package/dist/commands/migrate.d.ts.map +1 -0
  50. package/dist/commands/migrate.js +28 -0
  51. package/dist/commands/migrate.js.map +1 -0
  52. package/dist/commands/models.d.ts +3 -0
  53. package/dist/commands/models.d.ts.map +1 -0
  54. package/dist/commands/models.js +32 -0
  55. package/dist/commands/models.js.map +1 -0
  56. package/dist/commands/query.d.ts +3 -0
  57. package/dist/commands/query.d.ts.map +1 -0
  58. package/dist/commands/query.js +13 -0
  59. package/dist/commands/query.js.map +1 -0
  60. package/dist/commands/reindex.d.ts +3 -0
  61. package/dist/commands/reindex.d.ts.map +1 -0
  62. package/dist/commands/reindex.js +53 -0
  63. package/dist/commands/reindex.js.map +1 -0
  64. package/dist/commands/rescan.d.ts +3 -0
  65. package/dist/commands/rescan.d.ts.map +1 -0
  66. package/dist/commands/rescan.js +60 -0
  67. package/dist/commands/rescan.js.map +1 -0
  68. package/dist/commands/saturate.d.ts +3 -0
  69. package/dist/commands/saturate.d.ts.map +1 -0
  70. package/dist/commands/saturate.js +35 -0
  71. package/dist/commands/saturate.js.map +1 -0
  72. package/dist/commands/search.d.ts +3 -0
  73. package/dist/commands/search.d.ts.map +1 -0
  74. package/dist/commands/search.js +52 -0
  75. package/dist/commands/search.js.map +1 -0
  76. package/dist/commands/serve.d.ts +3 -0
  77. package/dist/commands/serve.d.ts.map +1 -0
  78. package/dist/commands/serve.js +9 -0
  79. package/dist/commands/serve.js.map +1 -0
  80. package/dist/commands/session.d.ts +3 -0
  81. package/dist/commands/session.d.ts.map +1 -0
  82. package/dist/commands/session.js +25 -0
  83. package/dist/commands/session.js.map +1 -0
  84. package/dist/commands/setup.d.ts +3 -0
  85. package/dist/commands/setup.d.ts.map +1 -0
  86. package/dist/commands/setup.js +38 -0
  87. package/dist/commands/setup.js.map +1 -0
  88. package/dist/commands/snap.d.ts +3 -0
  89. package/dist/commands/snap.d.ts.map +1 -0
  90. package/dist/commands/snap.js +27 -0
  91. package/dist/commands/snap.js.map +1 -0
  92. package/dist/commands/status.d.ts +3 -0
  93. package/dist/commands/status.d.ts.map +1 -0
  94. package/dist/commands/status.js +26 -0
  95. package/dist/commands/status.js.map +1 -0
  96. package/dist/commands/synthesize.d.ts +3 -0
  97. package/dist/commands/synthesize.d.ts.map +1 -0
  98. package/dist/commands/synthesize.js +13 -0
  99. package/dist/commands/synthesize.js.map +1 -0
  100. package/dist/commands/tag.d.ts +3 -0
  101. package/dist/commands/tag.d.ts.map +1 -0
  102. package/dist/commands/tag.js +46 -0
  103. package/dist/commands/tag.js.map +1 -0
  104. package/dist/commands/transcribe.d.ts +3 -0
  105. package/dist/commands/transcribe.d.ts.map +1 -0
  106. package/dist/commands/transcribe.js +110 -0
  107. package/dist/commands/transcribe.js.map +1 -0
  108. package/dist/commands/validate.d.ts +3 -0
  109. package/dist/commands/validate.d.ts.map +1 -0
  110. package/dist/commands/validate.js +81 -0
  111. package/dist/commands/validate.js.map +1 -0
  112. package/dist/commands/watch.d.ts +3 -0
  113. package/dist/commands/watch.d.ts.map +1 -0
  114. package/dist/commands/watch.js +50 -0
  115. package/dist/commands/watch.js.map +1 -0
  116. package/dist/errors.d.ts +9 -0
  117. package/dist/errors.d.ts.map +1 -0
  118. package/dist/errors.js +12 -0
  119. package/dist/errors.js.map +1 -0
  120. package/dist/exporters/csv.d.ts +8 -0
  121. package/dist/exporters/csv.d.ts.map +1 -0
  122. package/dist/exporters/csv.js +44 -0
  123. package/dist/exporters/csv.js.map +1 -0
  124. package/dist/exporters/eaf.d.ts +3 -0
  125. package/dist/exporters/eaf.d.ts.map +1 -0
  126. package/dist/exporters/eaf.js +91 -0
  127. package/dist/exporters/eaf.js.map +1 -0
  128. package/dist/exporters/html.d.ts +8 -0
  129. package/dist/exporters/html.d.ts.map +1 -0
  130. package/dist/exporters/html.js +47 -0
  131. package/dist/exporters/html.js.map +1 -0
  132. package/dist/exporters/md.d.ts +3 -0
  133. package/dist/exporters/md.d.ts.map +1 -0
  134. package/dist/exporters/md.js +43 -0
  135. package/dist/exporters/md.js.map +1 -0
  136. package/dist/exporters/pdf.d.ts +9 -0
  137. package/dist/exporters/pdf.d.ts.map +1 -0
  138. package/dist/exporters/pdf.js +40 -0
  139. package/dist/exporters/pdf.js.map +1 -0
  140. package/dist/exporters/report.d.ts +43 -0
  141. package/dist/exporters/report.d.ts.map +1 -0
  142. package/dist/exporters/report.js +49 -0
  143. package/dist/exporters/report.js.map +1 -0
  144. package/dist/index.d.ts +2 -0
  145. package/dist/index.d.ts.map +1 -0
  146. package/dist/index.js +6 -0
  147. package/dist/index.js.map +1 -0
  148. package/dist/legacy_client.d.ts +38 -0
  149. package/dist/legacy_client.d.ts.map +1 -0
  150. package/dist/legacy_client.js +44 -0
  151. package/dist/legacy_client.js.map +1 -0
  152. package/dist/lib/answerSchema.d.ts +2 -0
  153. package/dist/lib/answerSchema.d.ts.map +1 -0
  154. package/dist/lib/answerSchema.js +27 -0
  155. package/dist/lib/answerSchema.js.map +1 -0
  156. package/dist/lib/artifacts.d.ts +64 -0
  157. package/dist/lib/artifacts.d.ts.map +1 -0
  158. package/dist/lib/artifacts.js +254 -0
  159. package/dist/lib/artifacts.js.map +1 -0
  160. package/dist/lib/blame.d.ts +30 -0
  161. package/dist/lib/blame.d.ts.map +1 -0
  162. package/dist/lib/blame.js +164 -0
  163. package/dist/lib/blame.js.map +1 -0
  164. package/dist/lib/canonicalSessions.d.ts +24 -0
  165. package/dist/lib/canonicalSessions.d.ts.map +1 -0
  166. package/dist/lib/canonicalSessions.js +48 -0
  167. package/dist/lib/canonicalSessions.js.map +1 -0
  168. package/dist/lib/chat.d.ts +24 -0
  169. package/dist/lib/chat.d.ts.map +1 -0
  170. package/dist/lib/chat.js +50 -0
  171. package/dist/lib/chat.js.map +1 -0
  172. package/dist/lib/config.d.ts +45 -0
  173. package/dist/lib/config.d.ts.map +1 -0
  174. package/dist/lib/config.js +143 -0
  175. package/dist/lib/config.js.map +1 -0
  176. package/dist/lib/dispatch.d.ts +10 -0
  177. package/dist/lib/dispatch.d.ts.map +1 -0
  178. package/dist/lib/dispatch.js +31 -0
  179. package/dist/lib/dispatch.js.map +1 -0
  180. package/dist/lib/doctor.d.ts +19 -0
  181. package/dist/lib/doctor.d.ts.map +1 -0
  182. package/dist/lib/doctor.js +43 -0
  183. package/dist/lib/doctor.js.map +1 -0
  184. package/dist/lib/events.d.ts +42 -0
  185. package/dist/lib/events.d.ts.map +1 -0
  186. package/dist/lib/events.js +57 -0
  187. package/dist/lib/events.js.map +1 -0
  188. package/dist/lib/export.d.ts +14 -0
  189. package/dist/lib/export.d.ts.map +1 -0
  190. package/dist/lib/export.js +36 -0
  191. package/dist/lib/export.js.map +1 -0
  192. package/dist/lib/ingest.d.ts +21 -0
  193. package/dist/lib/ingest.d.ts.map +1 -0
  194. package/dist/lib/ingest.js +68 -0
  195. package/dist/lib/ingest.js.map +1 -0
  196. package/dist/lib/journal.d.ts +23 -0
  197. package/dist/lib/journal.d.ts.map +1 -0
  198. package/dist/lib/journal.js +95 -0
  199. package/dist/lib/journal.js.map +1 -0
  200. package/dist/lib/migrate.d.ts +29 -0
  201. package/dist/lib/migrate.d.ts.map +1 -0
  202. package/dist/lib/migrate.js +117 -0
  203. package/dist/lib/migrate.js.map +1 -0
  204. package/dist/lib/nativeRuntime.d.ts +46 -0
  205. package/dist/lib/nativeRuntime.d.ts.map +1 -0
  206. package/dist/lib/nativeRuntime.js +61 -0
  207. package/dist/lib/nativeRuntime.js.map +1 -0
  208. package/dist/lib/provisionNative.d.ts +46 -0
  209. package/dist/lib/provisionNative.d.ts.map +1 -0
  210. package/dist/lib/provisionNative.js +105 -0
  211. package/dist/lib/provisionNative.js.map +1 -0
  212. package/dist/lib/queue.d.ts +36 -0
  213. package/dist/lib/queue.d.ts.map +1 -0
  214. package/dist/lib/queue.js +102 -0
  215. package/dist/lib/queue.js.map +1 -0
  216. package/dist/lib/retrieve.d.ts +51 -0
  217. package/dist/lib/retrieve.d.ts.map +1 -0
  218. package/dist/lib/retrieve.js +92 -0
  219. package/dist/lib/retrieve.js.map +1 -0
  220. package/dist/lib/saturate.d.ts +21 -0
  221. package/dist/lib/saturate.d.ts.map +1 -0
  222. package/dist/lib/saturate.js +132 -0
  223. package/dist/lib/saturate.js.map +1 -0
  224. package/dist/lib/schemas.generated.d.ts +15 -0
  225. package/dist/lib/schemas.generated.d.ts.map +1 -0
  226. package/dist/lib/schemas.generated.js +975 -0
  227. package/dist/lib/schemas.generated.js.map +1 -0
  228. package/dist/lib/seed.d.ts +16 -0
  229. package/dist/lib/seed.d.ts.map +1 -0
  230. package/dist/lib/seed.js +64 -0
  231. package/dist/lib/seed.js.map +1 -0
  232. package/dist/lib/seedResolve.d.ts +6 -0
  233. package/dist/lib/seedResolve.d.ts.map +1 -0
  234. package/dist/lib/seedResolve.js +27 -0
  235. package/dist/lib/seedResolve.js.map +1 -0
  236. package/dist/lib/session.d.ts +19 -0
  237. package/dist/lib/session.d.ts.map +1 -0
  238. package/dist/lib/session.js +61 -0
  239. package/dist/lib/session.js.map +1 -0
  240. package/dist/lib/setup.d.ts +44 -0
  241. package/dist/lib/setup.d.ts.map +1 -0
  242. package/dist/lib/setup.js +249 -0
  243. package/dist/lib/setup.js.map +1 -0
  244. package/dist/lib/snap.d.ts +15 -0
  245. package/dist/lib/snap.d.ts.map +1 -0
  246. package/dist/lib/snap.js +115 -0
  247. package/dist/lib/snap.js.map +1 -0
  248. package/dist/lib/status.d.ts +39 -0
  249. package/dist/lib/status.d.ts.map +1 -0
  250. package/dist/lib/status.js +174 -0
  251. package/dist/lib/status.js.map +1 -0
  252. package/dist/lib/tagcode.d.ts +26 -0
  253. package/dist/lib/tagcode.d.ts.map +1 -0
  254. package/dist/lib/tagcode.js +231 -0
  255. package/dist/lib/tagcode.js.map +1 -0
  256. package/dist/lib/templates.d.ts +3 -0
  257. package/dist/lib/templates.d.ts.map +1 -0
  258. package/dist/lib/templates.js +21 -0
  259. package/dist/lib/templates.js.map +1 -0
  260. package/dist/lib/transcribeNative.d.ts +44 -0
  261. package/dist/lib/transcribeNative.d.ts.map +1 -0
  262. package/dist/lib/transcribeNative.js +53 -0
  263. package/dist/lib/transcribeNative.js.map +1 -0
  264. package/dist/lib/transcript.d.ts +68 -0
  265. package/dist/lib/transcript.d.ts.map +1 -0
  266. package/dist/lib/transcript.js +10 -0
  267. package/dist/lib/transcript.js.map +1 -0
  268. package/dist/lib/validate.d.ts +16 -0
  269. package/dist/lib/validate.d.ts.map +1 -0
  270. package/dist/lib/validate.js +155 -0
  271. package/dist/lib/validate.js.map +1 -0
  272. package/dist/llm/adapter.d.ts +33 -0
  273. package/dist/llm/adapter.d.ts.map +1 -0
  274. package/dist/llm/adapter.js +106 -0
  275. package/dist/llm/adapter.js.map +1 -0
  276. package/dist/llm/http.d.ts +9 -0
  277. package/dist/llm/http.d.ts.map +1 -0
  278. package/dist/llm/http.js +56 -0
  279. package/dist/llm/http.js.map +1 -0
  280. package/dist/llm/providers/anthropic.d.ts +14 -0
  281. package/dist/llm/providers/anthropic.d.ts.map +1 -0
  282. package/dist/llm/providers/anthropic.js +66 -0
  283. package/dist/llm/providers/anthropic.js.map +1 -0
  284. package/dist/llm/providers/lmstudio.d.ts +7 -0
  285. package/dist/llm/providers/lmstudio.d.ts.map +1 -0
  286. package/dist/llm/providers/lmstudio.js +8 -0
  287. package/dist/llm/providers/lmstudio.js.map +1 -0
  288. package/dist/llm/providers/ollama.d.ts +12 -0
  289. package/dist/llm/providers/ollama.d.ts.map +1 -0
  290. package/dist/llm/providers/ollama.js +87 -0
  291. package/dist/llm/providers/ollama.js.map +1 -0
  292. package/dist/llm/providers/openai.d.ts +7 -0
  293. package/dist/llm/providers/openai.d.ts.map +1 -0
  294. package/dist/llm/providers/openai.js +8 -0
  295. package/dist/llm/providers/openai.js.map +1 -0
  296. package/dist/llm/providers/openai_compatible.d.ts +18 -0
  297. package/dist/llm/providers/openai_compatible.d.ts.map +1 -0
  298. package/dist/llm/providers/openai_compatible.js +70 -0
  299. package/dist/llm/providers/openai_compatible.js.map +1 -0
  300. package/dist/llm/types.d.ts +60 -0
  301. package/dist/llm/types.d.ts.map +1 -0
  302. package/dist/llm/types.js +2 -0
  303. package/dist/llm/types.js.map +1 -0
  304. package/dist/logging.d.ts +22 -0
  305. package/dist/logging.d.ts.map +1 -0
  306. package/dist/logging.js +58 -0
  307. package/dist/logging.js.map +1 -0
  308. package/dist/loops/embed_worker.d.ts +44 -0
  309. package/dist/loops/embed_worker.d.ts.map +1 -0
  310. package/dist/loops/embed_worker.js +144 -0
  311. package/dist/loops/embed_worker.js.map +1 -0
  312. package/dist/loops/eval_grader.d.ts +19 -0
  313. package/dist/loops/eval_grader.d.ts.map +1 -0
  314. package/dist/loops/eval_grader.js +22 -0
  315. package/dist/loops/eval_grader.js.map +1 -0
  316. package/dist/loops/ingest_watcher.d.ts +17 -0
  317. package/dist/loops/ingest_watcher.d.ts.map +1 -0
  318. package/dist/loops/ingest_watcher.js +66 -0
  319. package/dist/loops/ingest_watcher.js.map +1 -0
  320. package/dist/loops/legacy_worker.d.ts +26 -0
  321. package/dist/loops/legacy_worker.d.ts.map +1 -0
  322. package/dist/loops/legacy_worker.js +102 -0
  323. package/dist/loops/legacy_worker.js.map +1 -0
  324. package/dist/loops/supervisor.d.ts +71 -0
  325. package/dist/loops/supervisor.d.ts.map +1 -0
  326. package/dist/loops/supervisor.js +122 -0
  327. package/dist/loops/supervisor.js.map +1 -0
  328. package/dist/loops/synthesis.d.ts +31 -0
  329. package/dist/loops/synthesis.d.ts.map +1 -0
  330. package/dist/loops/synthesis.js +71 -0
  331. package/dist/loops/synthesis.js.map +1 -0
  332. package/dist/loops/transcribe_worker.d.ts +22 -0
  333. package/dist/loops/transcribe_worker.d.ts.map +1 -0
  334. package/dist/loops/transcribe_worker.js +77 -0
  335. package/dist/loops/transcribe_worker.js.map +1 -0
  336. package/dist/output.d.ts +8 -0
  337. package/dist/output.d.ts.map +1 -0
  338. package/dist/output.js +26 -0
  339. package/dist/output.js.map +1 -0
  340. package/dist/render/transcript_md.d.ts +5 -0
  341. package/dist/render/transcript_md.d.ts.map +1 -0
  342. package/dist/render/transcript_md.js +14 -0
  343. package/dist/render/transcript_md.js.map +1 -0
  344. package/dist/router.d.ts +3 -0
  345. package/dist/router.d.ts.map +1 -0
  346. package/dist/router.js +68 -0
  347. package/dist/router.js.map +1 -0
  348. package/dist/transcriber_client.d.ts +42 -0
  349. package/dist/transcriber_client.d.ts.map +1 -0
  350. package/dist/transcriber_client.js +72 -0
  351. package/dist/transcriber_client.js.map +1 -0
  352. package/package.json +45 -0
  353. package/templates/AGENTS.md +25 -0
  354. package/templates/config.toml +56 -0
  355. package/templates/sample-seed/codebook/desire-for-manual-override.md +8 -0
  356. package/templates/sample-seed/codebook/distrust-of-automation.md +8 -0
  357. package/templates/sample-seed/highlights/H-001.md +9 -0
  358. package/templates/sample-seed/highlights/H-002.md +9 -0
  359. package/templates/sample-seed/seed.md +17 -0
  360. package/templates/sample-seed/sessions/S001/transcript.json +74 -0
  361. package/templates/sample-seed/synthesis/themes/control-earns-trust.md +13 -0
  362. package/templates/seed.md +21 -0
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Single source of truth for "is this subdir of `sessions/` a real session?"
3
+ * Shared between `compost status` and `compost saturate` so they can't disagree
4
+ * on the session set (#166 — saturate was counting every subdir as a session,
5
+ * while status correctly skipped non-canonical folders like `Transcripts/`).
6
+ *
7
+ * A subdir qualifies when ANY holds:
8
+ * - the name matches `S\d+` (canonical id shape from ingest-watcher), OR
9
+ * - it contains a `transcript.json` (already transcribed), OR
10
+ * - it contains a `source.<ext>` file (queued for transcription).
11
+ *
12
+ * `_inbox/` and dotfiles are filtered out by the listing helper, not the
13
+ * predicate; callers that traverse `sessions/` directly should handle those.
14
+ */
15
+ export declare const CANONICAL_SESSION_ID_RE: RegExp;
16
+ export declare function isCanonicalSession(absDir: string, name: string): boolean;
17
+ /**
18
+ * List the canonical session-id directory names under `<seed>/sessions/`,
19
+ * skipping `_inbox/`, dotfiles, files, and non-canonical folders. Returns the
20
+ * directory names (not absolute paths). Order is filesystem-dependent — sort
21
+ * at the call site if chronological ordering matters.
22
+ */
23
+ export declare function listCanonicalSessionIds(sessionsDir: string): string[];
24
+ //# sourceMappingURL=canonicalSessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonicalSessions.d.ts","sourceRoot":"","sources":["../../src/lib/canonicalSessions.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,uBAAuB,QAAW,CAAA;AAE/C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAKxE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAWrE"}
@@ -0,0 +1,48 @@
1
+ import { existsSync, readdirSync, statSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ /**
4
+ * Single source of truth for "is this subdir of `sessions/` a real session?"
5
+ * Shared between `compost status` and `compost saturate` so they can't disagree
6
+ * on the session set (#166 — saturate was counting every subdir as a session,
7
+ * while status correctly skipped non-canonical folders like `Transcripts/`).
8
+ *
9
+ * A subdir qualifies when ANY holds:
10
+ * - the name matches `S\d+` (canonical id shape from ingest-watcher), OR
11
+ * - it contains a `transcript.json` (already transcribed), OR
12
+ * - it contains a `source.<ext>` file (queued for transcription).
13
+ *
14
+ * `_inbox/` and dotfiles are filtered out by the listing helper, not the
15
+ * predicate; callers that traverse `sessions/` directly should handle those.
16
+ */
17
+ export const CANONICAL_SESSION_ID_RE = /^S\d+$/;
18
+ export function isCanonicalSession(absDir, name) {
19
+ if (CANONICAL_SESSION_ID_RE.test(name))
20
+ return true;
21
+ if (existsSync(join(absDir, 'transcript.json')))
22
+ return true;
23
+ // source.<ext> is written by processInbox before the dir is canonicalized.
24
+ return readdirSync(absDir).some((f) => f.startsWith('source.'));
25
+ }
26
+ /**
27
+ * List the canonical session-id directory names under `<seed>/sessions/`,
28
+ * skipping `_inbox/`, dotfiles, files, and non-canonical folders. Returns the
29
+ * directory names (not absolute paths). Order is filesystem-dependent — sort
30
+ * at the call site if chronological ordering matters.
31
+ */
32
+ export function listCanonicalSessionIds(sessionsDir) {
33
+ if (!existsSync(sessionsDir))
34
+ return [];
35
+ const out = [];
36
+ for (const entry of readdirSync(sessionsDir)) {
37
+ if (entry.startsWith('.') || entry === '_inbox')
38
+ continue;
39
+ const abs = join(sessionsDir, entry);
40
+ if (!statSync(abs).isDirectory())
41
+ continue;
42
+ if (!isCanonicalSession(abs, entry))
43
+ continue;
44
+ out.push(entry);
45
+ }
46
+ return out;
47
+ }
48
+ //# sourceMappingURL=canonicalSessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonicalSessions.js","sourceRoot":"","sources":["../../src/lib/canonicalSessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,QAAQ,CAAA;AAE/C,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,IAAY;IAC7D,IAAI,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IACnD,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IAC5D,2EAA2E;IAC3E,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAA;AACjE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,WAAmB;IACzD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,EAAE,CAAA;IACvC,MAAM,GAAG,GAAa,EAAE,CAAA;IACxB,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7C,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,QAAQ;YAAE,SAAQ;QACzD,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;QACpC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;YAAE,SAAQ;QAC1C,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC;YAAE,SAAQ;QAC7C,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACjB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { type Answer, type Chunk } from 'compost-retrieval';
2
+ export interface ChatCitation {
3
+ utterance_id: string;
4
+ quote: string;
5
+ confidence: number;
6
+ }
7
+ export interface ChatResult {
8
+ answer: string;
9
+ citations: ChatCitation[];
10
+ insufficient_evidence: boolean;
11
+ retrieved: number;
12
+ }
13
+ /** Generates a candidate Answer from the question + retrieved context. The
14
+ * command wires this to the LLM adapter; tests inject a fake. */
15
+ export type AnswerFn = (question: string, context: Chunk[]) => Promise<Answer>;
16
+ export interface ChatDeps {
17
+ answerFn: AnswerFn;
18
+ seed: string;
19
+ topK?: number;
20
+ now?: () => Date;
21
+ chatId?: string;
22
+ }
23
+ export declare function chat(seedPath: string, question: string, deps: ChatDeps): Promise<ChatResult>;
24
+ //# sourceMappingURL=chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/lib/chat.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,KAAK,EAAkB,MAAM,mBAAmB,CAAA;AAI3E,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,YAAY,EAAE,CAAA;IACzB,qBAAqB,EAAE,OAAO,CAAA;IAC9B,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;iEACiE;AACjE,MAAM,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;AAE9E,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,QAAQ,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAsB,IAAI,CACxB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,UAAU,CAAC,CAMrB"}
@@ -0,0 +1,50 @@
1
+ import { appendFileSync, mkdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { validateAnswer } from 'compost-retrieval';
4
+ import { buildDenseRetriever, retrieveChunks } from './retrieve.js';
5
+ export async function chat(seedPath, question, deps) {
6
+ const result = await answerQuestion(seedPath, question, deps);
7
+ // Every turn is persisted — a conversation happened even when the answer was
8
+ // "insufficient evidence".
9
+ persistTurn(seedPath, deps, question, result);
10
+ return result;
11
+ }
12
+ async function answerQuestion(seedPath, question, deps) {
13
+ const dense = await buildDenseRetriever(seedPath);
14
+ const { retrieved, corpus } = await retrieveChunks(seedPath, question, {
15
+ topK: deps.topK ?? 8,
16
+ dense,
17
+ });
18
+ if (corpus.chunks.length === 0)
19
+ return insufficient('No indexed sessions in this seed yet.', 0);
20
+ if (retrieved.length === 0)
21
+ return insufficient('Nothing in the corpus matched the question.', 0);
22
+ const evidence = corpus.evidence;
23
+ const raw = await deps.answerFn(question, retrieved);
24
+ const validation = validateAnswer(raw, evidence);
25
+ if (validation.ok && raw.insufficient_evidence !== true) {
26
+ return {
27
+ answer: raw.answer,
28
+ citations: raw.claims.map((c) => ({
29
+ utterance_id: c.utterance_id,
30
+ quote: c.quote,
31
+ confidence: c.confidence,
32
+ })),
33
+ insufficient_evidence: false,
34
+ retrieved: retrieved.length,
35
+ };
36
+ }
37
+ return insufficient(raw.insufficient_evidence === true ? raw.answer : 'Answer failed citation validation.', retrieved.length);
38
+ }
39
+ function insufficient(answer, retrieved) {
40
+ return { answer, citations: [], insufficient_evidence: true, retrieved };
41
+ }
42
+ function persistTurn(seedPath, deps, question, result) {
43
+ const now = (deps.now ?? (() => new Date()))();
44
+ const chatId = deps.chatId ?? 'default';
45
+ const dir = join(seedPath, '.compost', 'chats', deps.seed);
46
+ mkdirSync(dir, { recursive: true });
47
+ const line = JSON.stringify({ ts: now.toISOString(), question, ...result });
48
+ appendFileSync(join(dir, `${chatId}.jsonl`), `${line}\n`, 'utf8');
49
+ }
50
+ //# sourceMappingURL=chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/lib/chat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ export interface ProviderSettings {
2
+ base_url?: string;
3
+ api_key_env?: string;
4
+ }
5
+ export interface CompostConfig {
6
+ providers: Record<string, ProviderSettings>;
7
+ defaults: Record<string, string>;
8
+ raw: Record<string, unknown>;
9
+ }
10
+ export declare function parseConfig(tomlText: string): CompostConfig;
11
+ export declare function loadConfig(seedPath: string): CompostConfig;
12
+ export declare function providerBaseUrl(config: CompostConfig, providerName: string): string;
13
+ export declare function providerApiKey(config: CompostConfig, providerName: string): string | undefined;
14
+ /** Resolve a dotted key (e.g. `providers.ollama.base_url`) against the raw TOML
15
+ * object. Returns undefined if any segment is missing. */
16
+ export declare function getConfigValue(raw: Record<string, unknown>, key: string): unknown;
17
+ /** The set of types `compost config set --type=<X>` accepts. */
18
+ export type ConfigValueType = 'string' | 'bool' | 'int' | 'float' | 'json';
19
+ /**
20
+ * Set a dotted key in the raw TOML object.
21
+ *
22
+ * Default behavior: store the value as a **string**. This matches `git config`,
23
+ * `gh config`, `aws configure`: leaf values are strings unless explicitly
24
+ * typed otherwise. This eliminates silent type drift (a researcher typing
25
+ * `compost config set features.beta true` previously stored a boolean and
26
+ * later confused `cfg.features.beta === "true"` checks).
27
+ *
28
+ * To store a non-string type, pass `type`:
29
+ * - `bool` → 'true' | 'false'
30
+ * - `int` → integer (must match /^-?\d+$/)
31
+ * - `float` → decimal (must match /^-?\d+(\.\d+)?$/)
32
+ * - `json` → JSON.parse the value (arrays, objects, nested structures)
33
+ *
34
+ * Agents writing config programmatically should always pass `type` to be
35
+ * explicit. Humans typing strings can leave it off.
36
+ */
37
+ export declare function setConfigValue(raw: Record<string, unknown>, key: string, value: string, type?: ConfigValueType): void;
38
+ /** Write the raw TOML object back to .compost/config.toml. */
39
+ export declare function saveConfig(seedPath: string, raw: Record<string, unknown>): void;
40
+ /** Parse a "provider:model" routing string (model may itself contain colons). */
41
+ export declare function parseRoute(route: string): {
42
+ provider: string;
43
+ model: string;
44
+ };
45
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IAC3C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC7B;AASD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAU3D;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAM1D;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQ9F;AAED;0DAC0D;AAC1D,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CASjF;AAED,gEAAgE;AAChE,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,CAAA;AAE1E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,eAA0B,GAC/B,IAAI,CAeN;AAsDD,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAG/E;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAS7E"}
@@ -0,0 +1,143 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { parse as parseToml, stringify as stringifyToml } from 'smol-toml';
4
+ import { CompostError } from '../errors.js';
5
+ const DEFAULT_BASE_URLS = {
6
+ ollama: 'http://localhost:11434',
7
+ lmstudio: 'http://localhost:1234/v1',
8
+ openai: 'https://api.openai.com/v1',
9
+ anthropic: 'https://api.anthropic.com',
10
+ };
11
+ export function parseConfig(tomlText) {
12
+ let parsed;
13
+ try {
14
+ parsed = parseToml(tomlText);
15
+ }
16
+ catch (cause) {
17
+ throw new CompostError('CONFIG_ERROR', 'Could not parse config.toml', { cause });
18
+ }
19
+ const providers = parsed.providers ?? {};
20
+ const defaults = parsed.defaults ?? {};
21
+ return { providers, defaults, raw: parsed };
22
+ }
23
+ export function loadConfig(seedPath) {
24
+ const configPath = join(seedPath, '.compost', 'config.toml');
25
+ if (!existsSync(configPath)) {
26
+ throw new CompostError('CONFIG_ERROR', `No config.toml at ${configPath}`);
27
+ }
28
+ return parseConfig(readFileSync(configPath, 'utf8'));
29
+ }
30
+ export function providerBaseUrl(config, providerName) {
31
+ return config.providers[providerName]?.base_url ?? DEFAULT_BASE_URLS[providerName] ?? '';
32
+ }
33
+ export function providerApiKey(config, providerName) {
34
+ const envName = config.providers[providerName]?.api_key_env;
35
+ if (envName === undefined)
36
+ return undefined;
37
+ // A set-but-blank env var (`export ANTHROPIC_API_KEY=`) is effectively no key —
38
+ // normalize to undefined so the adapter's missing-key guard fires (and we never
39
+ // send a blank `x-api-key`).
40
+ const value = process.env[envName];
41
+ return value && value.trim() !== '' ? value : undefined;
42
+ }
43
+ /** Resolve a dotted key (e.g. `providers.ollama.base_url`) against the raw TOML
44
+ * object. Returns undefined if any segment is missing. */
45
+ export function getConfigValue(raw, key) {
46
+ const parts = key.split('.');
47
+ let cursor = raw;
48
+ for (const part of parts) {
49
+ if (typeof cursor !== 'object' || cursor === null)
50
+ return undefined;
51
+ cursor = cursor[part];
52
+ if (cursor === undefined)
53
+ return undefined;
54
+ }
55
+ return cursor;
56
+ }
57
+ /**
58
+ * Set a dotted key in the raw TOML object.
59
+ *
60
+ * Default behavior: store the value as a **string**. This matches `git config`,
61
+ * `gh config`, `aws configure`: leaf values are strings unless explicitly
62
+ * typed otherwise. This eliminates silent type drift (a researcher typing
63
+ * `compost config set features.beta true` previously stored a boolean and
64
+ * later confused `cfg.features.beta === "true"` checks).
65
+ *
66
+ * To store a non-string type, pass `type`:
67
+ * - `bool` → 'true' | 'false'
68
+ * - `int` → integer (must match /^-?\d+$/)
69
+ * - `float` → decimal (must match /^-?\d+(\.\d+)?$/)
70
+ * - `json` → JSON.parse the value (arrays, objects, nested structures)
71
+ *
72
+ * Agents writing config programmatically should always pass `type` to be
73
+ * explicit. Humans typing strings can leave it off.
74
+ */
75
+ export function setConfigValue(raw, key, value, type = 'string') {
76
+ const parts = key.split('.');
77
+ if (parts.length === 0) {
78
+ throw new CompostError('INVALID_INPUT', 'Empty config key');
79
+ }
80
+ let cursor = raw;
81
+ for (let i = 0; i < parts.length - 1; i++) {
82
+ const part = parts[i];
83
+ const next = cursor[part];
84
+ if (next === undefined || typeof next !== 'object' || next === null || Array.isArray(next)) {
85
+ cursor[part] = {};
86
+ }
87
+ cursor = cursor[part];
88
+ }
89
+ cursor[parts[parts.length - 1]] = coerceTyped(value, type);
90
+ }
91
+ function coerceTyped(value, type) {
92
+ switch (type) {
93
+ case 'string':
94
+ return value;
95
+ case 'bool':
96
+ if (value === 'true')
97
+ return true;
98
+ if (value === 'false')
99
+ return false;
100
+ throw new CompostError('INVALID_INPUT', `--type=bool requires "true" or "false"; got ${JSON.stringify(value)}`);
101
+ case 'int': {
102
+ if (!/^-?\d+$/.test(value)) {
103
+ throw new CompostError('INVALID_INPUT', `--type=int requires an integer; got ${JSON.stringify(value)}`);
104
+ }
105
+ const n = Number(value);
106
+ if (!Number.isFinite(n) || !Number.isInteger(n)) {
107
+ throw new CompostError('INVALID_INPUT', `--type=int value out of range: ${JSON.stringify(value)}`);
108
+ }
109
+ return n;
110
+ }
111
+ case 'float': {
112
+ if (!/^-?\d+(\.\d+)?$/.test(value)) {
113
+ throw new CompostError('INVALID_INPUT', `--type=float requires a decimal number; got ${JSON.stringify(value)}`);
114
+ }
115
+ const n = Number(value);
116
+ if (!Number.isFinite(n)) {
117
+ throw new CompostError('INVALID_INPUT', `--type=float value not finite: ${JSON.stringify(value)}`);
118
+ }
119
+ return n;
120
+ }
121
+ case 'json':
122
+ try {
123
+ return JSON.parse(value);
124
+ }
125
+ catch (cause) {
126
+ throw new CompostError('INVALID_INPUT', `--type=json: invalid JSON: ${value}`, { cause });
127
+ }
128
+ }
129
+ }
130
+ /** Write the raw TOML object back to .compost/config.toml. */
131
+ export function saveConfig(seedPath, raw) {
132
+ const configPath = join(seedPath, '.compost', 'config.toml');
133
+ writeFileSync(configPath, stringifyToml(raw), 'utf8');
134
+ }
135
+ /** Parse a "provider:model" routing string (model may itself contain colons). */
136
+ export function parseRoute(route) {
137
+ const idx = route.indexOf(':');
138
+ if (idx === -1) {
139
+ throw new CompostError('CONFIG_ERROR', `Invalid route "${route}"; expected "provider:model" (e.g. ollama:llama3.1:8b)`);
140
+ }
141
+ return { provider: route.slice(0, idx), model: route.slice(idx + 1) };
142
+ }
143
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { JobKind } from './queue.js';
2
+ export interface Dispatch {
3
+ kind: JobKind;
4
+ category: 'audio' | 'video' | 'document' | 'tabular' | 'markdown';
5
+ ext: string;
6
+ }
7
+ /** Classify a file by extension into a worker dispatch, or null if unsupported. */
8
+ export declare function classify(path: string): Dispatch | null;
9
+ export declare const SUPPORTED_EXTENSIONS: string[];
10
+ //# sourceMappingURL=dispatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/lib/dispatch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,OAAO,CAAA;IACb,QAAQ,EAAE,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAA;IACjE,GAAG,EAAE,MAAM,CAAA;CACZ;AAUD,mFAAmF;AACnF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAQtD;AAED,eAAO,MAAM,oBAAoB,UAMzB,CAAA"}
@@ -0,0 +1,31 @@
1
+ import { extname } from 'node:path';
2
+ const AUDIO = new Set(['.mp3', '.wav', '.m4a', '.aac', '.flac', '.ogg', '.opus']);
3
+ const VIDEO = new Set(['.mp4', '.mov', '.mkv', '.webm', '.avi', '.m4v']);
4
+ const DOCUMENT = new Set(['.pdf', '.docx', '.pptx']);
5
+ // `.xlsx` lands under tabular (column-mapped via openpyxl in legacy ingest).
6
+ // `.txt` lands under markdown (Otter/Zoom exports often arrive as plain text).
7
+ const TABULAR = new Set(['.csv', '.tsv', '.xlsx']);
8
+ const MARKDOWN = new Set(['.md', '.markdown', '.txt']);
9
+ /** Classify a file by extension into a worker dispatch, or null if unsupported. */
10
+ export function classify(path) {
11
+ const ext = extname(path).toLowerCase();
12
+ if (AUDIO.has(ext))
13
+ return { kind: 'transcribe', category: 'audio', ext };
14
+ if (VIDEO.has(ext))
15
+ return { kind: 'transcribe', category: 'video', ext };
16
+ if (DOCUMENT.has(ext))
17
+ return { kind: 'legacy-ingest', category: 'document', ext };
18
+ if (TABULAR.has(ext))
19
+ return { kind: 'legacy-ingest', category: 'tabular', ext };
20
+ if (MARKDOWN.has(ext))
21
+ return { kind: 'legacy-ingest', category: 'markdown', ext };
22
+ return null;
23
+ }
24
+ export const SUPPORTED_EXTENSIONS = [
25
+ ...AUDIO,
26
+ ...VIDEO,
27
+ ...DOCUMENT,
28
+ ...TABULAR,
29
+ ...MARKDOWN,
30
+ ].sort();
31
+ //# sourceMappingURL=dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../src/lib/dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAUnC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AACjF,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;AACxE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;AACpD,6EAA6E;AAC7E,+EAA+E;AAC/E,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AAClD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC,CAAA;AAEtD,mFAAmF;AACnF,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;IACvC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,CAAA;IACzE,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,CAAA;IACzE,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,CAAA;IAClF,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,CAAA;IAChF,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,CAAA;IAClF,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,GAAG,KAAK;IACR,GAAG,KAAK;IACR,GAAG,QAAQ;IACX,GAAG,OAAO;IACV,GAAG,QAAQ;CACZ,CAAC,IAAI,EAAE,CAAA"}
@@ -0,0 +1,19 @@
1
+ import type { LLMAdapter } from '../llm/adapter.js';
2
+ import type { ProviderHealth } from '../llm/types.js';
3
+ import type { CompostConfig } from './config.js';
4
+ export interface TaskReport {
5
+ task: string;
6
+ route: string;
7
+ provider: string;
8
+ model: string;
9
+ status: 'ok' | 'provider_down' | 'model_missing' | 'unroutable';
10
+ suggestion?: string;
11
+ }
12
+ export interface DoctorReport {
13
+ schema_version: '1.0';
14
+ providers: Record<string, ProviderHealth>;
15
+ tasks: TaskReport[];
16
+ ok: boolean;
17
+ }
18
+ export declare function runDoctor(adapter: LLMAdapter, config: CompostConfig): Promise<DoctorReport>;
19
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/lib/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAGhD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,IAAI,GAAG,eAAe,GAAG,eAAe,GAAG,YAAY,CAAA;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,KAAK,CAAA;IACrB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;IACzC,KAAK,EAAE,UAAU,EAAE,CAAA;IACnB,EAAE,EAAE,OAAO,CAAA;CACZ;AAUD,wBAAsB,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAmCjG"}
@@ -0,0 +1,43 @@
1
+ import { parseRoute } from './config.js';
2
+ /** A model is "present" if any reported model id starts with the routed model name. */
3
+ function modelPresent(health, model) {
4
+ if (health === undefined || !health.ok)
5
+ return false;
6
+ return health.model_list.some((m) => m === model || m.startsWith(`${model}:`) || m.startsWith(model));
7
+ }
8
+ export async function runDoctor(adapter, config) {
9
+ const providers = await adapter.healthAll();
10
+ const tasks = [];
11
+ let ok = true;
12
+ for (const [task, route] of Object.entries(config.defaults)) {
13
+ let provider = '';
14
+ let model = '';
15
+ try {
16
+ const parsed = parseRoute(route);
17
+ provider = parsed.provider;
18
+ model = parsed.model;
19
+ }
20
+ catch {
21
+ tasks.push({ task, route, provider: '', model: '', status: 'unroutable' });
22
+ ok = false;
23
+ continue;
24
+ }
25
+ const health = providers[provider];
26
+ if (health === undefined || !health.ok) {
27
+ tasks.push({ task, route, provider, model, status: 'provider_down' });
28
+ ok = false;
29
+ continue;
30
+ }
31
+ if (!modelPresent(health, model)) {
32
+ const report = { task, route, provider, model, status: 'model_missing' };
33
+ if (provider === 'ollama')
34
+ report.suggestion = `ollama pull ${model}`;
35
+ tasks.push(report);
36
+ ok = false;
37
+ continue;
38
+ }
39
+ tasks.push({ task, route, provider, model, status: 'ok' });
40
+ }
41
+ return { schema_version: '1.0', providers, tasks, ok };
42
+ }
43
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/lib/doctor.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAkBxC,uFAAuF;AACvF,SAAS,YAAY,CAAC,MAAkC,EAAE,KAAa;IACrE,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,KAAK,CAAA;IACpD,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,CAC3B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CACvE,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAmB,EAAE,MAAqB;IACxE,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,CAAA;IAC3C,MAAM,KAAK,GAAiB,EAAE,CAAA;IAC9B,IAAI,EAAE,GAAG,IAAI,CAAA;IAEb,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5D,IAAI,QAAQ,GAAG,EAAE,CAAA;QACjB,IAAI,KAAK,GAAG,EAAE,CAAA;QACd,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;YAChC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;YAC1B,KAAK,GAAG,MAAM,CAAC,KAAK,CAAA;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAA;YAC1E,EAAE,GAAG,KAAK,CAAA;YACV,SAAQ;QACV,CAAC;QAED,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;QAClC,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAA;YACrE,EAAE,GAAG,KAAK,CAAA;YACV,SAAQ;QACV,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;YACjC,MAAM,MAAM,GAAe,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAA;YACpF,IAAI,QAAQ,KAAK,QAAQ;gBAAE,MAAM,CAAC,UAAU,GAAG,eAAe,KAAK,EAAE,CAAA;YACrE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YAClB,EAAE,GAAG,KAAK,CAAA;YACV,SAAQ;QACV,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;IAC5D,CAAC;IAED,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;AACxD,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { type Event, EventWriter } from 'compost-provenance';
2
+ /** Open an EventWriter on a seed's .compost/events.sqlite. */
3
+ export declare function openSeedEvents(seedPath: string): EventWriter;
4
+ /** Content-address an artifact's initial state (SHA256 of canonical JSON). */
5
+ export declare function artifactId(initialState: unknown): string;
6
+ /** Emit an agent-authored `create` event (used by ingest + ingest-watcher). */
7
+ export declare function emitAgentCreate(writer: EventWriter, params: {
8
+ artifactKind: string;
9
+ initialState: Record<string, unknown>;
10
+ agentName: string;
11
+ agentVersion: string;
12
+ batchId?: string;
13
+ }): Event;
14
+ /**
15
+ * Author of a researcher- or AI-created artifact. A direct CLI invocation is a
16
+ * researcher; the MCP wrapper (Claude Code) passes `ai` with an actor_id like
17
+ * `claude-code:<plugin_ver>:<sha256(prompt)[:8]>` and a prompt_hash so the
18
+ * suggestion lands as `[draft]` until a researcher endorses it.
19
+ */
20
+ export interface Author {
21
+ actorType: 'researcher' | 'ai';
22
+ actorId: string;
23
+ model?: string;
24
+ promptHash?: string;
25
+ }
26
+ /** Emit a researcher- or AI-authored `create` event. artifact_id is the SHA256
27
+ * of initialState (the provenance content-address); the human-facing file id
28
+ * lives in initialState.id so blame can map between them. */
29
+ export declare function emitCreate(writer: EventWriter, params: {
30
+ artifactKind: string;
31
+ initialState: Record<string, unknown>;
32
+ author: Author;
33
+ }): Event;
34
+ /** Emit a researcher `endorse` event chaining the artifact's create event.
35
+ * Promotes an AI `[draft]` to endorsed (snapshot author becomes hybrid). */
36
+ export declare function emitEndorse(writer: EventWriter, params: {
37
+ artifactKind: string;
38
+ artifactId: string;
39
+ parentEventId: string;
40
+ researcherId: string;
41
+ }): Event;
42
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/lib/events.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,KAAK,EAAmB,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAE7E,8DAA8D;AAC9D,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAE5D;AAED,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,YAAY,EAAE,OAAO,GAAG,MAAM,CAExD;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAC7B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE;IACN,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrC,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,GACA,KAAK,CAaP;AAED;;;;;GAKG;AACH,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;6DAE6D;AAC7D,wBAAgB,UAAU,CACxB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtF,KAAK,CAaP;AAED;4EAC4E;AAC5E,wBAAgB,WAAW,CACzB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE;IACN,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;CACrB,GACA,KAAK,CAUP"}
@@ -0,0 +1,57 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { join } from 'node:path';
3
+ import { EventWriter } from 'compost-provenance';
4
+ /** Open an EventWriter on a seed's .compost/events.sqlite. */
5
+ export function openSeedEvents(seedPath) {
6
+ return new EventWriter({ dbPath: join(seedPath, '.compost', 'events.sqlite') });
7
+ }
8
+ /** Content-address an artifact's initial state (SHA256 of canonical JSON). */
9
+ export function artifactId(initialState) {
10
+ return createHash('sha256').update(JSON.stringify(initialState)).digest('hex');
11
+ }
12
+ /** Emit an agent-authored `create` event (used by ingest + ingest-watcher). */
13
+ export function emitAgentCreate(writer, params) {
14
+ const input = {
15
+ artifact_kind: params.artifactKind,
16
+ artifact_id: artifactId(params.initialState),
17
+ action: 'create',
18
+ actor_type: 'agent',
19
+ actor_id: `${params.agentName}@${params.agentVersion}`,
20
+ agent_name: params.agentName,
21
+ agent_version: params.agentVersion,
22
+ payload: params.initialState,
23
+ ...(params.batchId !== undefined ? { batch_id: params.batchId } : {}),
24
+ };
25
+ return writer.appendEvent(input);
26
+ }
27
+ /** Emit a researcher- or AI-authored `create` event. artifact_id is the SHA256
28
+ * of initialState (the provenance content-address); the human-facing file id
29
+ * lives in initialState.id so blame can map between them. */
30
+ export function emitCreate(writer, params) {
31
+ const { author } = params;
32
+ const input = {
33
+ artifact_kind: params.artifactKind,
34
+ artifact_id: artifactId(params.initialState),
35
+ action: 'create',
36
+ actor_type: author.actorType,
37
+ actor_id: author.actorId,
38
+ payload: params.initialState,
39
+ ...(author.model !== undefined ? { model: author.model } : {}),
40
+ ...(author.promptHash !== undefined ? { prompt_hash: author.promptHash } : {}),
41
+ };
42
+ return writer.appendEvent(input);
43
+ }
44
+ /** Emit a researcher `endorse` event chaining the artifact's create event.
45
+ * Promotes an AI `[draft]` to endorsed (snapshot author becomes hybrid). */
46
+ export function emitEndorse(writer, params) {
47
+ return writer.appendEvent({
48
+ artifact_kind: params.artifactKind,
49
+ artifact_id: params.artifactId,
50
+ action: 'endorse',
51
+ actor_type: 'researcher',
52
+ actor_id: params.researcherId,
53
+ parent_event: params.parentEventId,
54
+ payload: { endorsed: true },
55
+ });
56
+ }
57
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/lib/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EAA+B,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAE7E,8DAA8D;AAC9D,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,OAAO,IAAI,WAAW,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,eAAe,CAAC,EAAE,CAAC,CAAA;AACjF,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,UAAU,CAAC,YAAqB;IAC9C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAChF,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,eAAe,CAC7B,MAAmB,EACnB,MAMC;IAED,MAAM,KAAK,GAAe;QACxB,aAAa,EAAE,MAAM,CAAC,YAAY;QAClC,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC;QAC5C,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,OAAO;QACnB,QAAQ,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,YAAY,EAAE;QACtD,UAAU,EAAE,MAAM,CAAC,SAAS;QAC5B,aAAa,EAAE,MAAM,CAAC,YAAY;QAClC,OAAO,EAAE,MAAM,CAAC,YAAY;QAC5B,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtE,CAAA;IACD,OAAO,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;AAClC,CAAC;AAeD;;6DAE6D;AAC7D,MAAM,UAAU,UAAU,CACxB,MAAmB,EACnB,MAAuF;IAEvF,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IACzB,MAAM,KAAK,GAAe;QACxB,aAAa,EAAE,MAAM,CAAC,YAAY;QAClC,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC;QAC5C,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,MAAM,CAAC,SAAS;QAC5B,QAAQ,EAAE,MAAM,CAAC,OAAO;QACxB,OAAO,EAAE,MAAM,CAAC,YAAY;QAC5B,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/E,CAAA;IACD,OAAO,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;AAClC,CAAC;AAED;4EAC4E;AAC5E,MAAM,UAAU,WAAW,CACzB,MAAmB,EACnB,MAKC;IAED,OAAO,MAAM,CAAC,WAAW,CAAC;QACxB,aAAa,EAAE,MAAM,CAAC,YAAY;QAClC,WAAW,EAAE,MAAM,CAAC,UAAU;QAC9B,MAAM,EAAE,SAAS;QACjB,UAAU,EAAE,YAAY;QACxB,QAAQ,EAAE,MAAM,CAAC,YAAY;QAC7B,YAAY,EAAE,MAAM,CAAC,aAAa;QAClC,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;KAC5B,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Transcript } from './transcript.js';
2
+ export type ExportFormat = 'csv' | 'md' | 'eaf';
3
+ export interface ExportOptions {
4
+ format: ExportFormat;
5
+ createdDate?: string;
6
+ }
7
+ export interface ExportResult {
8
+ format: ExportFormat;
9
+ session_id: string;
10
+ content: string;
11
+ }
12
+ export declare function loadTranscript(path: string): Transcript;
13
+ export declare function exportTranscript(transcript: Transcript, opts: ExportOptions): ExportResult;
14
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/lib/export.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAA;AAE/C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAkBvD;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,GAAG,YAAY,CAa1F"}