@they-juanreina/compost-cli 0.1.2 → 0.1.4

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 (313) hide show
  1. package/dist/commands/agreement.d.ts +3 -0
  2. package/dist/commands/agreement.d.ts.map +1 -0
  3. package/dist/commands/agreement.js +35 -0
  4. package/dist/commands/agreement.js.map +1 -0
  5. package/dist/commands/backup.d.ts +3 -0
  6. package/dist/commands/backup.d.ts.map +1 -0
  7. package/dist/commands/backup.js +31 -0
  8. package/dist/commands/backup.js.map +1 -0
  9. package/dist/commands/chat.d.ts.map +1 -1
  10. package/dist/commands/chat.js +3 -2
  11. package/dist/commands/chat.js.map +1 -1
  12. package/dist/commands/create.d.ts +1 -0
  13. package/dist/commands/create.d.ts.map +1 -1
  14. package/dist/commands/create.js +39 -1
  15. package/dist/commands/create.js.map +1 -1
  16. package/dist/commands/export.d.ts.map +1 -1
  17. package/dist/commands/export.js +47 -4
  18. package/dist/commands/export.js.map +1 -1
  19. package/dist/commands/import.d.ts +3 -0
  20. package/dist/commands/import.d.ts.map +1 -0
  21. package/dist/commands/import.js +64 -0
  22. package/dist/commands/import.js.map +1 -0
  23. package/dist/commands/ingest.d.ts.map +1 -1
  24. package/dist/commands/ingest.js +1 -0
  25. package/dist/commands/ingest.js.map +1 -1
  26. package/dist/commands/init.d.ts.map +1 -1
  27. package/dist/commands/init.js +2 -0
  28. package/dist/commands/init.js.map +1 -1
  29. package/dist/commands/jobs.d.ts +3 -0
  30. package/dist/commands/jobs.d.ts.map +1 -0
  31. package/dist/commands/jobs.js +105 -0
  32. package/dist/commands/jobs.js.map +1 -0
  33. package/dist/commands/label.d.ts +3 -0
  34. package/dist/commands/label.d.ts.map +1 -0
  35. package/dist/commands/label.js +67 -0
  36. package/dist/commands/label.js.map +1 -0
  37. package/dist/commands/models.d.ts.map +1 -1
  38. package/dist/commands/models.js +2 -1
  39. package/dist/commands/models.js.map +1 -1
  40. package/dist/commands/recode.d.ts +3 -0
  41. package/dist/commands/recode.d.ts.map +1 -0
  42. package/dist/commands/recode.js +60 -0
  43. package/dist/commands/recode.js.map +1 -0
  44. package/dist/commands/reindex.d.ts.map +1 -1
  45. package/dist/commands/reindex.js +19 -7
  46. package/dist/commands/reindex.js.map +1 -1
  47. package/dist/commands/rerun.d.ts +3 -0
  48. package/dist/commands/rerun.d.ts.map +1 -0
  49. package/dist/commands/rerun.js +91 -0
  50. package/dist/commands/rerun.js.map +1 -0
  51. package/dist/commands/search.d.ts.map +1 -1
  52. package/dist/commands/search.js +12 -1
  53. package/dist/commands/search.js.map +1 -1
  54. package/dist/commands/secrets.d.ts +3 -0
  55. package/dist/commands/secrets.d.ts.map +1 -0
  56. package/dist/commands/secrets.js +145 -0
  57. package/dist/commands/secrets.js.map +1 -0
  58. package/dist/commands/setup.d.ts.map +1 -1
  59. package/dist/commands/setup.js +95 -2
  60. package/dist/commands/setup.js.map +1 -1
  61. package/dist/commands/setupItem.d.ts +26 -0
  62. package/dist/commands/setupItem.d.ts.map +1 -0
  63. package/dist/commands/setupItem.js +145 -0
  64. package/dist/commands/setupItem.js.map +1 -0
  65. package/dist/commands/status.d.ts.map +1 -1
  66. package/dist/commands/status.js +2 -1
  67. package/dist/commands/status.js.map +1 -1
  68. package/dist/commands/transcribe.d.ts.map +1 -1
  69. package/dist/commands/transcribe.js +32 -4
  70. package/dist/commands/transcribe.js.map +1 -1
  71. package/dist/commands/validate.d.ts.map +1 -1
  72. package/dist/commands/validate.js +29 -1
  73. package/dist/commands/validate.js.map +1 -1
  74. package/dist/commands/watch.d.ts.map +1 -1
  75. package/dist/commands/watch.js +53 -6
  76. package/dist/commands/watch.js.map +1 -1
  77. package/dist/engine.d.ts +23 -0
  78. package/dist/engine.d.ts.map +1 -0
  79. package/dist/engine.js +32 -0
  80. package/dist/engine.js.map +1 -0
  81. package/dist/errors.d.ts +5 -1
  82. package/dist/errors.d.ts.map +1 -1
  83. package/dist/errors.js +6 -0
  84. package/dist/errors.js.map +1 -1
  85. package/dist/exporters/pdf.d.ts.map +1 -1
  86. package/dist/exporters/pdf.js +2 -1
  87. package/dist/exporters/pdf.js.map +1 -1
  88. package/dist/exporters/prov.d.ts +11 -0
  89. package/dist/exporters/prov.d.ts.map +1 -0
  90. package/dist/exporters/prov.js +151 -0
  91. package/dist/exporters/prov.js.map +1 -0
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +6 -0
  94. package/dist/index.js.map +1 -1
  95. package/dist/legacy_client.d.ts.map +1 -1
  96. package/dist/legacy_client.js +2 -1
  97. package/dist/legacy_client.js.map +1 -1
  98. package/dist/lib/agreement.d.ts +77 -0
  99. package/dist/lib/agreement.d.ts.map +1 -0
  100. package/dist/lib/agreement.js +261 -0
  101. package/dist/lib/agreement.js.map +1 -0
  102. package/dist/lib/artifacts.d.ts +35 -2
  103. package/dist/lib/artifacts.d.ts.map +1 -1
  104. package/dist/lib/artifacts.js +158 -29
  105. package/dist/lib/artifacts.js.map +1 -1
  106. package/dist/lib/backup.d.ts +37 -0
  107. package/dist/lib/backup.d.ts.map +1 -0
  108. package/dist/lib/backup.js +57 -0
  109. package/dist/lib/backup.js.map +1 -0
  110. package/dist/lib/childEnv.d.ts +13 -0
  111. package/dist/lib/childEnv.d.ts.map +1 -0
  112. package/dist/lib/childEnv.js +45 -0
  113. package/dist/lib/childEnv.js.map +1 -0
  114. package/dist/lib/config.d.ts +3 -0
  115. package/dist/lib/config.d.ts.map +1 -1
  116. package/dist/lib/config.js.map +1 -1
  117. package/dist/lib/doctor.d.ts +3 -0
  118. package/dist/lib/doctor.d.ts.map +1 -1
  119. package/dist/lib/doctor.js +24 -1
  120. package/dist/lib/doctor.js.map +1 -1
  121. package/dist/lib/events.d.ts +44 -1
  122. package/dist/lib/events.d.ts.map +1 -1
  123. package/dist/lib/events.js +55 -2
  124. package/dist/lib/events.js.map +1 -1
  125. package/dist/lib/importTranscript.d.ts +16 -0
  126. package/dist/lib/importTranscript.d.ts.map +1 -0
  127. package/dist/lib/importTranscript.js +94 -0
  128. package/dist/lib/importTranscript.js.map +1 -0
  129. package/dist/lib/ingest.d.ts.map +1 -1
  130. package/dist/lib/ingest.js +12 -6
  131. package/dist/lib/ingest.js.map +1 -1
  132. package/dist/lib/journal.d.ts +13 -4
  133. package/dist/lib/journal.d.ts.map +1 -1
  134. package/dist/lib/journal.js +53 -16
  135. package/dist/lib/journal.js.map +1 -1
  136. package/dist/lib/legacyNative.d.ts +17 -0
  137. package/dist/lib/legacyNative.d.ts.map +1 -0
  138. package/dist/lib/legacyNative.js +38 -0
  139. package/dist/lib/legacyNative.js.map +1 -0
  140. package/dist/lib/migrate.d.ts.map +1 -1
  141. package/dist/lib/migrate.js +9 -2
  142. package/dist/lib/migrate.js.map +1 -1
  143. package/dist/lib/nativeRuntime.d.ts +31 -0
  144. package/dist/lib/nativeRuntime.d.ts.map +1 -1
  145. package/dist/lib/nativeRuntime.js +38 -0
  146. package/dist/lib/nativeRuntime.js.map +1 -1
  147. package/dist/lib/pathSafe.d.ts +8 -0
  148. package/dist/lib/pathSafe.d.ts.map +1 -0
  149. package/dist/lib/pathSafe.js +12 -0
  150. package/dist/lib/pathSafe.js.map +1 -0
  151. package/dist/lib/provisionNative.d.ts.map +1 -1
  152. package/dist/lib/provisionNative.js +7 -3
  153. package/dist/lib/provisionNative.js.map +1 -1
  154. package/dist/lib/queue.d.ts +25 -0
  155. package/dist/lib/queue.d.ts.map +1 -1
  156. package/dist/lib/queue.js +70 -3
  157. package/dist/lib/queue.js.map +1 -1
  158. package/dist/lib/reads.d.ts +24 -0
  159. package/dist/lib/reads.d.ts.map +1 -0
  160. package/dist/lib/reads.js +115 -0
  161. package/dist/lib/reads.js.map +1 -0
  162. package/dist/lib/recode.d.ts +19 -0
  163. package/dist/lib/recode.d.ts.map +1 -0
  164. package/dist/lib/recode.js +43 -0
  165. package/dist/lib/recode.js.map +1 -0
  166. package/dist/lib/redact.d.ts +7 -0
  167. package/dist/lib/redact.d.ts.map +1 -0
  168. package/dist/lib/redact.js +45 -0
  169. package/dist/lib/redact.js.map +1 -0
  170. package/dist/lib/rerun.d.ts +51 -0
  171. package/dist/lib/rerun.d.ts.map +1 -0
  172. package/dist/lib/rerun.js +160 -0
  173. package/dist/lib/rerun.js.map +1 -0
  174. package/dist/lib/retrieve.d.ts +8 -4
  175. package/dist/lib/retrieve.d.ts.map +1 -1
  176. package/dist/lib/retrieve.js +14 -3
  177. package/dist/lib/retrieve.js.map +1 -1
  178. package/dist/lib/saturate.js +3 -3
  179. package/dist/lib/saturate.js.map +1 -1
  180. package/dist/lib/schemas.generated.d.ts.map +1 -1
  181. package/dist/lib/schemas.generated.js +28 -0
  182. package/dist/lib/schemas.generated.js.map +1 -1
  183. package/dist/lib/secrets.d.ts +158 -0
  184. package/dist/lib/secrets.d.ts.map +1 -0
  185. package/dist/lib/secrets.js +514 -0
  186. package/dist/lib/secrets.js.map +1 -0
  187. package/dist/lib/seed.d.ts +5 -0
  188. package/dist/lib/seed.d.ts.map +1 -1
  189. package/dist/lib/seed.js +15 -2
  190. package/dist/lib/seed.js.map +1 -1
  191. package/dist/lib/seedResolve.d.ts +5 -0
  192. package/dist/lib/seedResolve.d.ts.map +1 -1
  193. package/dist/lib/seedResolve.js +12 -3
  194. package/dist/lib/seedResolve.js.map +1 -1
  195. package/dist/lib/session.d.ts +14 -0
  196. package/dist/lib/session.d.ts.map +1 -1
  197. package/dist/lib/session.js +53 -4
  198. package/dist/lib/session.js.map +1 -1
  199. package/dist/lib/sessionId.d.ts +9 -0
  200. package/dist/lib/sessionId.d.ts.map +1 -0
  201. package/dist/lib/sessionId.js +37 -0
  202. package/dist/lib/sessionId.js.map +1 -0
  203. package/dist/lib/setup.d.ts +9 -0
  204. package/dist/lib/setup.d.ts.map +1 -1
  205. package/dist/lib/setup.js +97 -29
  206. package/dist/lib/setup.js.map +1 -1
  207. package/dist/lib/setupItem.d.ts +99 -0
  208. package/dist/lib/setupItem.d.ts.map +1 -0
  209. package/dist/lib/setupItem.js +262 -0
  210. package/dist/lib/setupItem.js.map +1 -0
  211. package/dist/lib/setupWizard.d.ts +53 -0
  212. package/dist/lib/setupWizard.d.ts.map +1 -0
  213. package/dist/lib/setupWizard.js +347 -0
  214. package/dist/lib/setupWizard.js.map +1 -0
  215. package/dist/lib/snap.d.ts.map +1 -1
  216. package/dist/lib/snap.js +5 -0
  217. package/dist/lib/snap.js.map +1 -1
  218. package/dist/lib/speakers.d.ts +41 -0
  219. package/dist/lib/speakers.d.ts.map +1 -0
  220. package/dist/lib/speakers.js +78 -0
  221. package/dist/lib/speakers.js.map +1 -0
  222. package/dist/lib/status.d.ts.map +1 -1
  223. package/dist/lib/status.js +21 -0
  224. package/dist/lib/status.js.map +1 -1
  225. package/dist/lib/stdin.d.ts +5 -0
  226. package/dist/lib/stdin.d.ts.map +1 -0
  227. package/dist/lib/stdin.js +12 -0
  228. package/dist/lib/stdin.js.map +1 -0
  229. package/dist/lib/transcribeNative.d.ts +4 -9
  230. package/dist/lib/transcribeNative.d.ts.map +1 -1
  231. package/dist/lib/transcribeNative.js +11 -26
  232. package/dist/lib/transcribeNative.js.map +1 -1
  233. package/dist/lib/userConfig.d.ts +22 -0
  234. package/dist/lib/userConfig.d.ts.map +1 -0
  235. package/dist/lib/userConfig.js +67 -0
  236. package/dist/lib/userConfig.js.map +1 -0
  237. package/dist/lib/validate.d.ts +18 -0
  238. package/dist/lib/validate.d.ts.map +1 -1
  239. package/dist/lib/validate.js +71 -1
  240. package/dist/lib/validate.js.map +1 -1
  241. package/dist/lib/version.d.ts +30 -0
  242. package/dist/lib/version.d.ts.map +1 -0
  243. package/dist/lib/version.js +65 -0
  244. package/dist/lib/version.js.map +1 -0
  245. package/dist/llm/adapter.d.ts +5 -0
  246. package/dist/llm/adapter.d.ts.map +1 -1
  247. package/dist/llm/adapter.js +27 -8
  248. package/dist/llm/adapter.js.map +1 -1
  249. package/dist/llm/http.d.ts +22 -1
  250. package/dist/llm/http.d.ts.map +1 -1
  251. package/dist/llm/http.js +52 -30
  252. package/dist/llm/http.js.map +1 -1
  253. package/dist/llm/providers/anthropic.d.ts.map +1 -1
  254. package/dist/llm/providers/anthropic.js +6 -9
  255. package/dist/llm/providers/anthropic.js.map +1 -1
  256. package/dist/llm/providers/ollama.d.ts.map +1 -1
  257. package/dist/llm/providers/ollama.js +8 -7
  258. package/dist/llm/providers/ollama.js.map +1 -1
  259. package/dist/llm/providers/openai_compatible.d.ts.map +1 -1
  260. package/dist/llm/providers/openai_compatible.js +2 -7
  261. package/dist/llm/providers/openai_compatible.js.map +1 -1
  262. package/dist/logging.d.ts.map +1 -1
  263. package/dist/logging.js +3 -1
  264. package/dist/logging.js.map +1 -1
  265. package/dist/loops/embed_worker.d.ts +3 -0
  266. package/dist/loops/embed_worker.d.ts.map +1 -1
  267. package/dist/loops/embed_worker.js +11 -4
  268. package/dist/loops/embed_worker.js.map +1 -1
  269. package/dist/loops/ingest_watcher.d.ts.map +1 -1
  270. package/dist/loops/ingest_watcher.js +6 -3
  271. package/dist/loops/ingest_watcher.js.map +1 -1
  272. package/dist/loops/legacy_worker.d.ts +28 -1
  273. package/dist/loops/legacy_worker.d.ts.map +1 -1
  274. package/dist/loops/legacy_worker.js +91 -10
  275. package/dist/loops/legacy_worker.js.map +1 -1
  276. package/dist/loops/supervisor.d.ts +7 -0
  277. package/dist/loops/supervisor.d.ts.map +1 -1
  278. package/dist/loops/supervisor.js +17 -2
  279. package/dist/loops/supervisor.js.map +1 -1
  280. package/dist/loops/synthesis.d.ts.map +1 -1
  281. package/dist/loops/synthesis.js +15 -0
  282. package/dist/loops/synthesis.js.map +1 -1
  283. package/dist/loops/transcribe_worker.d.ts +3 -0
  284. package/dist/loops/transcribe_worker.d.ts.map +1 -1
  285. package/dist/loops/transcribe_worker.js +15 -7
  286. package/dist/loops/transcribe_worker.js.map +1 -1
  287. package/dist/output.d.ts +13 -1
  288. package/dist/output.d.ts.map +1 -1
  289. package/dist/output.js +27 -6
  290. package/dist/output.js.map +1 -1
  291. package/dist/render/glyphs.d.ts +30 -0
  292. package/dist/render/glyphs.d.ts.map +1 -0
  293. package/dist/render/glyphs.js +38 -0
  294. package/dist/render/glyphs.js.map +1 -0
  295. package/dist/render/human.d.ts +22 -0
  296. package/dist/render/human.d.ts.map +1 -0
  297. package/dist/render/human.js +62 -0
  298. package/dist/render/human.js.map +1 -0
  299. package/dist/router.d.ts.map +1 -1
  300. package/dist/router.js +32 -4
  301. package/dist/router.js.map +1 -1
  302. package/dist/transcriber_client.d.ts.map +1 -1
  303. package/dist/transcriber_client.js +2 -1
  304. package/dist/transcriber_client.js.map +1 -1
  305. package/package.json +12 -5
  306. package/templates/AGENTS.md +1 -1
  307. package/templates/config.toml +6 -1
  308. package/transcriber/app/diarization.py +36 -6
  309. package/transcriber/app/legacy_cli.py +90 -0
  310. package/transcriber/app/pipeline.py +13 -7
  311. package/transcriber/app/prosody.py +5 -0
  312. package/transcriber/app/transcribe_cli.py +15 -1
  313. package/transcriber/app/vad.py +82 -11
