@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,44 @@
1
+ import { resolveFetch } from './llm/http.js';
2
+ export class LegacyServiceError extends Error {
3
+ kind;
4
+ constructor(message, kind) {
5
+ super(message);
6
+ this.kind = kind;
7
+ this.name = 'LegacyServiceError';
8
+ }
9
+ }
10
+ /** HTTP client for the transcriber service's /legacy-ingest route. */
11
+ export class LegacyIngestClient {
12
+ base;
13
+ fetchImpl;
14
+ timeoutMs;
15
+ constructor(opts = {}) {
16
+ this.base = (opts.baseUrl ?? 'http://localhost:7862').replace(/\/$/, '');
17
+ this.fetchImpl = resolveFetch(opts.fetchImpl);
18
+ this.timeoutMs = opts.timeoutMs ?? 600_000; // 10 min; PDFs with OCR can be slow
19
+ }
20
+ async ingest(req) {
21
+ let res;
22
+ try {
23
+ res = await this.fetchImpl(`${this.base}/legacy-ingest`, {
24
+ method: 'POST',
25
+ headers: { 'content-type': 'application/json' },
26
+ body: JSON.stringify(req),
27
+ });
28
+ }
29
+ catch (err) {
30
+ throw new LegacyServiceError(`legacy-ingest service unreachable at ${this.base}: ${err instanceof Error ? err.message : String(err)}`, 'down');
31
+ }
32
+ if (res.status === 503)
33
+ throw new LegacyServiceError('legacy-ingest dep missing (install transcriber [legacy] extras)', 'dep_missing');
34
+ if (res.status === 422) {
35
+ const body = (await res.json());
36
+ throw new LegacyServiceError(`invalid_input: ${body.detail ?? 'unknown'}`, 'invalid_input');
37
+ }
38
+ if (!res.ok) {
39
+ throw new LegacyServiceError(`legacy-ingest failed: ${res.status} ${res.statusText}`, 'failed');
40
+ }
41
+ return (await res.json());
42
+ }
43
+ }
44
+ //# sourceMappingURL=legacy_client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy_client.js","sourceRoot":"","sources":["../src/legacy_client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAwB5C,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAGzB;IAFlB,YACE,OAAe,EACC,IAAyD;QAEzE,KAAK,CAAC,OAAO,CAAC,CAAA;QAFE,SAAI,GAAJ,IAAI,CAAqD;QAGzE,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;IAClC,CAAC;CACF;AAQD,sEAAsE;AACtE,MAAM,OAAO,kBAAkB;IACZ,IAAI,CAAQ;IACZ,SAAS,CAAW;IACpB,SAAS,CAAQ;IAElC,YAAY,OAA4B,EAAE;QACxC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,uBAAuB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;QACxE,IAAI,CAAC,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC7C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,OAAO,CAAA,CAAC,oCAAoC;IACjF,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAwB;QACnC,IAAI,GAAmC,CAAA;QACvC,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,IAAI,gBAAgB,EAAE;gBACvD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;aAC1B,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,kBAAkB,CAC1B,wCAAwC,IAAI,CAAC,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EACxG,MAAM,CACP,CAAA;QACH,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YACpB,MAAM,IAAI,kBAAkB,CAC1B,iEAAiE,EACjE,aAAa,CACd,CAAA;QACH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAwB,CAAA;YACtD,MAAM,IAAI,kBAAkB,CAAC,kBAAkB,IAAI,CAAC,MAAM,IAAI,SAAS,EAAE,EAAE,eAAe,CAAC,CAAA;QAC7F,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,kBAAkB,CAC1B,yBAAyB,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,EACvD,QAAQ,CACT,CAAA;QACH,CAAC;QACD,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAyB,CAAA;IACnD,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export declare const ANSWER_JSON_SCHEMA: Record<string, unknown>;
2
+ //# sourceMappingURL=answerSchema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"answerSchema.d.ts","sourceRoot":"","sources":["../../src/lib/answerSchema.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAsBtD,CAAA"}
@@ -0,0 +1,27 @@
1
+ // JSON Schema passed to providers that support structured output, so the
2
+ // model returns a citation-carrying answer the retrieval validator can check.
3
+ // Mirrors schema/answer.schema.json.
4
+ export const ANSWER_JSON_SCHEMA = {
5
+ type: 'object',
6
+ required: ['answer', 'claims'],
7
+ additionalProperties: false,
8
+ properties: {
9
+ answer: { type: 'string' },
10
+ insufficient_evidence: { type: 'boolean' },
11
+ claims: {
12
+ type: 'array',
13
+ items: {
14
+ type: 'object',
15
+ required: ['quote', 'utterance_id', 'session_id', 'confidence'],
16
+ additionalProperties: false,
17
+ properties: {
18
+ quote: { type: 'string' },
19
+ utterance_id: { type: 'string' },
20
+ session_id: { type: 'string' },
21
+ confidence: { type: 'number' },
22
+ },
23
+ },
24
+ },
25
+ },
26
+ };
27
+ //# sourceMappingURL=answerSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"answerSchema.js","sourceRoot":"","sources":["../../src/lib/answerSchema.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,8EAA8E;AAC9E,qCAAqC;AACrC,MAAM,CAAC,MAAM,kBAAkB,GAA4B;IACzD,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC9B,oBAAoB,EAAE,KAAK;IAC3B,UAAU,EAAE;QACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC1B,qBAAqB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QAC1C,MAAM,EAAE;YACN,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,CAAC;gBAC/D,oBAAoB,EAAE,KAAK;gBAC3B,UAAU,EAAE;oBACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACzB,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAChC,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAC9B,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;iBAC/B;aACF;SACF;KACF;CACF,CAAA"}
@@ -0,0 +1,64 @@
1
+ import Database from 'better-sqlite3';
2
+ import { type Author } from './events.js';
3
+ export interface CreatedArtifact {
4
+ id: string;
5
+ artifact_id: string;
6
+ path: string;
7
+ event_id: string;
8
+ }
9
+ export interface CreateHighlightInput {
10
+ sessionId: string;
11
+ utteranceId: string;
12
+ span: [number, number];
13
+ text: string;
14
+ author: Author;
15
+ }
16
+ export declare function createHighlight(seedPath: string, input: CreateHighlightInput): CreatedArtifact;
17
+ export interface CreateCodeInput {
18
+ name: string;
19
+ definition: string;
20
+ evidence?: string[];
21
+ author: Author;
22
+ }
23
+ export declare function createCode(seedPath: string, input: CreateCodeInput): CreatedArtifact;
24
+ export interface CreateThemeInput {
25
+ name: string;
26
+ summary: string;
27
+ codes?: string[];
28
+ author: Author;
29
+ }
30
+ export declare function createTheme(seedPath: string, input: CreateThemeInput): CreatedArtifact;
31
+ interface CreateEventRow {
32
+ id: string;
33
+ artifact_kind: string;
34
+ }
35
+ /**
36
+ * Human-id form for an artifact ref: `H-NNN`, `C-slug`, `T-slug` — the id
37
+ * `compost create` prints. We accept it wherever a SHA prefix is accepted so
38
+ * the obvious `endorse <id-from-create>` round-trip works (#168). The dash and
39
+ * non-hex chars make it unambiguous vs a SHA prefix (`^[a-f0-9]{8,64}$`).
40
+ */
41
+ export declare const HUMAN_REF_RE: RegExp;
42
+ /**
43
+ * Look up a create event by the human id stored in its payload (initialState.id).
44
+ * Returns undefined when the ref isn't a human id OR no matching create exists,
45
+ * so callers can fall through to SHA-prefix / latest: handling.
46
+ */
47
+ export declare function tryResolveHumanRef(db: Database.Database, ref: string): (CreateEventRow & {
48
+ artifact_id: string;
49
+ }) | undefined;
50
+ /**
51
+ * Resolve an artifact ref (human id, full/prefix SHA, or `latest:<kind>=<seed>`)
52
+ * to its create event, then emit a researcher endorse chaining it. Mirrors
53
+ * blame's ref resolution so `compost endorse <id-from-create>` works (#168).
54
+ */
55
+ export declare function endorseArtifact(seedPath: string, artifactRef: string, researcherId: string): {
56
+ artifact_id: string;
57
+ endorse_event_id: string;
58
+ parent_event_id: string;
59
+ already_endorsed?: true;
60
+ };
61
+ /** Read the configured researcher identity: COMPOST_USER env, else fallback. */
62
+ export declare function defaultResearcherId(): string;
63
+ export {};
64
+ //# sourceMappingURL=artifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../src/lib/artifacts.ts"],"names":[],"mappings":"AAGA,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AAGrC,OAAO,EAAE,KAAK,MAAM,EAAuD,MAAM,aAAa,CAAA;AAE9F,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB;AA8ED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,GAAG,eAAe,CA+B9F;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,eAAe,CA2BpF;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,eAAe,CA4BtF;AAID,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,aAAa,EAAE,MAAM,CAAA;CACtB;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,QAA2B,CAAA;AAEpD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,GAAG,EAAE,MAAM,GACV,CAAC,cAAc,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,CAOxD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB;IACD,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,MAAM,CAAA;IACvB,gBAAgB,CAAC,EAAE,IAAI,CAAA;CACxB,CAmFA;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
@@ -0,0 +1,254 @@
1
+ import { existsSync, mkdirSync, readdirSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import Database from 'better-sqlite3';
4
+ import { CompostError } from '../errors.js';
5
+ import { artifactId, emitCreate, emitEndorse, openSeedEvents } from './events.js';
6
+ // ---------------------------------------------------------------- helpers
7
+ /** Next sequential H-NNN in highlights/, scanning existing files. */
8
+ function nextHighlightId(dir) {
9
+ let max = 0;
10
+ if (existsSync(dir)) {
11
+ for (const f of readdirSync(dir)) {
12
+ const m = /^H-(\d+)\.md$/.exec(f);
13
+ if (m)
14
+ max = Math.max(max, Number.parseInt(m[1], 10));
15
+ }
16
+ }
17
+ return `H-${String(max + 1).padStart(3, '0')}`;
18
+ }
19
+ /** Filesystem-safe slug for code/theme names. */
20
+ function slug(name) {
21
+ const s = name
22
+ .toLowerCase()
23
+ .trim()
24
+ .replace(/[^a-z0-9]+/g, '-')
25
+ .replace(/^-+|-+$/g, '');
26
+ if (s.length === 0)
27
+ throw new CompostError('INVALID_INPUT', `Name has no slug-able characters: ${JSON.stringify(name)}`);
28
+ return s;
29
+ }
30
+ function frontmatter(fields) {
31
+ const lines = Object.entries(fields).map(([k, v]) => `${k}: ${formatYamlValue(v)}`);
32
+ return `---\n${lines.join('\n')}\n---\n`;
33
+ }
34
+ function formatYamlValue(v) {
35
+ if (Array.isArray(v))
36
+ return `[${v.map((x) => String(x)).join(', ')}]`;
37
+ if (typeof v === 'object' && v !== null) {
38
+ const inner = Object.entries(v)
39
+ .map(([k, val]) => `${k}: ${String(val)}`)
40
+ .join(', ');
41
+ return `{ ${inner} }`;
42
+ }
43
+ return String(v);
44
+ }
45
+ // ---------------------------------------------------------------- create
46
+ /**
47
+ * Write the markdown, then emit its create event — atomically. If the event
48
+ * fails (e.g. schema validation: AI events require model + prompt_hash), roll
49
+ * the file back so no code path ever leaves a `.md` without a matching create
50
+ * event (#165). The caller guarantees `path` did not pre-exist (existsSync
51
+ * check / fresh sequential id), so the rollback only removes our own write.
52
+ */
53
+ function writeArtifactAtomic(seedPath, path, body, event) {
54
+ writeFileSync(path, body, 'utf8');
55
+ const events = openSeedEvents(seedPath);
56
+ try {
57
+ return emitCreate(events, event).id;
58
+ }
59
+ catch (err) {
60
+ try {
61
+ rmSync(path, { force: true }); // roll back the orphan-to-be
62
+ }
63
+ catch {
64
+ // best-effort cleanup; surface the original (more useful) error regardless
65
+ }
66
+ throw err;
67
+ }
68
+ finally {
69
+ events.close();
70
+ }
71
+ }
72
+ export function createHighlight(seedPath, input) {
73
+ const dir = join(seedPath, 'highlights');
74
+ mkdirSync(dir, { recursive: true });
75
+ const id = nextHighlightId(dir);
76
+ // initialState is what the SHA addresses — the artifact's identity at birth.
77
+ const initialState = {
78
+ id,
79
+ kind: 'highlight',
80
+ session_id: input.sessionId,
81
+ utterance_id: input.utteranceId,
82
+ span: input.span,
83
+ text: input.text,
84
+ };
85
+ const sha = artifactId(initialState);
86
+ const body = `${frontmatter({
87
+ id,
88
+ session_id: input.sessionId,
89
+ utterance_id: input.utteranceId,
90
+ span: input.span,
91
+ artifact_id: sha,
92
+ provenance: { actor_type: input.author.actorType, actor_id: input.author.actorId },
93
+ })}\n${input.text}\n`;
94
+ const path = join(dir, `${id}.md`);
95
+ const event_id = writeArtifactAtomic(seedPath, path, body, {
96
+ artifactKind: 'highlight',
97
+ initialState,
98
+ author: input.author,
99
+ });
100
+ return { id, artifact_id: sha, path, event_id };
101
+ }
102
+ export function createCode(seedPath, input) {
103
+ const dir = join(seedPath, 'codebook');
104
+ mkdirSync(dir, { recursive: true });
105
+ const name = slug(input.name);
106
+ const id = `C-${name}`;
107
+ const evidence = input.evidence ?? [];
108
+ const initialState = { id, kind: 'code', name, definition: input.definition, evidence };
109
+ const sha = artifactId(initialState);
110
+ const body = `${frontmatter({
111
+ id,
112
+ name,
113
+ evidence,
114
+ artifact_id: sha,
115
+ provenance: { actor_type: input.author.actorType, actor_id: input.author.actorId },
116
+ })}\n${input.definition}\n`;
117
+ const path = join(dir, `${name}.md`);
118
+ if (existsSync(path)) {
119
+ throw new CompostError('INVALID_INPUT', `Code "${id}" already exists at ${path}`);
120
+ }
121
+ const event_id = writeArtifactAtomic(seedPath, path, body, {
122
+ artifactKind: 'code',
123
+ initialState,
124
+ author: input.author,
125
+ });
126
+ return { id, artifact_id: sha, path, event_id };
127
+ }
128
+ export function createTheme(seedPath, input) {
129
+ const dir = join(seedPath, 'synthesis', 'themes');
130
+ mkdirSync(dir, { recursive: true });
131
+ const name = slug(input.name);
132
+ const id = `T-${name}`;
133
+ const codes = input.codes ?? [];
134
+ const initialState = { id, kind: 'theme', name, summary: input.summary, codes };
135
+ const sha = artifactId(initialState);
136
+ const title = input.name.trim();
137
+ const body = `${frontmatter({
138
+ id,
139
+ name,
140
+ codes,
141
+ artifact_id: sha,
142
+ provenance: { actor_type: input.author.actorType, actor_id: input.author.actorId },
143
+ })}\n# ${title}\n\n${input.summary}\n`;
144
+ const path = join(dir, `${name}.md`);
145
+ if (existsSync(path)) {
146
+ throw new CompostError('INVALID_INPUT', `Theme "${id}" already exists at ${path}`);
147
+ }
148
+ const event_id = writeArtifactAtomic(seedPath, path, body, {
149
+ artifactKind: 'theme',
150
+ initialState,
151
+ author: input.author,
152
+ });
153
+ return { id, artifact_id: sha, path, event_id };
154
+ }
155
+ /**
156
+ * Human-id form for an artifact ref: `H-NNN`, `C-slug`, `T-slug` — the id
157
+ * `compost create` prints. We accept it wherever a SHA prefix is accepted so
158
+ * the obvious `endorse <id-from-create>` round-trip works (#168). The dash and
159
+ * non-hex chars make it unambiguous vs a SHA prefix (`^[a-f0-9]{8,64}$`).
160
+ */
161
+ export const HUMAN_REF_RE = /^[CHT]-[A-Za-z0-9_-]+$/;
162
+ /**
163
+ * Look up a create event by the human id stored in its payload (initialState.id).
164
+ * Returns undefined when the ref isn't a human id OR no matching create exists,
165
+ * so callers can fall through to SHA-prefix / latest: handling.
166
+ */
167
+ export function tryResolveHumanRef(db, ref) {
168
+ if (!HUMAN_REF_RE.test(ref))
169
+ return undefined;
170
+ return db
171
+ .prepare("SELECT id, artifact_kind, artifact_id FROM events WHERE action = 'create' AND json_extract(payload, '$.id') = ? ORDER BY ts, rowid LIMIT 1")
172
+ .get(ref);
173
+ }
174
+ /**
175
+ * Resolve an artifact ref (human id, full/prefix SHA, or `latest:<kind>=<seed>`)
176
+ * to its create event, then emit a researcher endorse chaining it. Mirrors
177
+ * blame's ref resolution so `compost endorse <id-from-create>` works (#168).
178
+ */
179
+ export function endorseArtifact(seedPath, artifactRef, researcherId) {
180
+ const eventsDb = join(seedPath, '.compost', 'events.sqlite');
181
+ if (!existsSync(eventsDb)) {
182
+ throw new CompostError('FILE_NOT_FOUND', `No events.sqlite in seed; nothing to endorse.`);
183
+ }
184
+ const db = new Database(eventsDb, { readonly: true, fileMustExist: true });
185
+ let createRow;
186
+ // Same (artifact_id, researcher) endorse already on the timeline → idempotent
187
+ // no-op (#169). Looked up alongside the create row so we hold the read-only
188
+ // connection once and avoid a stat/open dance.
189
+ let existingEndorse;
190
+ try {
191
+ createRow = tryResolveHumanRef(db, artifactRef);
192
+ if (createRow === undefined) {
193
+ const latest = /^latest:(\w+)=(.+)$/.exec(artifactRef);
194
+ if (latest) {
195
+ const kind = latest[1];
196
+ createRow = db
197
+ .prepare("SELECT id, artifact_kind, artifact_id FROM events WHERE artifact_kind = ? AND action = 'create' ORDER BY ts DESC, rowid DESC LIMIT 1")
198
+ .get(kind);
199
+ }
200
+ else if (/^[a-f0-9]{8,64}$/i.test(artifactRef)) {
201
+ createRow = db
202
+ .prepare("SELECT id, artifact_kind, artifact_id FROM events WHERE artifact_id LIKE ? AND action = 'create' ORDER BY ts, rowid LIMIT 1")
203
+ .get(`${artifactRef.toLowerCase()}%`);
204
+ }
205
+ else if (!HUMAN_REF_RE.test(artifactRef)) {
206
+ // Not human-shaped, not SHA-shaped, not latest: → user typed something
207
+ // unparseable. (Human-shaped refs that didn't resolve fall through to
208
+ // the FILE_NOT_FOUND below with a clearer message.)
209
+ throw new CompostError('INVALID_INPUT', `Invalid artifact ref "${artifactRef}". Use the id from \`compost create\` (e.g. C-slug, H-001), a SHA256 prefix, or latest:<kind>=<seed>.`);
210
+ }
211
+ }
212
+ if (createRow !== undefined) {
213
+ existingEndorse = db
214
+ .prepare("SELECT id, parent_event FROM events WHERE artifact_id = ? AND action = 'endorse' AND actor_id = ? ORDER BY ts, rowid LIMIT 1")
215
+ .get(createRow.artifact_id, researcherId);
216
+ }
217
+ }
218
+ finally {
219
+ db.close();
220
+ }
221
+ if (createRow === undefined) {
222
+ throw new CompostError('FILE_NOT_FOUND', `No create event found for ref "${artifactRef}".`);
223
+ }
224
+ if (existingEndorse !== undefined) {
225
+ return {
226
+ artifact_id: createRow.artifact_id,
227
+ endorse_event_id: existingEndorse.id,
228
+ parent_event_id: existingEndorse.parent_event ?? createRow.id,
229
+ already_endorsed: true,
230
+ };
231
+ }
232
+ const events = openSeedEvents(seedPath);
233
+ try {
234
+ const endorse = emitEndorse(events, {
235
+ artifactKind: createRow.artifact_kind,
236
+ artifactId: createRow.artifact_id,
237
+ parentEventId: createRow.id,
238
+ researcherId,
239
+ });
240
+ return {
241
+ artifact_id: createRow.artifact_id,
242
+ endorse_event_id: endorse.id,
243
+ parent_event_id: createRow.id,
244
+ };
245
+ }
246
+ finally {
247
+ events.close();
248
+ }
249
+ }
250
+ /** Read the configured researcher identity: COMPOST_USER env, else fallback. */
251
+ export function defaultResearcherId() {
252
+ return process.env.COMPOST_USER || process.env.USER || 'researcher';
253
+ }
254
+ //# sourceMappingURL=artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/lib/artifacts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export interface BlameEvent {
2
+ id: string;
3
+ ts: string;
4
+ artifact_kind: string;
5
+ artifact_id: string;
6
+ action: string;
7
+ actor_type: 'researcher' | 'agent' | 'ai';
8
+ actor_id: string;
9
+ agent_name: string | null;
10
+ agent_version: string | null;
11
+ prompt_hash: string | null;
12
+ model: string | null;
13
+ payload: unknown;
14
+ parent_event: string | null;
15
+ batch_id: string | null;
16
+ }
17
+ export interface BlameResult {
18
+ schema_version: '1.0';
19
+ query: string;
20
+ resolved_artifact_id: string;
21
+ seed: string;
22
+ events: BlameEvent[];
23
+ }
24
+ export interface BlameOptions {
25
+ cwd?: string;
26
+ seed?: string;
27
+ }
28
+ export declare function blame(query: string, opts?: BlameOptions): BlameResult;
29
+ export declare function renderHuman(result: BlameResult): string;
30
+ //# sourceMappingURL=blame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blame.d.ts","sourceRoot":"","sources":["../../src/lib/blame.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,YAAY,GAAG,OAAO,GAAG,IAAI,CAAA;IACzC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,KAAK,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,oBAAoB,EAAE,MAAM,CAAA;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,UAAU,EAAE,CAAA;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAsBD,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,WAAW,CA4BzE;AAkJD,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAqBvD"}
@@ -0,0 +1,164 @@
1
+ import { existsSync, readdirSync, statSync } from 'node:fs';
2
+ import { join, resolve } from 'node:path';
3
+ import Database from 'better-sqlite3';
4
+ import { CompostError } from '../errors.js';
5
+ import { HUMAN_REF_RE, tryResolveHumanRef } from './artifacts.js';
6
+ const ARTIFACT_PREFIX_RE = /^[a-f0-9]{8,64}$/i;
7
+ const LATEST_REF_RE = /^latest:(\w+)=(.+)$/;
8
+ export function blame(query, opts = {}) {
9
+ const cwd = opts.cwd ?? process.cwd();
10
+ const seedName = resolveSeedForBlame(query, opts.seed, cwd);
11
+ const eventsDb = resolve(cwd, 'Seeds', seedName, '.compost', 'events.sqlite');
12
+ if (!existsSync(eventsDb)) {
13
+ throw new CompostError('FILE_NOT_FOUND', `No events.sqlite at ${eventsDb}. Has any artifact been created in seed "${seedName}"?`);
14
+ }
15
+ const db = new Database(eventsDb, { readonly: true, fileMustExist: true });
16
+ try {
17
+ const artifactId = resolveArtifactId(db, query, seedName);
18
+ const rows = db
19
+ .prepare('SELECT * FROM events WHERE artifact_id = ? ORDER BY ts, rowid')
20
+ .all(artifactId);
21
+ return {
22
+ schema_version: '1.0',
23
+ query,
24
+ resolved_artifact_id: artifactId,
25
+ seed: seedName,
26
+ events: rows.map(rowToEvent),
27
+ };
28
+ }
29
+ finally {
30
+ db.close();
31
+ }
32
+ }
33
+ function rowToEvent(row) {
34
+ return {
35
+ id: row.id,
36
+ ts: row.ts,
37
+ artifact_kind: row.artifact_kind,
38
+ artifact_id: row.artifact_id,
39
+ action: row.action,
40
+ actor_type: row.actor_type,
41
+ actor_id: row.actor_id,
42
+ agent_name: row.agent_name,
43
+ agent_version: row.agent_version,
44
+ prompt_hash: row.prompt_hash,
45
+ model: row.model,
46
+ payload: JSON.parse(row.payload),
47
+ parent_event: row.parent_event,
48
+ batch_id: row.batch_id,
49
+ };
50
+ }
51
+ function resolveArtifactId(db, query, seed) {
52
+ // Human id (H-NNN / C-slug / T-slug) — the form `compost create` prints (#168).
53
+ // Tried first so a human ref short-circuits before the SHA/latest branches.
54
+ const humanRow = tryResolveHumanRef(db, query);
55
+ if (humanRow !== undefined)
56
+ return humanRow.artifact_id;
57
+ if (HUMAN_REF_RE.test(query)) {
58
+ throw new CompostError('FILE_NOT_FOUND', `No artifact with id "${query}" in seed "${seed}".`);
59
+ }
60
+ const latestMatch = LATEST_REF_RE.exec(query);
61
+ if (latestMatch !== null) {
62
+ const kind = latestMatch[1];
63
+ const target = latestMatch[2];
64
+ if (target !== seed) {
65
+ throw new CompostError('INVALID_INPUT', `latest: ref points at seed "${target}" but we resolved seed "${seed}"`);
66
+ }
67
+ const row = db
68
+ .prepare('SELECT artifact_id FROM events WHERE artifact_kind = ? AND action = ? ORDER BY ts DESC, rowid DESC LIMIT 1')
69
+ .get(kind, 'create');
70
+ if (row === undefined) {
71
+ throw new CompostError('FILE_NOT_FOUND', `No "${kind}" artifacts found in seed "${seed}"`);
72
+ }
73
+ return row.artifact_id;
74
+ }
75
+ if (!ARTIFACT_PREFIX_RE.test(query)) {
76
+ throw new CompostError('INVALID_INPUT', `Invalid artifact ref "${query}". Expected the id from \`compost create\` (e.g. C-slug, H-001), a SHA256 prefix (8-64 hex chars), or "latest:<kind>=<seed>".`);
77
+ }
78
+ if (query.length === 64)
79
+ return query.toLowerCase();
80
+ const matches = db
81
+ .prepare('SELECT DISTINCT artifact_id FROM events WHERE artifact_id LIKE ?')
82
+ .all(`${query.toLowerCase()}%`);
83
+ if (matches.length === 0) {
84
+ throw new CompostError('FILE_NOT_FOUND', `No artifact found matching prefix "${query}" in seed "${seed}"`);
85
+ }
86
+ if (matches.length > 1) {
87
+ throw new CompostError('INVALID_INPUT', `Prefix "${query}" is ambiguous (${matches.length} matches). Use more characters.`);
88
+ }
89
+ return matches[0].artifact_id;
90
+ }
91
+ /**
92
+ * Resolve the seed name for a blame query.
93
+ *
94
+ * Precedence:
95
+ * 1. Explicit `--seed` flag — wins, but errors if a `latest:kind=seed` ref
96
+ * embeds a different name.
97
+ * 2. Seed embedded in the ref (`latest:kind=<seed>`) — used when no flag is
98
+ * given; skips the multi-seed singleton check (the ref already disambiguates).
99
+ * 3. Fall back to `findSingletonSeed`, which errors in multi-seed workspaces.
100
+ *
101
+ * The earlier bug: precedence (3) fired before (2) was considered, so
102
+ * `compost blame latest:ingest_job=Lineage` errored in a multi-seed workspace
103
+ * even though the ref already named the seed.
104
+ */
105
+ function resolveSeedForBlame(query, seedFlag, cwd) {
106
+ const latestMatch = LATEST_REF_RE.exec(query);
107
+ const seedFromRef = latestMatch !== null ? latestMatch[2] : undefined;
108
+ if (seedFlag !== undefined && seedFromRef !== undefined && seedFlag !== seedFromRef) {
109
+ // When the only difference is case AND the flag's exact-cased name is not
110
+ // a directory entry, the user almost certainly mistyped — surface that
111
+ // instead of the misleading generic "disagrees" message.
112
+ //
113
+ // We readdirSync rather than existsSync because macOS HFS+/APFS is
114
+ // case-insensitive by default: existsSync('Seeds/lineage') returns true
115
+ // even when only 'Seeds/Lineage' is on disk. readdir gives us the actual
116
+ // directory entry names.
117
+ if (seedFlag.toLowerCase() === seedFromRef.toLowerCase()) {
118
+ const root = resolve(cwd, 'Seeds');
119
+ const entries = existsSync(root) ? readdirSync(root) : [];
120
+ if (!entries.includes(seedFlag)) {
121
+ throw new CompostError('INVALID_INPUT', `Seed names are case-sensitive; "${seedFlag}" does not exist. Did you mean "${seedFromRef}"?`);
122
+ }
123
+ }
124
+ throw new CompostError('INVALID_INPUT', `--seed "${seedFlag}" disagrees with ref-embedded seed "${seedFromRef}"`);
125
+ }
126
+ return seedFlag ?? seedFromRef ?? findSingletonSeed(cwd);
127
+ }
128
+ function findSingletonSeed(cwd) {
129
+ const root = resolve(cwd, 'Seeds');
130
+ if (!existsSync(root)) {
131
+ throw new CompostError('NOT_IN_SEED', `No Seeds/ at ${root}. Pass --seed <name> or run from a directory containing one.`);
132
+ }
133
+ const entries = readdirSync(root).filter((e) => !e.startsWith('.') && statSync(join(root, e)).isDirectory());
134
+ if (entries.length === 0) {
135
+ throw new CompostError('NOT_IN_SEED', `No seeds found under ${root}`);
136
+ }
137
+ if (entries.length > 1) {
138
+ throw new CompostError('INVALID_INPUT', `Multiple seeds under ${root} (${entries.join(', ')}). Pass --seed <name>.`);
139
+ }
140
+ return entries[0];
141
+ }
142
+ export function renderHuman(result) {
143
+ const lines = [];
144
+ lines.push(`blame ${result.resolved_artifact_id.slice(0, 12)}… (${result.events.length} events in seed "${result.seed}")`);
145
+ for (const e of result.events) {
146
+ const tag = e.actor_type === 'ai'
147
+ ? `[ai] ${e.model ?? '?'}`
148
+ : e.actor_type === 'agent'
149
+ ? `[agent] ${e.agent_name ?? '?'}@${e.agent_version ?? '?'}`
150
+ : `[researcher] ${e.actor_id}`;
151
+ lines.push('');
152
+ lines.push(`event ${e.id}`);
153
+ lines.push(` ${e.action.padEnd(8)} ${e.ts}`);
154
+ lines.push(` ${tag}`);
155
+ if (e.parent_event !== null)
156
+ lines.push(` parent ${e.parent_event}`);
157
+ if (e.batch_id !== null)
158
+ lines.push(` batch ${e.batch_id}`);
159
+ if (e.prompt_hash !== null)
160
+ lines.push(` prompt ${e.prompt_hash.slice(0, 12)}…`);
161
+ }
162
+ return lines.join('\n');
163
+ }
164
+ //# sourceMappingURL=blame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blame.js","sourceRoot":"","sources":["../../src/lib/blame.ts"],"names":[],"mappings":"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"}