@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.
- package/LICENSE +21 -0
- package/README.md +5 -0
- package/bin/compost.js +7 -0
- package/dist/commands/_stub.d.ts +9 -0
- package/dist/commands/_stub.d.ts.map +1 -0
- package/dist/commands/_stub.js +27 -0
- package/dist/commands/_stub.js.map +1 -0
- package/dist/commands/blame.d.ts +3 -0
- package/dist/commands/blame.d.ts.map +1 -0
- package/dist/commands/blame.js +31 -0
- package/dist/commands/blame.js.map +1 -0
- package/dist/commands/chat.d.ts +8 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +99 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/code.d.ts +3 -0
- package/dist/commands/code.d.ts.map +1 -0
- package/dist/commands/code.js +70 -0
- package/dist/commands/code.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +76 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/create.d.ts +20 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +148 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/endorse.d.ts +3 -0
- package/dist/commands/endorse.d.ts.map +1 -0
- package/dist/commands/endorse.js +31 -0
- package/dist/commands/endorse.js.map +1 -0
- package/dist/commands/evals.d.ts +3 -0
- package/dist/commands/evals.d.ts.map +1 -0
- package/dist/commands/evals.js +54 -0
- package/dist/commands/evals.js.map +1 -0
- package/dist/commands/export.d.ts +3 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +54 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/ingest.d.ts +3 -0
- package/dist/commands/ingest.d.ts.map +1 -0
- package/dist/commands/ingest.js +26 -0
- package/dist/commands/ingest.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +51 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/migrate.d.ts +3 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +28 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/models.d.ts +3 -0
- package/dist/commands/models.d.ts.map +1 -0
- package/dist/commands/models.js +32 -0
- package/dist/commands/models.js.map +1 -0
- package/dist/commands/query.d.ts +3 -0
- package/dist/commands/query.d.ts.map +1 -0
- package/dist/commands/query.js +13 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/reindex.d.ts +3 -0
- package/dist/commands/reindex.d.ts.map +1 -0
- package/dist/commands/reindex.js +53 -0
- package/dist/commands/reindex.js.map +1 -0
- package/dist/commands/rescan.d.ts +3 -0
- package/dist/commands/rescan.d.ts.map +1 -0
- package/dist/commands/rescan.js +60 -0
- package/dist/commands/rescan.js.map +1 -0
- package/dist/commands/saturate.d.ts +3 -0
- package/dist/commands/saturate.d.ts.map +1 -0
- package/dist/commands/saturate.js +35 -0
- package/dist/commands/saturate.js.map +1 -0
- package/dist/commands/search.d.ts +3 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +52 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/serve.d.ts +3 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +9 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/session.d.ts +3 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +25 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/setup.d.ts +3 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +38 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/snap.d.ts +3 -0
- package/dist/commands/snap.d.ts.map +1 -0
- package/dist/commands/snap.js +27 -0
- package/dist/commands/snap.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +26 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/synthesize.d.ts +3 -0
- package/dist/commands/synthesize.d.ts.map +1 -0
- package/dist/commands/synthesize.js +13 -0
- package/dist/commands/synthesize.js.map +1 -0
- package/dist/commands/tag.d.ts +3 -0
- package/dist/commands/tag.d.ts.map +1 -0
- package/dist/commands/tag.js +46 -0
- package/dist/commands/tag.js.map +1 -0
- package/dist/commands/transcribe.d.ts +3 -0
- package/dist/commands/transcribe.d.ts.map +1 -0
- package/dist/commands/transcribe.js +110 -0
- package/dist/commands/transcribe.js.map +1 -0
- package/dist/commands/validate.d.ts +3 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +81 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/watch.d.ts +3 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +50 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/errors.d.ts +9 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +12 -0
- package/dist/errors.js.map +1 -0
- package/dist/exporters/csv.d.ts +8 -0
- package/dist/exporters/csv.d.ts.map +1 -0
- package/dist/exporters/csv.js +44 -0
- package/dist/exporters/csv.js.map +1 -0
- package/dist/exporters/eaf.d.ts +3 -0
- package/dist/exporters/eaf.d.ts.map +1 -0
- package/dist/exporters/eaf.js +91 -0
- package/dist/exporters/eaf.js.map +1 -0
- package/dist/exporters/html.d.ts +8 -0
- package/dist/exporters/html.d.ts.map +1 -0
- package/dist/exporters/html.js +47 -0
- package/dist/exporters/html.js.map +1 -0
- package/dist/exporters/md.d.ts +3 -0
- package/dist/exporters/md.d.ts.map +1 -0
- package/dist/exporters/md.js +43 -0
- package/dist/exporters/md.js.map +1 -0
- package/dist/exporters/pdf.d.ts +9 -0
- package/dist/exporters/pdf.d.ts.map +1 -0
- package/dist/exporters/pdf.js +40 -0
- package/dist/exporters/pdf.js.map +1 -0
- package/dist/exporters/report.d.ts +43 -0
- package/dist/exporters/report.d.ts.map +1 -0
- package/dist/exporters/report.js +49 -0
- package/dist/exporters/report.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/legacy_client.d.ts +38 -0
- package/dist/legacy_client.d.ts.map +1 -0
- package/dist/legacy_client.js +44 -0
- package/dist/legacy_client.js.map +1 -0
- package/dist/lib/answerSchema.d.ts +2 -0
- package/dist/lib/answerSchema.d.ts.map +1 -0
- package/dist/lib/answerSchema.js +27 -0
- package/dist/lib/answerSchema.js.map +1 -0
- package/dist/lib/artifacts.d.ts +64 -0
- package/dist/lib/artifacts.d.ts.map +1 -0
- package/dist/lib/artifacts.js +254 -0
- package/dist/lib/artifacts.js.map +1 -0
- package/dist/lib/blame.d.ts +30 -0
- package/dist/lib/blame.d.ts.map +1 -0
- package/dist/lib/blame.js +164 -0
- package/dist/lib/blame.js.map +1 -0
- package/dist/lib/canonicalSessions.d.ts +24 -0
- package/dist/lib/canonicalSessions.d.ts.map +1 -0
- package/dist/lib/canonicalSessions.js +48 -0
- package/dist/lib/canonicalSessions.js.map +1 -0
- package/dist/lib/chat.d.ts +24 -0
- package/dist/lib/chat.d.ts.map +1 -0
- package/dist/lib/chat.js +50 -0
- package/dist/lib/chat.js.map +1 -0
- package/dist/lib/config.d.ts +45 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +143 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/dispatch.d.ts +10 -0
- package/dist/lib/dispatch.d.ts.map +1 -0
- package/dist/lib/dispatch.js +31 -0
- package/dist/lib/dispatch.js.map +1 -0
- package/dist/lib/doctor.d.ts +19 -0
- package/dist/lib/doctor.d.ts.map +1 -0
- package/dist/lib/doctor.js +43 -0
- package/dist/lib/doctor.js.map +1 -0
- package/dist/lib/events.d.ts +42 -0
- package/dist/lib/events.d.ts.map +1 -0
- package/dist/lib/events.js +57 -0
- package/dist/lib/events.js.map +1 -0
- package/dist/lib/export.d.ts +14 -0
- package/dist/lib/export.d.ts.map +1 -0
- package/dist/lib/export.js +36 -0
- package/dist/lib/export.js.map +1 -0
- package/dist/lib/ingest.d.ts +21 -0
- package/dist/lib/ingest.d.ts.map +1 -0
- package/dist/lib/ingest.js +68 -0
- package/dist/lib/ingest.js.map +1 -0
- package/dist/lib/journal.d.ts +23 -0
- package/dist/lib/journal.d.ts.map +1 -0
- package/dist/lib/journal.js +95 -0
- package/dist/lib/journal.js.map +1 -0
- package/dist/lib/migrate.d.ts +29 -0
- package/dist/lib/migrate.d.ts.map +1 -0
- package/dist/lib/migrate.js +117 -0
- package/dist/lib/migrate.js.map +1 -0
- package/dist/lib/nativeRuntime.d.ts +46 -0
- package/dist/lib/nativeRuntime.d.ts.map +1 -0
- package/dist/lib/nativeRuntime.js +61 -0
- package/dist/lib/nativeRuntime.js.map +1 -0
- package/dist/lib/provisionNative.d.ts +46 -0
- package/dist/lib/provisionNative.d.ts.map +1 -0
- package/dist/lib/provisionNative.js +105 -0
- package/dist/lib/provisionNative.js.map +1 -0
- package/dist/lib/queue.d.ts +36 -0
- package/dist/lib/queue.d.ts.map +1 -0
- package/dist/lib/queue.js +102 -0
- package/dist/lib/queue.js.map +1 -0
- package/dist/lib/retrieve.d.ts +51 -0
- package/dist/lib/retrieve.d.ts.map +1 -0
- package/dist/lib/retrieve.js +92 -0
- package/dist/lib/retrieve.js.map +1 -0
- package/dist/lib/saturate.d.ts +21 -0
- package/dist/lib/saturate.d.ts.map +1 -0
- package/dist/lib/saturate.js +132 -0
- package/dist/lib/saturate.js.map +1 -0
- package/dist/lib/schemas.generated.d.ts +15 -0
- package/dist/lib/schemas.generated.d.ts.map +1 -0
- package/dist/lib/schemas.generated.js +975 -0
- package/dist/lib/schemas.generated.js.map +1 -0
- package/dist/lib/seed.d.ts +16 -0
- package/dist/lib/seed.d.ts.map +1 -0
- package/dist/lib/seed.js +64 -0
- package/dist/lib/seed.js.map +1 -0
- package/dist/lib/seedResolve.d.ts +6 -0
- package/dist/lib/seedResolve.d.ts.map +1 -0
- package/dist/lib/seedResolve.js +27 -0
- package/dist/lib/seedResolve.js.map +1 -0
- package/dist/lib/session.d.ts +19 -0
- package/dist/lib/session.d.ts.map +1 -0
- package/dist/lib/session.js +61 -0
- package/dist/lib/session.js.map +1 -0
- package/dist/lib/setup.d.ts +44 -0
- package/dist/lib/setup.d.ts.map +1 -0
- package/dist/lib/setup.js +249 -0
- package/dist/lib/setup.js.map +1 -0
- package/dist/lib/snap.d.ts +15 -0
- package/dist/lib/snap.d.ts.map +1 -0
- package/dist/lib/snap.js +115 -0
- package/dist/lib/snap.js.map +1 -0
- package/dist/lib/status.d.ts +39 -0
- package/dist/lib/status.d.ts.map +1 -0
- package/dist/lib/status.js +174 -0
- package/dist/lib/status.js.map +1 -0
- package/dist/lib/tagcode.d.ts +26 -0
- package/dist/lib/tagcode.d.ts.map +1 -0
- package/dist/lib/tagcode.js +231 -0
- package/dist/lib/tagcode.js.map +1 -0
- package/dist/lib/templates.d.ts +3 -0
- package/dist/lib/templates.d.ts.map +1 -0
- package/dist/lib/templates.js +21 -0
- package/dist/lib/templates.js.map +1 -0
- package/dist/lib/transcribeNative.d.ts +44 -0
- package/dist/lib/transcribeNative.d.ts.map +1 -0
- package/dist/lib/transcribeNative.js +53 -0
- package/dist/lib/transcribeNative.js.map +1 -0
- package/dist/lib/transcript.d.ts +68 -0
- package/dist/lib/transcript.d.ts.map +1 -0
- package/dist/lib/transcript.js +10 -0
- package/dist/lib/transcript.js.map +1 -0
- package/dist/lib/validate.d.ts +16 -0
- package/dist/lib/validate.d.ts.map +1 -0
- package/dist/lib/validate.js +155 -0
- package/dist/lib/validate.js.map +1 -0
- package/dist/llm/adapter.d.ts +33 -0
- package/dist/llm/adapter.d.ts.map +1 -0
- package/dist/llm/adapter.js +106 -0
- package/dist/llm/adapter.js.map +1 -0
- package/dist/llm/http.d.ts +9 -0
- package/dist/llm/http.d.ts.map +1 -0
- package/dist/llm/http.js +56 -0
- package/dist/llm/http.js.map +1 -0
- package/dist/llm/providers/anthropic.d.ts +14 -0
- package/dist/llm/providers/anthropic.d.ts.map +1 -0
- package/dist/llm/providers/anthropic.js +66 -0
- package/dist/llm/providers/anthropic.js.map +1 -0
- package/dist/llm/providers/lmstudio.d.ts +7 -0
- package/dist/llm/providers/lmstudio.d.ts.map +1 -0
- package/dist/llm/providers/lmstudio.js +8 -0
- package/dist/llm/providers/lmstudio.js.map +1 -0
- package/dist/llm/providers/ollama.d.ts +12 -0
- package/dist/llm/providers/ollama.d.ts.map +1 -0
- package/dist/llm/providers/ollama.js +87 -0
- package/dist/llm/providers/ollama.js.map +1 -0
- package/dist/llm/providers/openai.d.ts +7 -0
- package/dist/llm/providers/openai.d.ts.map +1 -0
- package/dist/llm/providers/openai.js +8 -0
- package/dist/llm/providers/openai.js.map +1 -0
- package/dist/llm/providers/openai_compatible.d.ts +18 -0
- package/dist/llm/providers/openai_compatible.d.ts.map +1 -0
- package/dist/llm/providers/openai_compatible.js +70 -0
- package/dist/llm/providers/openai_compatible.js.map +1 -0
- package/dist/llm/types.d.ts +60 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/llm/types.js +2 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/logging.d.ts +22 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +58 -0
- package/dist/logging.js.map +1 -0
- package/dist/loops/embed_worker.d.ts +44 -0
- package/dist/loops/embed_worker.d.ts.map +1 -0
- package/dist/loops/embed_worker.js +144 -0
- package/dist/loops/embed_worker.js.map +1 -0
- package/dist/loops/eval_grader.d.ts +19 -0
- package/dist/loops/eval_grader.d.ts.map +1 -0
- package/dist/loops/eval_grader.js +22 -0
- package/dist/loops/eval_grader.js.map +1 -0
- package/dist/loops/ingest_watcher.d.ts +17 -0
- package/dist/loops/ingest_watcher.d.ts.map +1 -0
- package/dist/loops/ingest_watcher.js +66 -0
- package/dist/loops/ingest_watcher.js.map +1 -0
- package/dist/loops/legacy_worker.d.ts +26 -0
- package/dist/loops/legacy_worker.d.ts.map +1 -0
- package/dist/loops/legacy_worker.js +102 -0
- package/dist/loops/legacy_worker.js.map +1 -0
- package/dist/loops/supervisor.d.ts +71 -0
- package/dist/loops/supervisor.d.ts.map +1 -0
- package/dist/loops/supervisor.js +122 -0
- package/dist/loops/supervisor.js.map +1 -0
- package/dist/loops/synthesis.d.ts +31 -0
- package/dist/loops/synthesis.d.ts.map +1 -0
- package/dist/loops/synthesis.js +71 -0
- package/dist/loops/synthesis.js.map +1 -0
- package/dist/loops/transcribe_worker.d.ts +22 -0
- package/dist/loops/transcribe_worker.d.ts.map +1 -0
- package/dist/loops/transcribe_worker.js +77 -0
- package/dist/loops/transcribe_worker.js.map +1 -0
- package/dist/output.d.ts +8 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +26 -0
- package/dist/output.js.map +1 -0
- package/dist/render/transcript_md.d.ts +5 -0
- package/dist/render/transcript_md.d.ts.map +1 -0
- package/dist/render/transcript_md.js +14 -0
- package/dist/render/transcript_md.js.map +1 -0
- package/dist/router.d.ts +3 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +68 -0
- package/dist/router.js.map +1 -0
- package/dist/transcriber_client.d.ts +42 -0
- package/dist/transcriber_client.d.ts.map +1 -0
- package/dist/transcriber_client.js +72 -0
- package/dist/transcriber_client.js.map +1 -0
- package/package.json +45 -0
- package/templates/AGENTS.md +25 -0
- package/templates/config.toml +56 -0
- package/templates/sample-seed/codebook/desire-for-manual-override.md +8 -0
- package/templates/sample-seed/codebook/distrust-of-automation.md +8 -0
- package/templates/sample-seed/highlights/H-001.md +9 -0
- package/templates/sample-seed/highlights/H-002.md +9 -0
- package/templates/sample-seed/seed.md +17 -0
- package/templates/sample-seed/sessions/S001/transcript.json +74 -0
- package/templates/sample-seed/synthesis/themes/control-earns-trust.md +13 -0
- 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 @@
|
|
|
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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"}
|