@wrenautomation/read 0.0.0-stage → 0.29.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.
Files changed (72) hide show
  1. package/LICENSE.md +61 -0
  2. package/README.md +36 -2
  3. package/dist/fetch/fetcher.d.ts +84 -0
  4. package/dist/fetch/fetcher.js +180 -0
  5. package/dist/fetch/fetcher.js.map +1 -0
  6. package/dist/fetch/index.d.ts +9 -0
  7. package/dist/fetch/index.js +10 -0
  8. package/dist/fetch/index.js.map +1 -0
  9. package/dist/fetch/ladder.d.ts +44 -0
  10. package/dist/fetch/ladder.js +18 -0
  11. package/dist/fetch/ladder.js.map +1 -0
  12. package/dist/fetch/robots.d.ts +14 -0
  13. package/dist/fetch/robots.js +92 -0
  14. package/dist/fetch/robots.js.map +1 -0
  15. package/dist/index.d.ts +11 -0
  16. package/dist/index.js +12 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/study/claims.d.ts +19 -0
  19. package/dist/study/claims.js +13 -0
  20. package/dist/study/claims.js.map +1 -0
  21. package/dist/study/drafts.d.ts +43 -0
  22. package/dist/study/drafts.js +93 -0
  23. package/dist/study/drafts.js.map +1 -0
  24. package/dist/study/evidence.d.ts +17 -0
  25. package/dist/study/evidence.js +72 -0
  26. package/dist/study/evidence.js.map +1 -0
  27. package/dist/study/grounding.d.ts +29 -0
  28. package/dist/study/grounding.js +58 -0
  29. package/dist/study/grounding.js.map +1 -0
  30. package/dist/study/index.d.ts +11 -0
  31. package/dist/study/index.js +12 -0
  32. package/dist/study/index.js.map +1 -0
  33. package/dist/study/report.d.ts +55 -0
  34. package/dist/study/report.js +56 -0
  35. package/dist/study/report.js.map +1 -0
  36. package/dist/text/entities.d.ts +2 -0
  37. package/dist/text/entities.js +4 -0
  38. package/dist/text/entities.js.map +1 -0
  39. package/dist/text/htmltext.d.ts +30 -0
  40. package/dist/text/htmltext.js +208 -0
  41. package/dist/text/htmltext.js.map +1 -0
  42. package/dist/text/index.d.ts +7 -0
  43. package/dist/text/index.js +8 -0
  44. package/dist/text/index.js.map +1 -0
  45. package/dist/text/text.d.ts +8 -0
  46. package/dist/text/text.js +38 -0
  47. package/dist/text/text.js.map +1 -0
  48. package/dist/video/gemini.d.ts +46 -0
  49. package/dist/video/gemini.js +93 -0
  50. package/dist/video/gemini.js.map +1 -0
  51. package/dist/video/index.d.ts +39 -0
  52. package/dist/video/index.js +16 -0
  53. package/dist/video/index.js.map +1 -0
  54. package/dist/video/list.d.ts +35 -0
  55. package/dist/video/list.js +32 -0
  56. package/dist/video/list.js.map +1 -0
  57. package/dist/video/read.d.ts +53 -0
  58. package/dist/video/read.js +92 -0
  59. package/dist/video/read.js.map +1 -0
  60. package/dist/video/shots.d.ts +35 -0
  61. package/dist/video/shots.js +139 -0
  62. package/dist/video/shots.js.map +1 -0
  63. package/dist/video/tools.d.ts +16 -0
  64. package/dist/video/tools.js +29 -0
  65. package/dist/video/tools.js.map +1 -0
  66. package/dist/video/url.d.ts +73 -0
  67. package/dist/video/url.js +255 -0
  68. package/dist/video/url.js.map +1 -0
  69. package/dist/video/watch.d.ts +94 -0
  70. package/dist/video/watch.js +321 -0
  71. package/dist/video/watch.js.map +1 -0
  72. package/package.json +55 -3
