granola-toolkit 0.5.0 → 0.7.0
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/dist/cli.js +46 -9
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
3
2
|
import { existsSync } from "node:fs";
|
|
3
|
+
import { mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
6
|
import { createHash } from "node:crypto";
|
|
@@ -37,7 +37,6 @@ function compareStrings(left, right) {
|
|
|
37
37
|
}
|
|
38
38
|
function firstExistingPath(candidates) {
|
|
39
39
|
for (const candidate of candidates) if (existsSync(candidate)) return candidate;
|
|
40
|
-
return candidates[0];
|
|
41
40
|
}
|
|
42
41
|
function granolaSupabaseCandidates() {
|
|
43
42
|
const home = homedir();
|
|
@@ -383,10 +382,13 @@ function parseSimpleToml(contents) {
|
|
|
383
382
|
return values;
|
|
384
383
|
}
|
|
385
384
|
async function loadTomlConfig(configPath) {
|
|
386
|
-
if (configPath)
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
385
|
+
if (configPath) {
|
|
386
|
+
if (!existsSync(configPath)) throw new Error(`config file not found: ${configPath}`);
|
|
387
|
+
return {
|
|
388
|
+
path: configPath,
|
|
389
|
+
values: parseSimpleToml(await readUtf8(configPath))
|
|
390
|
+
};
|
|
391
|
+
}
|
|
390
392
|
const candidates = [join(process.cwd(), ".granola.toml"), join(homedir(), ".granola.toml")];
|
|
391
393
|
for (const candidate of candidates) if (existsSync(candidate)) return {
|
|
392
394
|
path: candidate,
|
|
@@ -818,6 +820,7 @@ const notesCommand = {
|
|
|
818
820
|
subcommandFlags: commandFlags
|
|
819
821
|
});
|
|
820
822
|
if (!config.supabase) throw new Error(`supabase.json not found. Pass --supabase or create .granola.toml. Expected locations include: ${granolaSupabaseCandidates().join(", ")}`);
|
|
823
|
+
if (!existsSync(config.supabase)) throw new Error(`supabase.json not found: ${config.supabase}`);
|
|
821
824
|
debug(config.debug, "using config", config.configFileUsed ?? "(none)");
|
|
822
825
|
debug(config.debug, "supabase", config.supabase);
|
|
823
826
|
debug(config.debug, "timeoutMs", config.notes.timeoutMs);
|
|
@@ -903,7 +906,40 @@ function parseCacheContents(contents) {
|
|
|
903
906
|
}
|
|
904
907
|
//#endregion
|
|
905
908
|
//#region src/transcripts.ts
|
|
906
|
-
function
|
|
909
|
+
function transcriptSegmentKey(segment) {
|
|
910
|
+
if (segment.id) return `id:${segment.id}`;
|
|
911
|
+
return [
|
|
912
|
+
segment.documentId,
|
|
913
|
+
segment.source,
|
|
914
|
+
segment.startTimestamp,
|
|
915
|
+
segment.endTimestamp
|
|
916
|
+
].join("|");
|
|
917
|
+
}
|
|
918
|
+
function compareSegmentTimestamps(left, right) {
|
|
919
|
+
if (left === right) return 0;
|
|
920
|
+
const leftTime = Date.parse(left);
|
|
921
|
+
const rightTime = Date.parse(right);
|
|
922
|
+
if (!Number.isNaN(leftTime) && !Number.isNaN(rightTime)) return leftTime - rightTime;
|
|
923
|
+
return compareStrings(left, right);
|
|
924
|
+
}
|
|
925
|
+
function compareTranscriptSegments(left, right) {
|
|
926
|
+
return compareSegmentTimestamps(left.startTimestamp, right.startTimestamp) || compareSegmentTimestamps(left.endTimestamp, right.endTimestamp) || compareStrings(left.source, right.source) || compareStrings(left.id, right.id) || compareStrings(left.text, right.text);
|
|
927
|
+
}
|
|
928
|
+
function preferredTranscriptSegment(current, candidate) {
|
|
929
|
+
if (!current) return candidate;
|
|
930
|
+
if (candidate.isFinal !== current.isFinal) return candidate.isFinal ? candidate : current;
|
|
931
|
+
return compareSegmentTimestamps(candidate.endTimestamp, current.endTimestamp) > 0 || candidate.text.length > current.text.length ? candidate : current;
|
|
932
|
+
}
|
|
933
|
+
function normaliseTranscriptSegments(segments) {
|
|
934
|
+
const selected = /* @__PURE__ */ new Map();
|
|
935
|
+
for (const segment of [...segments].sort(compareTranscriptSegments)) {
|
|
936
|
+
const key = transcriptSegmentKey(segment);
|
|
937
|
+
const current = selected.get(key);
|
|
938
|
+
selected.set(key, preferredTranscriptSegment(current, segment));
|
|
939
|
+
}
|
|
940
|
+
return [...selected.values()].sort(compareTranscriptSegments);
|
|
941
|
+
}
|
|
942
|
+
function buildTranscriptExport(document, segments, rawSegments = segments) {
|
|
907
943
|
const renderedSegments = segments.map((segment) => ({
|
|
908
944
|
endTimestamp: segment.endTimestamp,
|
|
909
945
|
id: segment.id,
|
|
@@ -918,7 +954,7 @@ function buildTranscriptExport(document, segments) {
|
|
|
918
954
|
id: document.id,
|
|
919
955
|
raw: {
|
|
920
956
|
document,
|
|
921
|
-
segments
|
|
957
|
+
segments: rawSegments
|
|
922
958
|
},
|
|
923
959
|
segments: renderedSegments,
|
|
924
960
|
title: document.title,
|
|
@@ -987,7 +1023,7 @@ async function writeTranscripts(cacheData, outputDir, format = "text") {
|
|
|
987
1023
|
title: documentId,
|
|
988
1024
|
updatedAt: ""
|
|
989
1025
|
};
|
|
990
|
-
const content = renderTranscriptExport(buildTranscriptExport(document, segments), format);
|
|
1026
|
+
const content = renderTranscriptExport(buildTranscriptExport(document, normaliseTranscriptSegments(segments), segments), format);
|
|
991
1027
|
if (!content) return [];
|
|
992
1028
|
return [{
|
|
993
1029
|
content,
|
|
@@ -1034,6 +1070,7 @@ const transcriptsCommand = {
|
|
|
1034
1070
|
subcommandFlags: commandFlags
|
|
1035
1071
|
});
|
|
1036
1072
|
if (!config.transcripts.cacheFile) throw new Error(`Granola cache file not found. Pass --cache or create .granola.toml. Expected locations include: ${granolaCacheCandidates().join(", ")}`);
|
|
1073
|
+
if (!existsSync(config.transcripts.cacheFile)) throw new Error(`Granola cache file not found: ${config.transcripts.cacheFile}`);
|
|
1037
1074
|
debug(config.debug, "using config", config.configFileUsed ?? "(none)");
|
|
1038
1075
|
debug(config.debug, "cacheFile", config.transcripts.cacheFile);
|
|
1039
1076
|
debug(config.debug, "output", config.transcripts.output);
|