@tienne/gestalt 0.103.0 → 0.105.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/package.json +1 -1
- package/dist/plugin/role-agents/video-summarizer/AGENT.md +75 -15
- package/dist/plugin/skills/_shared/proactive-routing.md +1 -1
- package/dist/plugin/skills/video-digest/SKILL.md +121 -49
- package/dist/plugin/skills/video-digest/templates/visual.md +22 -0
- package/dist/src/cli/commands/digest.d.ts +3 -0
- package/dist/src/cli/commands/digest.d.ts.map +1 -1
- package/dist/src/cli/commands/digest.js +34 -1
- package/dist/src/cli/commands/digest.js.map +1 -1
- package/dist/src/cli/index.d.ts.map +1 -1
- package/dist/src/cli/index.js +6 -2
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/digest/blocks.d.ts +3875 -504
- package/dist/src/digest/blocks.d.ts.map +1 -1
- package/dist/src/digest/blocks.js +14 -6
- package/dist/src/digest/blocks.js.map +1 -1
- package/dist/src/digest/diagram-schema.d.ts +765 -0
- package/dist/src/digest/diagram-schema.d.ts.map +1 -0
- package/dist/src/digest/diagram-schema.js +72 -0
- package/dist/src/digest/diagram-schema.js.map +1 -0
- package/dist/src/digest/frames.d.ts +21 -1
- package/dist/src/digest/frames.d.ts.map +1 -1
- package/dist/src/digest/frames.js +124 -27
- package/dist/src/digest/frames.js.map +1 -1
- package/dist/src/digest/index.d.ts +1 -0
- package/dist/src/digest/index.d.ts.map +1 -1
- package/dist/src/digest/index.js +1 -0
- package/dist/src/digest/index.js.map +1 -1
- package/dist/src/digest/lint-extension.d.ts +16 -2
- package/dist/src/digest/lint-extension.d.ts.map +1 -1
- package/dist/src/digest/lint-extension.js +122 -5
- package/dist/src/digest/lint-extension.js.map +1 -1
- package/dist/src/digest/lint.d.ts +15 -5
- package/dist/src/digest/lint.d.ts.map +1 -1
- package/dist/src/digest/lint.js +93 -50
- package/dist/src/digest/lint.js.map +1 -1
- package/dist/src/digest/merge.d.ts.map +1 -1
- package/dist/src/digest/merge.js +4 -1
- package/dist/src/digest/merge.js.map +1 -1
- package/dist/src/digest/ocr.d.ts +4 -0
- package/dist/src/digest/ocr.d.ts.map +1 -1
- package/dist/src/digest/ocr.js +17 -6
- package/dist/src/digest/ocr.js.map +1 -1
- package/dist/src/digest/prose.d.ts +6 -2
- package/dist/src/digest/prose.d.ts.map +1 -1
- package/dist/src/digest/prose.js +61 -2
- package/dist/src/digest/prose.js.map +1 -1
- package/dist/src/digest/render-blocks.d.ts +7 -1
- package/dist/src/digest/render-blocks.d.ts.map +1 -1
- package/dist/src/digest/render-blocks.js +107 -21
- package/dist/src/digest/render-blocks.js.map +1 -1
- package/dist/src/digest/render-html.d.ts.map +1 -1
- package/dist/src/digest/render-html.js +62 -17
- package/dist/src/digest/render-html.js.map +1 -1
- package/dist/src/digest/render-md.d.ts.map +1 -1
- package/dist/src/digest/render-md.js +15 -2
- package/dist/src/digest/render-md.js.map +1 -1
- package/dist/src/digest/render.d.ts.map +1 -1
- package/dist/src/digest/render.js +4 -1
- package/dist/src/digest/render.js.map +1 -1
- package/dist/src/digest/reports.d.ts +9 -1
- package/dist/src/digest/reports.d.ts.map +1 -1
- package/dist/src/digest/reports.js +24 -1
- package/dist/src/digest/reports.js.map +1 -1
- package/dist/src/digest/scenes.d.ts +92 -0
- package/dist/src/digest/scenes.d.ts.map +1 -0
- package/dist/src/digest/scenes.js +182 -0
- package/dist/src/digest/scenes.js.map +1 -0
- package/dist/src/digest/schema.d.ts +10458 -3285
- package/dist/src/digest/schema.d.ts.map +1 -1
- package/dist/src/digest/schema.js +16 -30
- package/dist/src/digest/schema.js.map +1 -1
- package/dist/src/digest/svg.d.ts +30 -0
- package/dist/src/digest/svg.d.ts.map +1 -1
- package/dist/src/digest/svg.js +151 -0
- package/dist/src/digest/svg.js.map +1 -1
- package/dist/src/digest/viewer-js.d.ts.map +1 -1
- package/dist/src/digest/viewer-js.js +85 -51
- package/dist/src/digest/viewer-js.js.map +1 -1
- package/dist/src/digest/viewer-logic.d.ts +22 -5
- package/dist/src/digest/viewer-logic.d.ts.map +1 -1
- package/dist/src/digest/viewer-logic.js +23 -4
- package/dist/src/digest/viewer-logic.js.map +1 -1
- package/dist/src/mcp/schemas.js +1 -1
- package/dist/src/mcp/schemas.js.map +1 -1
- package/dist/src/mcp/tools/digest-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/digest-passthrough.js +3 -0
- package/dist/src/mcp/tools/digest-passthrough.js.map +1 -1
- package/package.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/.mcp.json +1 -1
- package/plugin/mcp.json +1 -1
- package/plugin/role-agents/video-summarizer/AGENT.md +75 -15
- package/plugin/skills/_shared/proactive-routing.md +1 -1
- package/plugin/skills/video-digest/SKILL.md +121 -49
- package/plugin/skills/video-digest/templates/visual.md +22 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { existsSync, mkdtempSync, rmSync } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { writeJsonAtomic } from '../core/json-file.js';
|
|
6
|
+
import { ensureVideo, parseShowinfo } from './frames.js';
|
|
7
|
+
import { OCR_FILE, ocrFileSchema } from './ocr.js';
|
|
8
|
+
import { DigestStore, readRaw } from './store.js';
|
|
9
|
+
import { findSegmentIndex } from './viewer-logic.js';
|
|
10
|
+
import { runCommand, timeoutFor } from './ytdlp.js';
|
|
11
|
+
/**
|
|
12
|
+
* 소섹션 shots가 고를 수 있는 후보 장면. 슬라이드가 넘어가거나 화면이 바뀐 시각이다.
|
|
13
|
+
* 요약 작성자는 장면을 보지 못하니 OCR 글자 앞부분을 붙여 무엇이 화면에 있었는지 짐작하게 한다
|
|
14
|
+
*/
|
|
15
|
+
export const SCENES_FILE = 'scenes.json';
|
|
16
|
+
/** 이보다 글자가 적은 화면은 사람 얼굴이나 자막 한 줄일 때가 많아 슬라이드로 보지 않는다 */
|
|
17
|
+
export const SCENE_MIN_CHARS = 40;
|
|
18
|
+
/** 앞 항목과 단어가 이 비율보다 많이 달라야 다른 화면으로 본다 */
|
|
19
|
+
export const SCENE_CHANGE_RATIO = 0.5;
|
|
20
|
+
/** ffmpeg 장면 전환 점수 문턱 */
|
|
21
|
+
export const SCENE_THRESHOLD = 0.4;
|
|
22
|
+
// 대담 영상은 카메라가 몇 초마다 바뀌어서 장면 전환이 수백 번 잡힌다. 간격과 개수를 묶어 목록이 요약 입력을 덮지 않게 한다
|
|
23
|
+
export const SCENE_MIN_GAP_SEC = 3;
|
|
24
|
+
export const MAX_SCENES = 300;
|
|
25
|
+
const TEXT_HEAD = 80;
|
|
26
|
+
export const scenesFileSchema = z.object({
|
|
27
|
+
source: z.enum(['ocr', 'scene']),
|
|
28
|
+
items: z
|
|
29
|
+
.array(z.object({
|
|
30
|
+
sec: z.number().nonnegative(),
|
|
31
|
+
i: z.number().int().nonnegative(),
|
|
32
|
+
text: z.string().optional(),
|
|
33
|
+
}))
|
|
34
|
+
.max(MAX_SCENES),
|
|
35
|
+
/** 상한을 넘어 솎았을 때만 있다. 솎기 전 후보 수다 */
|
|
36
|
+
total: z.number().int().nonnegative().optional(),
|
|
37
|
+
});
|
|
38
|
+
const squash = (text) => text.replace(/\s+/g, '').toLowerCase();
|
|
39
|
+
const NO_SPACE_SCRIPT = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}]/u;
|
|
40
|
+
// 단어로 견준다. 두 글자 조각으로 견주면 영어 슬라이드끼리 흔한 조각이 겹쳐 다른 화면도 비슷하게 나온다.
|
|
41
|
+
// 띄어쓰기가 없는 중국어와 일본어 덩어리만 두 글자 조각으로 쪼갠다
|
|
42
|
+
function tokens(text) {
|
|
43
|
+
const out = new Set();
|
|
44
|
+
for (const word of text.toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? []) {
|
|
45
|
+
if (word.length <= 2 || !NO_SPACE_SCRIPT.test(word)) {
|
|
46
|
+
out.add(word);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
for (let k = 0; k + 1 < word.length; k++)
|
|
50
|
+
out.add(word.slice(k, k + 2));
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
/** cur의 단어 가운데 prev에 없는 비율. 0이면 같은 화면, 1이면 전혀 다른 화면이다 */
|
|
55
|
+
export function textChange(prev, cur) {
|
|
56
|
+
const a = tokens(prev);
|
|
57
|
+
const b = tokens(cur);
|
|
58
|
+
if (b.size === 0)
|
|
59
|
+
return 0;
|
|
60
|
+
let fresh = 0;
|
|
61
|
+
for (const g of b)
|
|
62
|
+
if (!a.has(g))
|
|
63
|
+
fresh += 1;
|
|
64
|
+
return fresh / b.size;
|
|
65
|
+
}
|
|
66
|
+
export function textHead(text, max = TEXT_HEAD) {
|
|
67
|
+
const line = text.replace(/\s+/g, ' ').trim();
|
|
68
|
+
return line.length <= max ? line : `${line.slice(0, max - 1)}…`;
|
|
69
|
+
}
|
|
70
|
+
/** 글자가 넉넉하고 앞 항목과 절반 넘게 다른 화면만 남긴다. 슬라이드가 넘어간 자리다 */
|
|
71
|
+
export function ocrScenes(ocr) {
|
|
72
|
+
const out = [];
|
|
73
|
+
let prev = '';
|
|
74
|
+
for (const item of ocr.items) {
|
|
75
|
+
const enough = squash(item.text).length >= SCENE_MIN_CHARS;
|
|
76
|
+
if (enough && textChange(prev, item.text) > SCENE_CHANGE_RATIO) {
|
|
77
|
+
out.push({ sec: item.sec, i: item.i, text: textHead(item.text) });
|
|
78
|
+
}
|
|
79
|
+
prev = item.text;
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
/** 앞 후보와 minGap초 안에 붙은 전환은 버린다. 카메라가 연달아 바뀌는 자리는 하나만 남는다 */
|
|
84
|
+
export function thinSceneTimes(secs, minGap = SCENE_MIN_GAP_SEC) {
|
|
85
|
+
const out = [];
|
|
86
|
+
for (const sec of [...secs].sort((a, b) => a - b)) {
|
|
87
|
+
const last = out[out.length - 1];
|
|
88
|
+
if (last === undefined || sec - last >= minGap)
|
|
89
|
+
out.push(sec);
|
|
90
|
+
}
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
/** 시간순 후보가 max개를 넘으면 처음과 끝을 포함해 고르게 솎는다. 앞에서 자르면 영상 뒷부분 장면이 통째로 빠진다 */
|
|
94
|
+
export function spreadEvenly(items, max = MAX_SCENES) {
|
|
95
|
+
if (items.length <= max)
|
|
96
|
+
return [...items];
|
|
97
|
+
if (max <= 1)
|
|
98
|
+
return items.slice(0, max);
|
|
99
|
+
return Array.from({ length: max }, (_, k) => items[Math.round((k * (items.length - 1)) / (max - 1))]);
|
|
100
|
+
}
|
|
101
|
+
function scenesFile(source, all) {
|
|
102
|
+
const items = spreadEvenly(all);
|
|
103
|
+
return items.length < all.length ? { source, items, total: all.length } : { source, items };
|
|
104
|
+
}
|
|
105
|
+
export function readScenes(store, slug) {
|
|
106
|
+
const raw = readRaw(join(store.dir(slug), SCENES_FILE));
|
|
107
|
+
if (raw.kind === 'missing')
|
|
108
|
+
return raw;
|
|
109
|
+
if (raw.kind === 'invalid-json')
|
|
110
|
+
return { kind: 'invalid', message: raw.message };
|
|
111
|
+
const parsed = scenesFileSchema.safeParse(raw.value);
|
|
112
|
+
if (!parsed.success) {
|
|
113
|
+
const issues = parsed.error.issues
|
|
114
|
+
.slice(0, 3)
|
|
115
|
+
.map((i) => `${i.path.join('.') || '(root)'}: ${i.message}`);
|
|
116
|
+
return { kind: 'invalid', message: issues.join('; ') };
|
|
117
|
+
}
|
|
118
|
+
return { kind: 'ok', value: parsed.data };
|
|
119
|
+
}
|
|
120
|
+
/** lint가 받는 꼴. 파일이 없거나 깨졌으면 null이다 */
|
|
121
|
+
export function sceneSecs(store, slug) {
|
|
122
|
+
const r = readScenes(store, slug);
|
|
123
|
+
return r.kind === 'ok' ? r.value.items.map((s) => s.sec) : null;
|
|
124
|
+
}
|
|
125
|
+
function readOcr(store, slug) {
|
|
126
|
+
const path = join(store.dir(slug), OCR_FILE);
|
|
127
|
+
if (!existsSync(path))
|
|
128
|
+
return null;
|
|
129
|
+
const raw = readRaw(path);
|
|
130
|
+
if (raw.kind !== 'ok')
|
|
131
|
+
return null;
|
|
132
|
+
const parsed = ocrFileSchema.safeParse(raw.value);
|
|
133
|
+
return parsed.success ? parsed.data : null;
|
|
134
|
+
}
|
|
135
|
+
function saveScenes(path, file) {
|
|
136
|
+
writeJsonAtomic(path, file);
|
|
137
|
+
const total = file.total ?? file.items.length;
|
|
138
|
+
return {
|
|
139
|
+
path,
|
|
140
|
+
source: file.source,
|
|
141
|
+
items: file.items.length,
|
|
142
|
+
total,
|
|
143
|
+
truncated: total > file.items.length,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* 후보 장면을 scenes.json에 둔다. ocr.json이 있으면 글자로 고르고 없으면 ffmpeg 장면 전환을 쓴다.
|
|
148
|
+
* 장면 전환만으로는 슬라이드인지 얼굴인지 못 가려서 글자가 있으면 글자를 먼저 쓴다
|
|
149
|
+
*/
|
|
150
|
+
export async function pickScenes(slug, opts) {
|
|
151
|
+
const store = new DigestStore(opts.repoRoot);
|
|
152
|
+
const t = store.readTranscript(slug);
|
|
153
|
+
if (!t.ok)
|
|
154
|
+
throw new Error(t.message);
|
|
155
|
+
const transcript = t.transcript;
|
|
156
|
+
const path = join(store.dir(slug), SCENES_FILE);
|
|
157
|
+
const ocr = readOcr(store, slug);
|
|
158
|
+
if (ocr) {
|
|
159
|
+
return saveScenes(path, scenesFile('ocr', ocrScenes(ocr)));
|
|
160
|
+
}
|
|
161
|
+
const run = opts.run ?? runCommand;
|
|
162
|
+
const cwd = mkdtempSync(join(tmpdir(), 'gestalt-digest-scenes-'));
|
|
163
|
+
try {
|
|
164
|
+
const video = await ensureVideo(run, transcript, store.videoCacheDir(slug), cwd);
|
|
165
|
+
// 점수만 보면 되니 작게 줄여서 디코딩을 가볍게 한다
|
|
166
|
+
const { stderr } = await run('ffmpeg', [
|
|
167
|
+
...['-hide_banner', '-nostats', '-i', video, '-an'],
|
|
168
|
+
...['-vf', `scale=320:-2,select='gt(scene,${SCENE_THRESHOLD})',showinfo`],
|
|
169
|
+
...['-f', 'null', '-'],
|
|
170
|
+
], { cwd, timeoutMs: timeoutFor(transcript.meta.durationSec, 0.5) });
|
|
171
|
+
const starts = transcript.segments.map((s) => s.startSec);
|
|
172
|
+
const items = thinSceneTimes(parseShowinfo(stderr)).map((raw) => {
|
|
173
|
+
const sec = Math.round(raw * 100) / 100;
|
|
174
|
+
return { sec, i: Math.max(0, findSegmentIndex(starts, sec)) };
|
|
175
|
+
});
|
|
176
|
+
return saveScenes(path, scenesFile('scene', items));
|
|
177
|
+
}
|
|
178
|
+
finally {
|
|
179
|
+
rmSync(cwd, { recursive: true, force: true });
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=scenes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scenes.js","sourceRoot":"","sources":["../../../src/digest/scenes.ts"],"names":[],"mappings":"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"}
|