@@ -0,0 +1,321 @@
1
+ /**
2
+ * Watching a video (designs/2026-10-21-video-watch.md). ffmpeg gives the facts: length,
3
+ * scene cuts, one 360p frame every 2 s, the speech as a small mono mp3. Models read them: an ear
4
+ * hears the speech (Cohere's Transcribe), an eye reads the frames as images (command-a-vision),
5
+ * and a model that takes video (Gemini) may read the whole of it too. One core; every caller
6
+ * passes its own models and tools. Nothing here touches a database.
7
+ *
8
+ * Cohere's vision is weak, so the result keeps what it did not read: a frame with no line is
9
+ * `null`, never filled from its neighbours, and every line carries its ffmpeg frame time.
10
+ */
11
+ import { mkdir, mkdtemp, readdir, readFile, rm } from "node:fs/promises";
12
+ import { tmpdir } from "node:os";
13
+ import { join, resolve } from "node:path";
14
+ import { cohere } from "@wrenautomation/models";
15
+ import { cohereEar } from "@wrenautomation/models/hear";
16
+ import { INLINE_MAX, readMedia, SHOWN, shrink } from "./gemini.js";
17
+ import { clock, runFor, TOOL_MS } from "./tools.js";
18
+ export const COHERE_VISION_MODEL = "command-a-vision-07-2025";
19
+ /** The text model for asks that need no picture (`video look --with cohere`). */
20
+ export const COHERE_TEXT_MODEL = "command-a-03-2025";
21
+ /** Trial keys allow about 20 calls a minute: wait out a busy ring, 2 s doubling to 30 s. */
22
+ const COHERE_ROTATE = { passes: 4, waitMs: 2000, maxWaitMs: 30_000 };
23
+ /** Frames per vision call. */
24
+ const BATCH = 8;
25
+ /** Vision calls at one time; trial keys allow about 20 calls a minute. */
26
+ const BATCHES_AT_ONCE = 3;
27
+ /** ffmpeg's scene score above which a frame starts a new shot. */
28
+ const SCENE = 0.25;
29
+ const FRAME_EVERY_S = 2;
30
+ /** A longer video gets its frames further apart, not more of them. */
31
+ const MAX_FRAMES = 300;
32
+ /** PySceneDetect's detectors: `hash` is the one films trust, `adaptive` the second signal. */
33
+ export const SCENE_DETECTORS = ["hash", "adaptive"];
34
+ /** Cohere's vision model on a key ring, waiting out a busy ring. */
35
+ export const cohereEye = (keys, o = {}) => cohere({ key: keys, model: COHERE_VISION_MODEL, rotate: COHERE_ROTATE, ...o });
36
+ /** Cohere's Transcribe on a key ring, waiting out a busy ring. */
37
+ export const cohereSpeech = (keys, o = {}) => cohereEar({ key: keys, rotate: COHERE_ROTATE, ...o });
38
+ /** `0:03.2`, a mark with a tenth of a second. */
39
+ export function stamp(s) {
40
+ const t = Math.round(s * 10);
41
+ return `${clock(Math.floor(t / 10))}.${t % 10}`;
42
+ }
43
+ // -- the screen ---------------------------------------------------------------------------
44
+ const SCREEN_ASK = (times) => `These are ${times.length} frames from one video, in order. Their times: ${times.join(", ")}. Read the text shown in each frame: captions, titles, slide and UI text, labels, numbers. Reply with exactly one line per frame, starting with its time in square brackets, like "[${times[0]}] text". Write "[${times[0]}] none" for a frame with no text. No other text.`;
45
+ /** Added to the ask once, when the model would not describe a frame. */
46
+ const TEXT_ONLY = "Read only on-screen text, UI and graphics. Ignore people.";
47
+ /** The model declining ("I can't assist with describing images of people"), as opposed to reading. */
48
+ const REFUSAL = /\bi(?:'|’)?m (?:sorry|unable|not able)|\bi am (?:sorry|unable|not able)|\bunable to (?:assist|help|describe|identify|process|provide|analy[sz]e)|\b(?:can(?:'|’)?t|cannot|can not|won(?:'|’)?t|not able to)\s+(?:\w+\s+){0,3}(?:assist|help|describe|identify|process|provide|analy[sz]e|comply)/i;
49
+ const LINE = /^[\s*•-]*\[?(\d+(?::\d{2}){1,2})\]?\s*[:–—-]?\s*(.*)$/;
50
+ const NONE = /^(?:none|no text|n\/a|-)\.?$/i;
51
+ /**
52
+ * The lines of an answer by frame time. A time that is not in the batch is dropped; the first
53
+ * line for a time wins; a refusing line is dropped. `refused`: the model declined, in a line or
54
+ * as the whole answer.
55
+ */
56
+ function parseScreen(answer, times) {
57
+ const lines = new Map();
58
+ let refused = false;
59
+ for (const raw of answer.split("\n")) {
60
+ const m = LINE.exec(raw);
61
+ if (!m || !times.has(m[1]) || lines.has(m[1]))
62
+ continue;
63
+ const text = (m[2] ?? "").trim();
64
+ if (REFUSAL.test(text.slice(0, 80)))
65
+ refused = true;
66
+ else
67
+ lines.set(m[1], NONE.test(text) ? "" : text);
68
+ }
69
+ if (!lines.size && REFUSAL.test(answer))
70
+ refused = true;
71
+ return { lines, refused };
72
+ }
73
+ async function readBatch(batch, eye) {
74
+ const times = batch.map((f) => clock(f.at));
75
+ const ask = (extra) => eye
76
+ .complete({
77
+ prompt: [
78
+ { type: "text", text: `${SCREEN_ASK(times)}${extra}` },
79
+ ...batch.map((f) => ({ type: "image", data: f.jpeg, mediaType: "image/jpeg" })),
80
+ ],
81
+ })
82
+ .then((r) => r.text, (err) => {
83
+ const why = err instanceof Error ? err.message : String(err);
84
+ throw new Error(`${eye.id} ${times[0]}: ${why}`, { cause: err });
85
+ });
86
+ const first = parseScreen(await ask(""), new Set(times));
87
+ if (first.refused) {
88
+ // Once more, told to leave people out. A frame the first answer read keeps its line.
89
+ const again = parseScreen(await ask(` ${TEXT_ONLY}`), new Set(times));
90
+ for (const [t, text] of again.lines)
91
+ if (!first.lines.has(t))
92
+ first.lines.set(t, text);
93
+ }
94
+ // A time with no line stays null: not read. Never filled from the frames around it.
95
+ return batch.map((f, i) => ({ at: f.at, text: first.lines.get(times[i]) ?? null }));
96
+ }
97
+ /**
98
+ * On-screen text for each frame, `BATCH` frames a call, `BATCHES_AT_ONCE` calls at a time. A
99
+ * batch that cannot be asked at all leaves its frames unread (and a warning); all of them
100
+ * failing throws.
101
+ */
102
+ export async function readScreen(shots, eye) {
103
+ const batches = [];
104
+ for (let i = 0; i < shots.length; i += BATCH)
105
+ batches.push(shots.slice(i, i + BATCH));
106
+ const out = [];
107
+ const errors = [];
108
+ for (let i = 0; i < batches.length; i += BATCHES_AT_ONCE) {
109
+ const group = batches.slice(i, i + BATCHES_AT_ONCE);
110
+ const done = await Promise.allSettled(group.map((b) => readBatch(b, eye)));
111
+ for (const [j, r] of done.entries()) {
112
+ if (r.status === "fulfilled") {
113
+ out.push(...r.value);
114
+ continue;
115
+ }
116
+ const err = r.reason instanceof Error ? r.reason : new Error(String(r.reason));
117
+ errors.push(err);
118
+ console.warn(`${err.message}; frames from ${clock(group[j]?.[0]?.at ?? 0)} not read`);
119
+ out.push(...(group[j] ?? []).map((f) => ({ at: f.at, text: null })));
120
+ }
121
+ }
122
+ if (batches.length && errors.length === batches.length)
123
+ throw errors[0];
124
+ return out;
125
+ }
126
+ async function probe(file, ffmpeg) {
127
+ const { stdout } = await runFor(ffmpeg.replace(/ffmpeg$/, "ffprobe"), [
128
+ ...["-v", "error", "-of", "json", file],
129
+ ...["-show_entries", "format=duration:stream=codec_type,width,height"],
130
+ ], TOOL_MS);
131
+ const j = JSON.parse(stdout);
132
+ const picture = (j.streams ?? []).find((s) => s.codec_type === "video");
133
+ return {
134
+ durationS: Number(j.format?.duration) || 0,
135
+ audio: (j.streams ?? []).some((s) => s.codec_type === "audio"),
136
+ picture: !!picture,
137
+ ...(picture?.width ? { width: picture.width } : {}),
138
+ ...(picture?.height ? { height: picture.height } : {}),
139
+ };
140
+ }
141
+ /** Frame `i` (from 0) is at `i * every`. Short side 360, so a wide screen recording stays readable. */
142
+ async function frames(file, dir, every, ffmpeg) {
143
+ const out = join(dir, "frames");
144
+ await mkdir(out);
145
+ const scale = "scale='if(gt(iw,ih),-2,360)':'if(gt(iw,ih),360,-2)'";
146
+ await runFor(ffmpeg, [
147
+ ...["-hide_banner", "-loglevel", "error", "-i", file, "-an"],
148
+ ...["-vf", `fps=1/${every},${scale}`, "-q:v", "5", join(out, "%03d.jpg")],
149
+ ], TOOL_MS);
150
+ const names = (await readdir(out)).filter((n) => n.endsWith(".jpg")).sort();
151
+ return Promise.all(names.map(async (n, i) => ({ at: i * every, jpeg: await readFile(join(out, n)) })));
152
+ }
153
+ /** Cut times from a `list-scenes` CSV (`--skip-cuts`: the header, then one row a scene). Each scene after the first starts on a cut. */
154
+ export function parseScenes(csv) {
155
+ const rows = csv.trim().split("\n");
156
+ const col = (rows[0] ?? "").split(",").indexOf("Start Time (seconds)");
157
+ if (col < 0)
158
+ return [];
159
+ return rows
160
+ .slice(2)
161
+ .map((r) => Math.round(Number(r.split(",")[col]) * 100) / 100)
162
+ .filter((n) => Number.isFinite(n));
163
+ }
164
+ /** PySceneDetect's cuts by one detector. ffmpeg's `scene` misses a fade and a card swap on black; `hash` finds them (designs/studies/2026-10-25-launch-films.md). */
165
+ export async function sceneDetectCuts(file, detector, cmd, dir) {
166
+ const [bin, ...pre] = cmd.split(/\s+/);
167
+ const name = `scenes-${detector}.csv`;
168
+ await runFor(bin, [
169
+ ...pre,
170
+ "-q",
171
+ "-i",
172
+ file,
173
+ `detect-${detector}`,
174
+ "list-scenes",
175
+ "-o",
176
+ dir,
177
+ "-f",
178
+ name,
179
+ "--skip-cuts",
180
+ ], TOOL_MS);
181
+ return parseScenes(await readFile(join(dir, name), "utf8"));
182
+ }
183
+ /** Shot changes: the frames `select` keeps are logged by `showinfo`, on stderr. */
184
+ export async function sceneCuts(file, ffmpeg) {
185
+ const { stderr } = await runFor(ffmpeg, [
186
+ ...["-hide_banner", "-nostats", "-i", file, "-an"],
187
+ ...["-vf", `select='gt(scene,${SCENE})',showinfo`, "-f", "null", "-"],
188
+ ], TOOL_MS, { maxBuffer: 64 * 1024 * 1024 });
189
+ return [...stderr.matchAll(/pts_time:(\d+(?:\.\d+)?)/g)].map((m) => Math.round(Number(m[1]) * 100) / 100);
190
+ }
191
+ async function speech(file, dir, ffmpeg, ear, o) {
192
+ const mp3 = join(dir, "speech.mp3");
193
+ await runFor(ffmpeg, [
194
+ ...["-hide_banner", "-loglevel", "error", "-y", "-i", file, "-vn"],
195
+ ...["-ac", "1", "-ar", "16000", "-b:a", "48k", mp3],
196
+ ], TOOL_MS);
197
+ const heard = await ear.hear({ data: await readFile(mp3), mediaType: "audio/mpeg", filename: "speech.mp3" }, o);
198
+ return heard.text.trim();
199
+ }
200
+ // -- the whole video ---------------------------------------------------------------------
201
+ /** The video model's read of the screen from the file inline. Undefined: too large, or nothing came back. */
202
+ async function wholeScreen(file, dir, video, o) {
203
+ let bytes = await readFile(file);
204
+ if (bytes.length > INLINE_MAX)
205
+ bytes = await shrink(file, join(dir, "small.mp4"), o.info, o.ffmpeg);
206
+ if (bytes.length > INLINE_MAX)
207
+ return undefined;
208
+ try {
209
+ const text = await readMedia(video, [{ type: "video", data: bytes, mediaType: "video/mp4" }], (paraphrase) => `${SHOWN(0, paraphrase)} Markdown. If nothing is shown, reply with the single word none.`);
210
+ return text && text.toLowerCase() !== "none" ? text : undefined;
211
+ }
212
+ catch (err) {
213
+ console.warn(`${video.id} watch screen: not read, ${err instanceof Error ? err.message : err}`);
214
+ return undefined;
215
+ }
216
+ }
217
+ // -- the core -----------------------------------------------------------------------------
218
+ /** `Promise.all` that lets every promise finish before it throws the first failure: nothing still writes into the work directory when it goes. */
219
+ async function allSettled(ps) {
220
+ const done = await Promise.allSettled(ps);
221
+ for (const r of done)
222
+ if (r.status === "rejected")
223
+ throw r.reason;
224
+ return done.map((r) => r.value);
225
+ }
226
+ /** Watch a video file on disk (a URL is fetched first by `watch` in `url.ts`). */
227
+ export async function watchFile(input, opts) {
228
+ if (opts.video && !opts.video.takes.has("video"))
229
+ throw new Error(`${input}: ${opts.video.id} takes no video; pass it as the eye`);
230
+ const ffmpeg = opts.ffmpeg ?? "ffmpeg";
231
+ const dir = await mkdtemp(join(tmpdir(), "watch-"));
232
+ try {
233
+ const file = resolve(input);
234
+ const facts = await probe(file, ffmpeg).catch((err) => {
235
+ throw new Error(`${input}: ffprobe could not read it (${err.message.split("\n")[0]})`);
236
+ });
237
+ if (!facts.picture)
238
+ throw new Error(`${input}: no picture to watch`);
239
+ const durationS = facts.durationS;
240
+ const every = Math.max(opts.everyS ?? FRAME_EVERY_S, Math.ceil(durationS / MAX_FRAMES));
241
+ const psd = async (d) => opts.sceneDetect ? sceneDetectCuts(file, d, opts.sceneDetect, dir) : [];
242
+ const [c, h, a, f, s, g] = await allSettled([
243
+ sceneCuts(file, ffmpeg),
244
+ psd("hash"),
245
+ psd("adaptive"),
246
+ frames(file, dir, every, ffmpeg).then((shots) => readScreen(shots, opts.eye)),
247
+ opts.speech === false || !facts.audio || !opts.ear
248
+ ? Promise.resolve("")
249
+ : speech(file, dir, ffmpeg, opts.ear, {
250
+ language: opts.language ?? "en",
251
+ seconds: durationS,
252
+ }),
253
+ opts.video
254
+ ? wholeScreen(file, dir, opts.video, {
255
+ ffmpeg,
256
+ info: {
257
+ duration: durationS,
258
+ ...(facts.width ? { width: facts.width } : {}),
259
+ ...(facts.height ? { height: facts.height } : {}),
260
+ },
261
+ }).catch(() => undefined)
262
+ : Promise.resolve(undefined),
263
+ ]);
264
+ return {
265
+ durationS: Math.round(durationS * 100) / 100,
266
+ cuts: c,
267
+ ...(opts.sceneDetect ? { cutsBy: { hash: h, adaptive: a } } : {}),
268
+ audio: facts.audio,
269
+ speech: s,
270
+ frames: f,
271
+ ...(g ? { whole: g } : {}),
272
+ };
273
+ }
274
+ finally {
275
+ await rm(dir, { recursive: true, force: true });
276
+ }
277
+ }
278
+ // -- the page -----------------------------------------------------------------------------
279
+ /** The frames with something to say, each under its ffmpeg frame time; the unread ones say so. */
280
+ export function onScreenLines(w) {
281
+ return w.frames.flatMap((f) => f.text === null
282
+ ? [`[${clock(f.at)}] (not read)`]
283
+ : f.text
284
+ ? [`[${clock(f.at)}] ${f.text}`]
285
+ : []);
286
+ }
287
+ export const cutsLine = (w) => w.cuts.length ? w.cuts.map(stamp).join(", ") : "(none)";
288
+ /** `read`, `unread`: how many frames the model returned a line for. */
289
+ export function frameCounts(w) {
290
+ const unread = w.frames.filter((f) => f.text === null).length;
291
+ return { read: w.frames.length - unread, unread };
292
+ }
293
+ export const watchFacts = (w) => ({
294
+ duration_s: w.durationS,
295
+ audio: w.audio,
296
+ cuts_by: { ffmpeg: w.cuts, ...(w.cutsBy ?? {}) },
297
+ });
298
+ /** The facts fence of a rendered page, when it has one. */
299
+ export function readWatchFacts(md) {
300
+ const m = /## Facts\n\n```json\n([\s\S]*?)\n```/.exec(md);
301
+ if (!m)
302
+ return null;
303
+ try {
304
+ return JSON.parse(m[1]);
305
+ }
306
+ catch {
307
+ return null;
308
+ }
309
+ }
310
+ export function renderWatched(w) {
311
+ const screen = onScreenLines(w).join("\n") || "(no text on screen)";
312
+ return [
313
+ `## Speech\n\n${w.speech || "(no speech)"}`,
314
+ `## On screen\n\n${screen}`,
315
+ ...(w.whole ? [`## On screen (whole video)\n\n${w.whole}`] : []),
316
+ `## Cuts\n\n${cutsLine(w)}`,
317
+ // Only a film's page carries the fence: a reel's cuts are the line above.
318
+ ...(w.cutsBy ? [`## Facts\n\n\`\`\`json\n${JSON.stringify(watchFacts(w))}\n\`\`\``] : []),
319
+ ].join("\n\n");
320
+ }
321
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/video/watch.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,58 @@
1
1
  {
2
2
  "name": "@wrenautomation/read",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.29.0",
4
+ "description": "The web and files in, text out. Polite HTTP fetching with robots and a fetch ladder up to a browser; HTML and PDF to text, a page to title, text and links; a video or podcast from a URL or a file (captions, ffmpeg and a vision model, audio to markdown, what a channel or search holds); a study's synthesis reader whose every claim quotes a page.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/wrenautomation/engine.git",
8
+ "directory": "packages/read"
9
+ },
10
+ "license": "PolyForm-Strict-1.0.0",
11
+ "files": [
12
+ "dist",
13
+ "!dist/**/*.test.*",
14
+ "README.md",
15
+ "LICENSE.md"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "type": "module",
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "import": "./dist/index.js"
25
+ },
26
+ "./fetch": {
27
+ "types": "./dist/fetch/index.d.ts",
28
+ "import": "./dist/fetch/index.js"
29
+ },
30
+ "./study": {
31
+ "types": "./dist/study/index.d.ts",
32
+ "import": "./dist/study/index.js"
33
+ },
34
+ "./text": {
35
+ "types": "./dist/text/index.d.ts",
36
+ "import": "./dist/text/index.js"
37
+ },
38
+ "./video": {
39
+ "types": "./dist/video/index.d.ts",
40
+ "import": "./dist/video/index.js"
41
+ }
42
+ },
43
+ "engines": {
44
+ "node": ">=24"
45
+ },
46
+ "dependencies": {
47
+ "entities": "8.1.0",
48
+ "htmlparser2": "12.0.0",
49
+ "robots-parser": "3.0.1",
50
+ "unpdf": "1.8.1",
51
+ "zod": "4.6.5",
52
+ "@wrenautomation/models": "0.29.0"
53
+ },
54
+ "scripts": {
55
+ "typecheck": "tsc --noEmit",
56
+ "build": "sh ../../scripts/build.sh"
57
+ }
6
58
  }