@@ -0,0 +1,347 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { errMessage } from '../errors.js';
4
+ import { fetchWithTimeout, resolveFetch } from '../llm/http.js';
5
+ import { glyphs, statusGlyph } from '../render/glyphs.js';
6
+ import { loadConfig, saveConfig, setConfigValue } from './config.js';
7
+ import { diagnoseNativeRuntime, isAppleSilicon } from './nativeRuntime.js';
8
+ import { provisionNativeVenv } from './provisionNative.js';
9
+ import { setSecret } from './secrets.js';
10
+ import { LICENSE_PROBE_TIMEOUT_MS, runSetup } from './setup.js';
11
+ import { actionsFor, runItem } from './setupItem.js';
12
+ import { saveUserConfig } from './userConfig.js';
13
+ /** Per-task routes the wizard writes for each chat-model choice. The local
14
+ * default matches the seed template's quick_chat model; the cloud routes keep
15
+ * the template's synthesis model and add a fast model for the local tasks. */
16
+ export const LOCAL_CHAT_MODEL = 'llama3.1:8b';
17
+ export const CLOUD_FAST_MODEL = 'anthropic:claude-haiku-4-5';
18
+ export const CLOUD_SYNTHESIS_MODEL = 'anthropic:claude-opus-4-7';
19
+ const PYANNOTE_GATED_REPOS = ['pyannote/speaker-diarization-3.1', 'pyannote/segmentation-3.0'];
20
+ function checkById(report, id) {
21
+ return report.checks.find((c) => c.id === id);
22
+ }
23
+ /** True for embedding models — not usable for chat, so they're filtered out of
24
+ * the chat-model picker (compost pulls bge-m3 for search; it would be a
25
+ * confusing pick here). */
26
+ function isEmbeddingModel(name) {
27
+ return /(^bge|embed)/i.test(name);
28
+ }
29
+ /** Names of the chat-capable models already installed in Ollama, best-effort.
30
+ * Returns [] on any error (offline, Ollama down) so the wizard falls back to
31
+ * offering a pull — never throws. Mirrors the /api/tags probe in setup.ts. */
32
+ async function listInstalledChatModels(fetchImpl, ollamaUrl) {
33
+ try {
34
+ const res = await fetchImpl(`${ollamaUrl}/api/tags`, { method: 'GET' });
35
+ if (!res.ok)
36
+ return [];
37
+ const json = (await res.json());
38
+ return (json.models ?? [])
39
+ .map((m) => m.name ?? '')
40
+ .filter((n) => n !== '' && !isEmbeddingModel(n));
41
+ }
42
+ catch {
43
+ return [];
44
+ }
45
+ }
46
+ function notOk(report, id) {
47
+ const c = checkById(report, id);
48
+ return c !== undefined && c.status !== 'ok';
49
+ }
50
+ function printReport(io, report) {
51
+ for (const c of report.checks) {
52
+ io.say(` ${statusGlyph(c.status)} ${c.label} — ${c.detail}`);
53
+ }
54
+ }
55
+ /**
56
+ * Guided setup: walk every fixable gap with a per-step confirmed fix, collect
57
+ * the secrets the pipeline needs (HF token, optional LLM key), and let the
58
+ * user pick how `compost chat` should run on this machine. Every mutation is
59
+ * proposed before it runs; declining any step just moves on. The non-TTY
60
+ * `compost setup` diagnostic is unchanged — this runs only at a terminal.
61
+ */
62
+ export async function runSetupWizard(deps) {
63
+ const io = deps.io;
64
+ const cwd = deps.cwd ?? process.cwd();
65
+ const env = deps.env ?? process.env;
66
+ const apple = deps.appleSilicon ?? isAppleSilicon();
67
+ const check = deps.check ?? runSetup;
68
+ const run = deps.run ?? (() => ({ ok: false }));
69
+ const provision = deps.provision ?? provisionNativeVenv;
70
+ const storeSecret = deps.storeSecret ?? setSecret;
71
+ const saveDefaults = deps.saveDefaults ?? saveUserConfig;
72
+ const fetchImpl = resolveFetch(deps.fetchImpl);
73
+ const ollamaUrl = (deps.ollamaUrl ?? 'http://localhost:11434').replace(/\/$/, '');
74
+ const actions = [];
75
+ io.say('compost setup — guided');
76
+ io.say(`platform: ${process.platform}/${process.arch}${apple ? ' (native transcription)' : ' (Docker transcription fallback)'}`);
77
+ io.say('');
78
+ let report = await check({ cwd, env });
79
+ printReport(io, report);
80
+ io.say('');
81
+ // ── Outdated install: fix this first — everything else may be its symptom ─
82
+ if (notOk(report, 'version')) {
83
+ const detail = checkById(report, 'version')?.detail ?? '';
84
+ io.say(`This install is outdated (${detail}).`);
85
+ if (await io.confirm('Upgrade now (npm install -g @they-juanreina/compost-cli@latest)?', true)) {
86
+ const ok = run('npm', ['install', '-g', '@they-juanreina/compost-cli@latest']).ok;
87
+ actions.push(ok ? 'upgraded CLI — rerun `compost setup` on the new version' : 'upgrade failed');
88
+ if (ok) {
89
+ io.say('Upgraded. Rerun `compost setup` so the new version takes it from here.');
90
+ return { report, actions };
91
+ }
92
+ }
93
+ }
94
+ // ── Ollama: the embeddings (and optionally chat) engine ──────────────────
95
+ if (notOk(report, 'ollama')) {
96
+ io.say('Ollama powers search embeddings and local chat. It is not running.');
97
+ const brewAvailable = process.platform === 'darwin' && run('which', ['brew']).ok;
98
+ if (brewAvailable) {
99
+ if (await io.confirm('Install and start Ollama via Homebrew (brew install ollama)?', true)) {
100
+ const installed = run('brew', ['install', 'ollama']).ok;
101
+ const started = installed && run('brew', ['services', 'start', 'ollama']).ok;
102
+ actions.push(started ? 'installed + started Ollama' : 'Ollama install attempted — check output above');
103
+ }
104
+ }
105
+ else {
106
+ io.say('Install it from https://ollama.com/download, then open the app (or run `ollama serve`).');
107
+ }
108
+ }
109
+ // ── Embedding model ───────────────────────────────────────────────────────
110
+ if (notOk(report, 'model:bge-m3')) {
111
+ if (await io.confirm('Pull the embedding model bge-m3 (~1.2 GB)?', true)) {
112
+ const ok = run('ollama', ['pull', 'bge-m3']).ok;
113
+ actions.push(ok ? 'pulled bge-m3' : 'bge-m3 pull failed — is Ollama running?');
114
+ }
115
+ }
116
+ // ── Transcription engine (also required for PDF/document ingest) ─────────
117
+ if (apple && notOk(report, 'native-transcribe')) {
118
+ io.say('');
119
+ io.say('Transcription runs natively on Apple Silicon (the same engine also ingests PDFs and documents).');
120
+ if (await io.confirm('Provision the native engine now (downloads ~1 GB of Python wheels, a few minutes)?', true)) {
121
+ try {
122
+ const result = provision({});
123
+ actions.push(`native engine: ${result.status}`);
124
+ }
125
+ catch (err) {
126
+ io.say(` provisioning failed: ${errMessage(err)}`);
127
+ actions.push('native provisioning failed');
128
+ }
129
+ }
130
+ }
131
+ else if (!apple && notOk(report, 'transcriber')) {
132
+ const transcriberDir = diagnoseNativeRuntime({ env }).transcriberDir;
133
+ if (transcriberDir !== undefined && existsSync(join(transcriberDir, 'compose.yaml'))) {
134
+ io.say('');
135
+ io.say('Transcription (and PDF/document ingest) runs in Docker on this platform.');
136
+ if (await io.confirm('Build and start the transcriber container (first build downloads several GB)?', true)) {
137
+ const ok = run('docker', [
138
+ 'compose',
139
+ '-f',
140
+ join(transcriberDir, 'compose.yaml'),
141
+ 'up',
142
+ '--build',
143
+ '-d',
144
+ ]).ok;
145
+ actions.push(ok ? 'transcriber container started' : 'docker compose failed — is Docker running?');
146
+ }
147
+ }
148
+ else {
149
+ io.say('Could not locate the bundled transcriber sources — reinstall @they-juanreina/compost-cli.');
150
+ }
151
+ }
152
+ // ── HuggingFace token (audio diarization only) ────────────────────────────
153
+ if (notOk(report, 'hf-token')) {
154
+ io.say('');
155
+ io.say('Audio transcription labels who is speaking (diarization), which needs a free HuggingFace account:');
156
+ io.say(' 1. Token: https://hf.co/settings/tokens (a "read" token is enough)');
157
+ io.say(' 2. Licenses: accept on BOTH model pages, logged in as the same account —');
158
+ for (const repo of PYANNOTE_GATED_REPOS)
159
+ io.say(` https://huggingface.co/${repo}`);
160
+ io.say('PDF and document ingest do not need this — Enter skips, and `compost setup` can add it later.');
161
+ const token = (await io.askHidden('HuggingFace token (hidden, Enter to skip): ')).trim();
162
+ if (token !== '') {
163
+ const stored = storeSecret('HUGGINGFACE_TOKEN', token);
164
+ actions.push(`HF token stored in ${stored.stored_in}`);
165
+ for (const repo of PYANNOTE_GATED_REPOS) {
166
+ let accepted = false;
167
+ try {
168
+ const res = await fetchWithTimeout(fetchImpl, `https://huggingface.co/${repo}/resolve/main/config.yaml`, { method: 'GET', headers: { Authorization: `Bearer ${token}` } }, LICENSE_PROBE_TIMEOUT_MS);
169
+ accepted = res.ok;
170
+ }
171
+ catch {
172
+ accepted = false;
173
+ }
174
+ const lg = glyphs();
175
+ io.say(accepted
176
+ ? ` ${lg.ok} license accepted: ${repo}`
177
+ : ` ${lg.warn} license NOT accepted yet: https://huggingface.co/${repo}`);
178
+ }
179
+ }
180
+ }
181
+ // ── Chat model: how should `compost chat` answer on this machine? ────────
182
+ io.say('');
183
+ io.say('`compost chat` answers questions from your transcripts. Pick how it should run:');
184
+ io.say(' [1] local — run offline via Ollama (reuse a model you have, or pull one)');
185
+ io.say(' [2] cloud — use an Anthropic API key (best quality; sends excerpts to the API)');
186
+ io.say(' [3] skip for now');
187
+ const choice = (await io.ask('Choice', '1')).trim();
188
+ let routes = null;
189
+ if (choice === '1') {
190
+ // Offer the chat models already installed first — no reason to force a
191
+ // multi-GB pull when a capable model is sitting in Ollama's store.
192
+ const installed = await listInstalledChatModels(fetchImpl, ollamaUrl);
193
+ let model = '';
194
+ let needsPull = true;
195
+ if (installed.length > 0) {
196
+ io.say(' Use a model you already have (no download), or pull a new one:');
197
+ for (const [i, m] of installed.entries())
198
+ io.say(` [${i + 1}] ${m} (installed)`);
199
+ io.say(` [${installed.length + 1}] pull a different model (default ${LOCAL_CHAT_MODEL})`);
200
+ const pick = Number.parseInt((await io.ask('Model number', '1')).trim(), 10) - 1;
201
+ if (pick >= 0 && pick < installed.length) {
202
+ model = installed[pick];
203
+ needsPull = false;
204
+ }
205
+ }
206
+ if (needsPull) {
207
+ model = (await io.ask('Model to pull', LOCAL_CHAT_MODEL)).trim() || LOCAL_CHAT_MODEL;
208
+ if (!run('ollama', ['pull', model]).ok) {
209
+ io.say(' pull failed — is Ollama running? Rerun `compost setup` to retry.');
210
+ model = '';
211
+ }
212
+ }
213
+ if (model !== '') {
214
+ routes = {
215
+ quick_chat: `ollama:${model}`,
216
+ verification: `ollama:${model}`,
217
+ synthesis: `ollama:${model}`,
218
+ };
219
+ actions.push(`chat: local via ollama:${model}`);
220
+ io.say(' (cloud-quality synthesis can be added any time: rerun `compost setup` and pick cloud.)');
221
+ }
222
+ }
223
+ else if (choice === '2') {
224
+ const key = (await io.askHidden('Anthropic API key (hidden): ')).trim();
225
+ if (key !== '') {
226
+ const stored = storeSecret('ANTHROPIC_API_KEY', key);
227
+ routes = {
228
+ quick_chat: CLOUD_FAST_MODEL,
229
+ verification: CLOUD_FAST_MODEL,
230
+ synthesis: CLOUD_SYNTHESIS_MODEL,
231
+ };
232
+ actions.push(`chat: cloud (key in ${stored.stored_in})`);
233
+ }
234
+ }
235
+ if (routes !== null) {
236
+ const path = saveDefaults({ defaults: routes }, env);
237
+ io.say(` routing saved to ${path} — new seeds inherit it automatically.`);
238
+ const seeds = (deps.listSeeds ?? (() => []))();
239
+ for (const seedPath of seeds) {
240
+ if (await io.confirm(`Update model routing in the existing seed ${seedPath}?`, true)) {
241
+ const raw = loadConfig(seedPath).raw;
242
+ for (const [task, route] of Object.entries(routes)) {
243
+ setConfigValue(raw, `defaults.${task}`, route);
244
+ }
245
+ saveConfig(seedPath, raw);
246
+ actions.push(`updated routing: ${seedPath}`);
247
+ }
248
+ }
249
+ }
250
+ // ── Re-check and summarize ────────────────────────────────────────────────
251
+ io.say('');
252
+ report = await check({ cwd, env });
253
+ printReport(io, report);
254
+ io.say('');
255
+ // ── Maintain one item (change/renew/forget a token, re-pull a model) ──────
256
+ // Only once the install is otherwise healthy, so a first-run-with-gaps flow
257
+ // is unchanged. This is the path a *returning* user needs — the gap-driven
258
+ // walk above only surfaces an item when it is broken, never to change a set
259
+ // one. Driven by item number (blank = skip), so it wraps the same `runItem`
260
+ // primitive the `compost setup item` CLI and the skill use.
261
+ if (report.ready) {
262
+ await maintainItem({ io, report, run, fetchImpl, storeSecret, actions });
263
+ }
264
+ io.say(report.ready
265
+ ? 'Ready. Next steps:'
266
+ : 'Some checks still need attention (see above). Next steps:');
267
+ io.say(' compost init <study-name> # create a study');
268
+ io.say(' open Seeds/<study-name>/sessions/_inbox # drop a recording or PDF in');
269
+ io.say(' compost watch --once # process it');
270
+ return { report, actions };
271
+ }
272
+ /**
273
+ * Interactive "fix one item" menu — the path a *returning* user needs once the
274
+ * install is healthy (the gap-driven walk above only ever surfaces an item when
275
+ * it is broken, never to change a set one). Lists every check that carries
276
+ * lifecycle actions, runs the chosen one through the shared `runItem` primitive
277
+ * (same code path as the `compost setup item` CLI and the skill), and surfaces
278
+ * the remote half — the part compost can't do. Selection is by number; a blank
279
+ * entry skips, so an exhausted/scripted IO is a no-op. One item per run.
280
+ */
281
+ async function maintainItem(args) {
282
+ const { io, report } = args;
283
+ const items = report.checks
284
+ .map((c) => ({ id: c.id, actions: actionsFor(c.id) }))
285
+ .filter((it) => it.actions.length > 0);
286
+ if (items.length === 0)
287
+ return;
288
+ io.say('Maintain a specific item? (e.g. change/renew/forget the HuggingFace token)');
289
+ for (const [i, it] of items.entries()) {
290
+ io.say(` [${i + 1}] ${it.id} (${it.actions.map((a) => a.id).join(' / ')})`);
291
+ }
292
+ const pick = (await io.ask('Item number (blank to finish)', '')).trim();
293
+ if (pick === '')
294
+ return;
295
+ const item = items[Number.parseInt(pick, 10) - 1];
296
+ if (!item) {
297
+ io.say(` no item "${pick}".`);
298
+ return;
299
+ }
300
+ for (const [i, a] of item.actions.entries()) {
301
+ io.say(` [${i + 1}] ${a.id} — ${a.label}${a.url ? ` (${a.url})` : ''}`);
302
+ }
303
+ const aPick = (await io.ask('Action number', '1')).trim();
304
+ const action = item.actions[Number.parseInt(aPick, 10) - 1];
305
+ if (!action) {
306
+ io.say(` no action "${aPick}".`);
307
+ return;
308
+ }
309
+ const deps = {
310
+ run: args.run,
311
+ fetchImpl: args.fetchImpl,
312
+ storeSecret: args.storeSecret,
313
+ };
314
+ if (action.id === 'renew') {
315
+ if (action.url)
316
+ io.say(` Mint a new token at ${action.url}, then paste it below.`);
317
+ const v = (await io.askHidden('New value (hidden, Enter to cancel): ')).trim();
318
+ if (v === '') {
319
+ io.say(' cancelled (no value).');
320
+ return;
321
+ }
322
+ deps.value = v;
323
+ }
324
+ else if (action.id === 'forget') {
325
+ if (!(await io.confirm(`Forget compost's local copy of ${item.id}?`, false))) {
326
+ io.say(' cancelled.');
327
+ return;
328
+ }
329
+ }
330
+ else if (action.id === 'pull') {
331
+ if (!(await io.confirm('Pull now (may download several GB)?', true))) {
332
+ io.say(' cancelled.');
333
+ return;
334
+ }
335
+ }
336
+ const result = await runItem(item.id, action.id, deps);
337
+ const glyph = statusGlyph(result.recheck.status);
338
+ io.say(` ${glyph} ${item.id} ${action.id}: ${result.recheck.detail}`);
339
+ const r = result.result;
340
+ if (r.remote_action) {
341
+ io.say(` remote step (yours to do): ${r.remote_action.note} — ${r.remote_action.url}`);
342
+ }
343
+ if (r.env_note)
344
+ io.say(` ${r.env_note}`);
345
+ args.actions.push(`maintained ${item.id}: ${action.id} → ${result.recheck.status}`);
346
+ }
347
+ //# sourceMappingURL=setupWizard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setupWizard.js","sourceRoot":"","sources":["../../src/lib/setupWizard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAE/D,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACzD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACpE,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACxC,OAAO,EAAE,wBAAwB,EAAE,QAAQ,EAAqC,MAAM,YAAY,CAAA;AAClG,OAAO,EAAE,UAAU,EAAoB,OAAO,EAAE,MAAM,gBAAgB,CAAA;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD;;8EAE8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAA;AAC7C,MAAM,CAAC,MAAM,gBAAgB,GAAG,4BAA4B,CAAA;AAC5D,MAAM,CAAC,MAAM,qBAAqB,GAAG,2BAA2B,CAAA;AAEhE,MAAM,oBAAoB,GAAG,CAAC,kCAAkC,EAAE,2BAA2B,CAAC,CAAA;AAoC9F,SAAS,SAAS,CAAC,MAAmB,EAAE,EAAU;IAChD,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;AAC/C,CAAC;AAED;;2BAE2B;AAC3B,SAAS,gBAAgB,CAAC,IAAY;IACpC,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACnC,CAAC;AAED;;8EAE8E;AAC9E,KAAK,UAAU,uBAAuB,CAAC,SAAoB,EAAE,SAAiB;IAC5E,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,SAAS,WAAW,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;QACvE,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,CAAA;QACtB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0C,CAAA;QACxE,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;aACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;aACxB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAA;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,MAAmB,EAAE,EAAU;IAC5C,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAC/B,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,CAAA;AAC7C,CAAC;AAED,SAAS,WAAW,CAAC,EAAY,EAAE,MAAmB;IACpD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAC9B,EAAE,CAAC,GAAG,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAA;IAC/D,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAgB;IACnD,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAA;IAClB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAA;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,IAAI,cAAc,EAAE,CAAA;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAA;IACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;IAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,mBAAmB,CAAA;IACvD,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,SAAS,CAAA;IACjD,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,cAAc,CAAA;IACxD,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAC9C,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,wBAAwB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IACjF,MAAM,OAAO,GAAa,EAAE,CAAA;IAE5B,EAAE,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAA;IAChC,EAAE,CAAC,GAAG,CACJ,aAAa,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,kCAAkC,EAAE,CACzH,CAAA;IACD,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACV,IAAI,MAAM,GAAG,MAAM,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAA;IACtC,WAAW,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IACvB,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAEV,6EAA6E;IAC7E,IAAI,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,IAAI,EAAE,CAAA;QACzD,EAAE,CAAC,GAAG,CAAC,6BAA6B,MAAM,IAAI,CAAC,CAAA;QAC/C,IACE,MAAM,EAAE,CAAC,OAAO,CAAC,kEAAkE,EAAE,IAAI,CAAC,EAC1F,CAAC;YACD,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,oCAAoC,CAAC,CAAC,CAAC,EAAE,CAAA;YACjF,OAAO,CAAC,IAAI,CACV,EAAE,CAAC,CAAC,CAAC,yDAAyD,CAAC,CAAC,CAAC,gBAAgB,CAClF,CAAA;YACD,IAAI,EAAE,EAAE,CAAC;gBACP,EAAE,CAAC,GAAG,CAAC,wEAAwE,CAAC,CAAA;gBAChF,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,IAAI,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC5B,EAAE,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAA;QAC5E,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;QAChF,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,MAAM,EAAE,CAAC,OAAO,CAAC,8DAA8D,EAAE,IAAI,CAAC,EAAE,CAAC;gBAC3F,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;gBACvD,MAAM,OAAO,GAAG,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;gBAC5E,OAAO,CAAC,IAAI,CACV,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,+CAA+C,CACzF,CAAA;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,GAAG,CACJ,yFAAyF,CAC1F,CAAA;QACH,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,IAAI,KAAK,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,CAAC;QAClC,IAAI,MAAM,EAAE,CAAC,OAAO,CAAC,4CAA4C,EAAE,IAAI,CAAC,EAAE,CAAC;YACzE,MAAM,EAAE,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;YAC/C,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,yCAAyC,CAAC,CAAA;QAChF,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAAE,CAAC;QAChD,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACV,EAAE,CAAC,GAAG,CACJ,iGAAiG,CAClG,CAAA;QACD,IACE,MAAM,EAAE,CAAC,OAAO,CACd,oFAAoF,EACpF,IAAI,CACL,EACD,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,CAAA;gBAC5B,OAAO,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;YACjD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,EAAE,CAAC,GAAG,CAAC,0BAA0B,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;gBACnD,OAAO,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAA;YAC5C,CAAC;QACH,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,CAAC;QAClD,MAAM,cAAc,GAAG,qBAAqB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,cAAc,CAAA;QACpE,IAAI,cAAc,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;YACrF,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACV,EAAE,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAA;YAClF,IACE,MAAM,EAAE,CAAC,OAAO,CACd,+EAA+E,EAC/E,IAAI,CACL,EACD,CAAC;gBACD,MAAM,EAAE,GAAG,GAAG,CAAC,QAAQ,EAAE;oBACvB,SAAS;oBACT,IAAI;oBACJ,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC;oBACpC,IAAI;oBACJ,SAAS;oBACT,IAAI;iBACL,CAAC,CAAC,EAAE,CAAA;gBACL,OAAO,CAAC,IAAI,CACV,EAAE,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,4CAA4C,CACpF,CAAA;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,GAAG,CACJ,2FAA2F,CAC5F,CAAA;QACH,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,IAAI,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACV,EAAE,CAAC,GAAG,CACJ,mGAAmG,CACpG,CAAA;QACD,EAAE,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAA;QAClF,EAAE,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAA;QACpF,KAAK,MAAM,IAAI,IAAI,oBAAoB;YAAE,EAAE,CAAC,GAAG,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAA;QACxF,EAAE,CAAC,GAAG,CACJ,+FAA+F,CAChG,CAAA;QACD,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,6CAA6C,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QACxF,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,WAAW,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAA;YACtD,OAAO,CAAC,IAAI,CAAC,sBAAsB,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;YACtD,KAAK,MAAM,IAAI,IAAI,oBAAoB,EAAE,CAAC;gBACxC,IAAI,QAAQ,GAAG,KAAK,CAAA;gBACpB,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAChC,SAAS,EACT,0BAA0B,IAAI,2BAA2B,EACzD,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,EAAE,EAChE,wBAAwB,CACzB,CAAA;oBACD,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAA;gBACnB,CAAC;gBAAC,MAAM,CAAC;oBACP,QAAQ,GAAG,KAAK,CAAA;gBAClB,CAAC;gBACD,MAAM,EAAE,GAAG,MAAM,EAAE,CAAA;gBACnB,EAAE,CAAC,GAAG,CACJ,QAAQ;oBACN,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,sBAAsB,IAAI,EAAE;oBACxC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,qDAAqD,IAAI,EAAE,CAC5E,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACV,EAAE,CAAC,GAAG,CAAC,iFAAiF,CAAC,CAAA;IACzF,EAAE,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAA;IACpF,EAAE,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAAA;IAC1F,EAAE,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;IAC5B,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IACnD,IAAI,MAAM,GAAkC,IAAI,CAAA;IAChD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,uEAAuE;QACvE,mEAAmE;QACnE,MAAM,SAAS,GAAG,MAAM,uBAAuB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;QACrE,IAAI,KAAK,GAAG,EAAE,CAAA;QACd,IAAI,SAAS,GAAG,IAAI,CAAA;QACpB,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,EAAE,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAA;YAC1E,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE;gBAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;YACpF,EAAE,CAAC,GAAG,CAAC,QAAQ,SAAS,CAAC,MAAM,GAAG,CAAC,qCAAqC,gBAAgB,GAAG,CAAC,CAAA;YAC5F,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAA;YAChF,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;gBACzC,KAAK,GAAG,SAAS,CAAC,IAAI,CAAW,CAAA;gBACjC,SAAS,GAAG,KAAK,CAAA;YACnB,CAAC;QACH,CAAC;QACD,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,gBAAgB,CAAA;YACpF,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBACvC,EAAE,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAA;gBAC5E,KAAK,GAAG,EAAE,CAAA;YACZ,CAAC;QACH,CAAC;QACD,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACjB,MAAM,GAAG;gBACP,UAAU,EAAE,UAAU,KAAK,EAAE;gBAC7B,YAAY,EAAE,UAAU,KAAK,EAAE;gBAC/B,SAAS,EAAE,UAAU,KAAK,EAAE;aAC7B,CAAA;YACD,OAAO,CAAC,IAAI,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAA;YAC/C,EAAE,CAAC,GAAG,CACJ,0FAA0F,CAC3F,CAAA;QACH,CAAC;IACH,CAAC;SAAM,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QACvE,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,WAAW,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAA;YACpD,MAAM,GAAG;gBACP,UAAU,EAAE,gBAAgB;gBAC5B,YAAY,EAAE,gBAAgB;gBAC9B,SAAS,EAAE,qBAAqB;aACjC,CAAA;YACD,OAAO,CAAC,IAAI,CAAC,uBAAuB,MAAM,CAAC,SAAS,GAAG,CAAC,CAAA;QAC1D,CAAC;IACH,CAAC;IAED,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,YAAY,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,CAAA;QACpD,EAAE,CAAC,GAAG,CAAC,sBAAsB,IAAI,wCAAwC,CAAC,CAAA;QAC1E,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAA;QAC9C,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;YAC7B,IAAI,MAAM,EAAE,CAAC,OAAO,CAAC,6CAA6C,QAAQ,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;gBACrF,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAA;gBACpC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;oBACnD,cAAc,CAAC,GAAG,EAAE,YAAY,IAAI,EAAE,EAAE,KAAK,CAAC,CAAA;gBAChD,CAAC;gBACD,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;gBACzB,OAAO,CAAC,IAAI,CAAC,oBAAoB,QAAQ,EAAE,CAAC,CAAA;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACV,MAAM,GAAG,MAAM,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAA;IAClC,WAAW,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IACvB,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAEV,6EAA6E;IAC7E,4EAA4E;IAC5E,2EAA2E;IAC3E,4EAA4E;IAC5E,4EAA4E;IAC5E,4DAA4D;IAC5D,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,MAAM,YAAY,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAA;IAC1E,CAAC;IAED,EAAE,CAAC,GAAG,CACJ,MAAM,CAAC,KAAK;QACV,CAAC,CAAC,oBAAoB;QACtB,CAAC,CAAC,2DAA2D,CAChE,CAAA;IACD,EAAE,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAA;IAC1D,EAAE,CAAC,GAAG,CAAC,2EAA2E,CAAC,CAAA;IACnF,EAAE,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAA;IACtD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;AAC5B,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,YAAY,CAAC,IAO3B;IACC,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM;SACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;SACrD,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACxC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IAE9B,EAAE,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAA;IACpF,KAAK,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QACtC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC/E,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,+BAA+B,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IACvE,IAAI,IAAI,KAAK,EAAE;QAAE,OAAM;IACvB,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;IACjD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,EAAE,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,CAAA;QAC9B,OAAM;IACR,CAAC;IAED,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QAC5C,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAC3E,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IACzD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;IAC3D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,EAAE,CAAC,GAAG,CAAC,gBAAgB,KAAK,IAAI,CAAC,CAAA;QACjC,OAAM;IACR,CAAC;IAED,MAAM,IAAI,GAAgB;QACxB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,CAAA;IACD,IAAI,MAAM,CAAC,EAAE,KAAK,OAAO,EAAE,CAAC;QAC1B,IAAI,MAAM,CAAC,GAAG;YAAE,EAAE,CAAC,GAAG,CAAC,yBAAyB,MAAM,CAAC,GAAG,wBAAwB,CAAC,CAAA;QACnF,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,uCAAuC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QAC9E,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;YACb,EAAE,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAA;YACjC,OAAM;QACR,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,CAAC,CAAA;IAChB,CAAC;SAAM,IAAI,MAAM,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;QAClC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,kCAAkC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;YAC7E,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;YACtB,OAAM;QACR,CAAC;IACH,CAAC;SAAM,IAAI,MAAM,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;QAChC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,qCAAqC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;YACrE,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;YACtB,OAAM;QACR,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;IACtD,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAChD,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACtE,MAAM,CAAC,GAAG,MAAM,CAAC,MAA8E,CAAA;IAC/F,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;QACpB,EAAE,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC,aAAa,CAAC,IAAI,MAAM,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,CAAA;IACzF,CAAC;IACD,IAAI,CAAC,CAAC,QAAQ;QAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;IACzC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;AACrF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"snap.d.ts","sourceRoot":"","sources":["../../src/lib/snap.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAA;CACjB;AAKD,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAkBpD;AA+BD,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,CAAA;AAI5D,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,IAAI,CAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,WAAgB,GACrB,UAAU,CAyCZ"}
1
+ {"version":3,"file":"snap.d.ts","sourceRoot":"","sources":["../../src/lib/snap.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAA;CACjB;AAKD,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAkBpD;AA+BD,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,CAAA;AAI5D,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,IAAI,CAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,WAAgB,GACrB,UAAU,CA6CZ"}
package/dist/lib/snap.js CHANGED
@@ -2,6 +2,7 @@ import { execFileSync } from 'node:child_process';
2
2
  import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
3
3
  import { join } from 'node:path';
4
4
  import { CompostError } from '../errors.js';
5
+ import { assertSessionContained } from './sessionId.js';
5
6
  const FRAME_WIDTH = 640;
6
7
  const FRAME_HEIGHT = 360;
7
8
  /** Parse mm:ss, hh:mm:ss, or raw ms (integer) into milliseconds. */
@@ -53,6 +54,10 @@ function hasVideoStream(path, runner) {
53
54
  const defaultRunner = (cmd, args) => execFileSync(cmd, args, { encoding: 'utf8' });
54
55
  export function snap(seedPath, sessionId, at, opts = {}) {
55
56
  const runner = opts.runner ?? defaultRunner;
57
+ // sessionId is joined into the seed path (and written to) below — reject any
58
+ // path-separator/`..` value, and assert containment under the seed, before any
59
+ // fs op (#211 followup).
60
+ assertSessionContained(seedPath, sessionId);
56
61
  const atMs = parseTimestamp(at);
57
62
  const sessionDir = join(seedPath, 'sessions', sessionId);
58
63
  const source = findSource(sessionDir);
@@ -1 +1 @@
1
- {"version":3,"file":"snap.js","sourceRoot":"","sources":["../../src/lib/snap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"snap.js","sourceRoot":"","sources":["../../src/lib/snap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { Transcript, TranscriptSpeaker } from './transcript.js';
2
+ /**
3
+ * Speaker labeling (#177). Diarization emits cluster ids (S0, S1, … — pyannote's
4
+ * SPEAKER_NN canonicalized to the schema's S{n} form) with name == id; this maps
5
+ * them to real names. The map is applied to transcript.json
6
+ * AND persisted to a `speakers.json` sidecar next to it, so re-transcription
7
+ * re-applies the names (diarization cluster ids are stable per session).
8
+ */
9
+ export type SpeakerType = TranscriptSpeaker['type'];
10
+ export interface SpeakerLabel {
11
+ name?: string;
12
+ type?: SpeakerType;
13
+ }
14
+ export type SpeakerMap = Record<string, SpeakerLabel>;
15
+ export declare function sidecarPath(seedPath: string, session: string): string;
16
+ /** Apply a label map to a transcript's speakers[] in place. Returns the cluster
17
+ * ids that matched a real speaker and the map keys that matched none. */
18
+ export declare function applyLabels(transcript: Transcript, map: SpeakerMap): {
19
+ applied: string[];
20
+ unmatched: string[];
21
+ };
22
+ export declare function readSidecar(path: string): SpeakerMap;
23
+ export interface LabelResult {
24
+ session: string;
25
+ applied: string[];
26
+ unmatched: string[];
27
+ transcript_path: string;
28
+ sidecar_path: string;
29
+ }
30
+ /**
31
+ * Label a session's speakers: apply the map to transcript.json, then merge it
32
+ * into the persisted speakers.json sidecar so it survives re-transcription.
33
+ */
34
+ export declare function labelSession(seedPath: string, session: string, map: SpeakerMap): LabelResult;
35
+ /**
36
+ * Re-apply a session's persisted speaker labels to a freshly-written
37
+ * transcript.json (called from the transcribe finalize step). No-op when there
38
+ * is no sidecar. Returns the cluster ids relabeled.
39
+ */
40
+ export declare function applySidecar(transcriptJsonPath: string): string[];
41
+ //# sourceMappingURL=speakers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"speakers.d.ts","sourceRoot":"","sources":["../../src/lib/speakers.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAEpE;;;;;;GAMG;AAEH,MAAM,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAA;AAEnD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,WAAW,CAAA;CACnB;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;AAErD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAErE;AAMD;yEACyE;AACzE,wBAAgB,WAAW,CACzB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,UAAU,GACd;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAY5C;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAQpD;AAMD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,WAAW,CAiB5F;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,EAAE,CAUjE"}
@@ -0,0 +1,78 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { CompostError } from '../errors.js';
4
+ export function sidecarPath(seedPath, session) {
5
+ return join(seedPath, 'sessions', session, 'speakers.json');
6
+ }
7
+ function transcriptPath(seedPath, session) {
8
+ return join(seedPath, 'sessions', session, 'transcript.json');
9
+ }
10
+ /** Apply a label map to a transcript's speakers[] in place. Returns the cluster
11
+ * ids that matched a real speaker and the map keys that matched none. */
12
+ export function applyLabels(transcript, map) {
13
+ const ids = new Set(transcript.speakers.map((s) => s.id));
14
+ const applied = [];
15
+ for (const sp of transcript.speakers) {
16
+ const label = map[sp.id];
17
+ if (label === undefined)
18
+ continue;
19
+ if (label.name !== undefined)
20
+ sp.name = label.name;
21
+ if (label.type !== undefined)
22
+ sp.type = label.type;
23
+ applied.push(sp.id);
24
+ }
25
+ const unmatched = Object.keys(map).filter((id) => !ids.has(id));
26
+ return { applied, unmatched };
27
+ }
28
+ export function readSidecar(path) {
29
+ if (!existsSync(path))
30
+ return {};
31
+ try {
32
+ const parsed = JSON.parse(readFileSync(path, 'utf8'));
33
+ return parsed !== null && typeof parsed === 'object' ? parsed : {};
34
+ }
35
+ catch {
36
+ return {};
37
+ }
38
+ }
39
+ function writeJson(path, data) {
40
+ writeFileSync(path, `${JSON.stringify(data, null, 2)}\n`, 'utf8');
41
+ }
42
+ /**
43
+ * Label a session's speakers: apply the map to transcript.json, then merge it
44
+ * into the persisted speakers.json sidecar so it survives re-transcription.
45
+ */
46
+ export function labelSession(seedPath, session, map) {
47
+ const tPath = transcriptPath(seedPath, session);
48
+ if (!existsSync(tPath)) {
49
+ throw new CompostError('FILE_NOT_FOUND', `No transcript.json for session ${session} — transcribe it before labeling.`);
50
+ }
51
+ const transcript = JSON.parse(readFileSync(tPath, 'utf8'));
52
+ const { applied, unmatched } = applyLabels(transcript, map);
53
+ writeJson(tPath, transcript);
54
+ const sPath = sidecarPath(seedPath, session);
55
+ const merged = { ...readSidecar(sPath), ...map };
56
+ writeJson(sPath, merged);
57
+ return { session, applied, unmatched, transcript_path: tPath, sidecar_path: sPath };
58
+ }
59
+ /**
60
+ * Re-apply a session's persisted speaker labels to a freshly-written
61
+ * transcript.json (called from the transcribe finalize step). No-op when there
62
+ * is no sidecar. Returns the cluster ids relabeled.
63
+ */
64
+ export function applySidecar(transcriptJsonPath) {
65
+ const dir = transcriptJsonPath.slice(0, transcriptJsonPath.lastIndexOf('/'));
66
+ const sPath = join(dir, 'speakers.json');
67
+ if (!existsSync(sPath) || !existsSync(transcriptJsonPath))
68
+ return [];
69
+ const map = readSidecar(sPath);
70
+ if (Object.keys(map).length === 0)
71
+ return [];
72
+ const transcript = JSON.parse(readFileSync(transcriptJsonPath, 'utf8'));
73
+ const { applied } = applyLabels(transcript, map);
74
+ if (applied.length > 0)
75
+ writeJson(transcriptJsonPath, transcript);
76
+ return applied;
77
+ }
78
+ //# sourceMappingURL=speakers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"speakers.js","sourceRoot":"","sources":["../../src/lib/speakers.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lib/status.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,aAAa,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,MAAM,EAAE,UAAU,CAAA;IAClB;4DACwD;IACxD,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,KAAK,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,UAAU,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CACjB;AAED,wBAAgB,YAAY,CAAC,IAAI,GAAE,aAAkB,GAAG,cAAc,CAgCrE"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lib/status.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,aAAa,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,MAAM,EAAE,UAAU,CAAA;IAClB;4DACwD;IACxD,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,KAAK,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,UAAU,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CACjB;AAED,wBAAgB,YAAY,CAAC,IAAI,GAAE,aAAkB,GAAG,cAAc,CAgCrE"}
@@ -2,6 +2,7 @@ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
2
2
  import { join, resolve } from 'node:path';
3
3
  import { CompostError } from '../errors.js';
4
4
  import { isCanonicalSession } from './canonicalSessions.js';
5
+ import { JobQueue, stateDbPath } from './queue.js';
5
6
  export function gatherStatus(opts = {}) {
6
7
  const cwd = opts.cwd ?? process.cwd();
7
8
  const now = (opts.now ?? (() => new Date()))();
@@ -30,6 +31,13 @@ export function gatherStatus(opts = {}) {
30
31
  function readSeed(name, path) {
31
32
  const frontmatter = readFrontmatter(join(path, 'seed.md'));
32
33
  const warnings = [];
34
+ // A session without transcript.json counts as "queued" below, but if its job
35
+ // burned all attempts nothing will ever process it — surface that here so
36
+ // "queued" isn't read as "in progress" (#239).
37
+ const deadJobs = countDeadJobs(path);
38
+ if (deadJobs > 0) {
39
+ warnings.push(`${deadJobs} permanently failed job(s) in the queue — run \`compost jobs requeue\``);
40
+ }
33
41
  return {
34
42
  name,
35
43
  path,
@@ -48,6 +56,19 @@ function readSeed(name, path) {
48
56
  warnings,
49
57
  };
50
58
  }
59
+ function countDeadJobs(seedPath) {
60
+ // Guard on existence: status is read-only and must not scaffold .compost/
61
+ // state into a seed that never ran the watcher.
62
+ if (!existsSync(stateDbPath(seedPath)))
63
+ return 0;
64
+ const queue = new JobQueue(stateDbPath(seedPath));
65
+ try {
66
+ return queue.counts().failed;
67
+ }
68
+ finally {
69
+ queue.close();
70
+ }
71
+ }
51
72
  function countSessions(sessionsDir, warnings) {
52
73
  const counts = { total: 0, transcribed: 0, queued: 0, inbox: 0 };
53
74
  if (!existsSync(sessionsDir))