akari-video 0.1.62 → 0.1.64

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 (52) hide show
  1. package/package.json +1 -1
  2. package/src/capture-command.mjs +10 -2
  3. package/src/repo-assets.mjs +2 -1
  4. package/vendor/.akari-capability-sources.json +1 -0
  5. package/vendor/docs/contract-2026-08-02-preview-parity.md +36 -0
  6. package/vendor/docs/contract-2026-08-11-review-session-ui-events.md +1 -0
  7. package/vendor/docs/contract-2026-08-23-captions-emphasis-words-v0.md +22 -2
  8. package/vendor/docs/contract-2026-08-23-stroke-persistence.md +14 -2
  9. package/vendor/docs/contract-2026-09-12-review-session-viewer.md +97 -0
  10. package/vendor/packages/akari-launcher/package.json +1 -1
  11. package/vendor/packages/edit-lint/README.md +13 -2
  12. package/vendor/packages/edit-lint/src/edit-lint.mjs +236 -15
  13. package/vendor/packages/edit-store/lib/caption-display.d.ts +65 -0
  14. package/vendor/packages/edit-store/lib/caption-display.js +554 -62
  15. package/vendor/packages/edit-store/lib/caption-store.d.ts +2 -0
  16. package/vendor/packages/edit-store/lib/caption-store.js +111 -1
  17. package/vendor/packages/edit-store/lib/caption-window.d.ts +25 -0
  18. package/vendor/packages/edit-store/lib/caption-window.js +104 -0
  19. package/vendor/packages/edit-store/lib/cut-ranges.d.ts +2 -1
  20. package/vendor/packages/edit-store/lib/cut-ranges.js +27 -0
  21. package/vendor/packages/edit-store/lib/edit-v2.js +1 -1
  22. package/vendor/packages/edit-store/lib/history-store.d.ts +29 -0
  23. package/vendor/packages/edit-store/lib/history-store.js +186 -0
  24. package/vendor/packages/edit-store/lib/internal-model.d.ts +2 -0
  25. package/vendor/packages/edit-store/lib/internal-model.js +60 -8
  26. package/vendor/packages/edit-store/lib/webview-kernel.js +135 -9
  27. package/vendor/packages/schemas/bin/validate-captions.mjs +18 -4
  28. package/vendor/packages/schemas/bin/validate-edit.mjs +12 -0
  29. package/vendor/packages/schemas/captions.schema.json +10 -4
  30. package/vendor/packages/schemas/edit.schema.json +12 -0
  31. package/vendor/packages/schemas/fixtures/review/valid-session-fields/review.json +6 -0
  32. package/vendor/packages/schemas/review.schema.json +27 -0
  33. package/vendor/packages/schemas/test/edit-cut-reason.test.mjs +81 -0
  34. package/vendor/packages/schemas/test/edit-v2-schema.test.mjs +28 -0
  35. package/vendor/packages/schemas/test/validate-captions.test.mjs +51 -0
  36. package/vendor/skills/analyze-footage/bin/transcribe-cloud.mjs +9 -2
  37. package/vendor/skills/analyze-footage/bin/transcribe-sa.mjs +62 -4
  38. package/vendor/skills/analyze-footage/test/fixtures/scribe-speakers.json +8 -0
  39. package/vendor/skills/analyze-footage/test/normalize-scribe.test.mjs +19 -0
  40. package/vendor/skills/compile-review-session/bin/compile-review-session.mjs +9 -2
  41. package/vendor/skills/compile-review-session/bin/core/compiler.mjs +3 -1
  42. package/vendor/skills/compile-review-session/bin/core/install-root.mjs +125 -0
  43. package/vendor/skills/compile-review-session/bin/core/time-mapping.mjs +138 -11
  44. package/vendor/skills/compile-review-session/bin/core/transcription.mjs +117 -40
  45. package/vendor/skills/compile-review-session/compilation-rules.md +3 -0
  46. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0010/audio.wav +0 -0
  47. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0010/edit.snapshot.json +45 -0
  48. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0010/events.jsonl +2 -0
  49. package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0010/session.json +11 -0
  50. package/vendor/skills/compile-review-session/test/compiler.test.mjs +233 -0
  51. package/vendor/skills/compile-review-session/test/install-root.test.mjs +167 -0
  52. package/vendor/skills/compile-review-session/test/ui-events.test.mjs +68 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akari-video",
3
- "version": "0.1.62",
3
+ "version": "0.1.64",
4
4
  "description": "AKARI Video launcher CLI — start an AI-edited video project from any directory: scaffold, connection check, then hand over to Claude Code (or opencode). AKARI Video を opencode や Claude Code で、どのディレクトリからでも始めるための `akari` ランチャー CLI。接続確認(doctor)→ 未セットアップならプロジェクト雛形を作成 → AI エージェントを起動する。外部 npm 依存ゼロ(Node.js 組み込みモジュールのみ)。",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,13 +1,21 @@
1
1
  import { spawnSync } from "node:child_process";
2
2
  import { existsSync } from "node:fs";
3
3
 
4
- import { resolveLauncherAssets } from "./repo-assets.mjs";
4
+ import { CAPTURE_SCRIPT_RELATIVE, resolveLauncherAssets } from "./repo-assets.mjs";
5
5
 
6
6
  export async function runCaptureCommand(argv, options = {}) {
7
7
  const logError = options.error ?? options.logError ?? ((line) => console.error(line));
8
8
  const assets = options.assets ?? resolveLauncherAssets();
9
9
  if (!assets.captureScript || !existsSync(assets.captureScript)) {
10
- logError("akari capture の実行スクリプトが見つかりません。AKARI Video を再インストールしてください。");
10
+ // 再インストールで直る欠けではない(同梱漏れは配布物側の問題)。欠けている同梱物と
11
+ // 探索した置き場を名指しして、報告・切り分けに使える形で止める(issue #74)。
12
+ const missing = assets.captureScript ?? CAPTURE_SCRIPT_RELATIVE;
13
+ logError(
14
+ `akari capture の実行スクリプトが見つかりません: ${missing}`
15
+ + `(探索先: ${assets.repoRoot ?? "不明"})。`
16
+ + "この AKARI Video 配布物に packages/akari-tools/bin/capture.mjs が同梱されていません。"
17
+ + "バージョンと OS を添えて https://github.com/AkariLabs/akari-video/issues へ報告してください。",
18
+ );
11
19
  return { exitCode: 1 };
12
20
  }
13
21
 
@@ -35,7 +35,8 @@ const BEATMAP_SCRIPT_RELATIVE = path.join('packages', 'akari-tools', 'bin', 'bea
35
35
  const PROBE_FRAME_SCRIPT_RELATIVE = path.join('packages', 'akari-tools', 'bin', 'probe-frame.mjs');
36
36
  const DECISION_LOG_SCRIPT_RELATIVE = path.join('packages', 'akari-tools', 'bin', 'decision-log.mjs');
37
37
  const CAPTIONS_SCRIPT_RELATIVE = path.join('packages', 'akari-tools', 'bin', 'captions.mjs');
38
- const CAPTURE_SCRIPT_RELATIVE = path.join('packages', 'akari-tools', 'bin', 'capture.mjs');
38
+ // capture-command.mjs のエラー文と apps/shell の同梱テストが同じ相対パスを名指しできるよう export する。
39
+ export const CAPTURE_SCRIPT_RELATIVE = path.join('packages', 'akari-tools', 'bin', 'capture.mjs');
39
40
  const RENDER_WHEN_IDLE_SCRIPT_RELATIVE = path.join('packages', 'akari-tools', 'bin', 'render-when-idle.sh');
40
41
  const EYE_BAR_SCRIPT_RELATIVE = path.join('packages', 'akari-tools', 'bin', 'eye-bar.mjs');
41
42
 
@@ -66,6 +66,7 @@
66
66
  "docs/contract-2026-09-05-clip-adjust-v1.md",
67
67
  "docs/contract-2026-09-06-cut-audio-split-v0.md",
68
68
  "docs/contract-2026-09-06-vgpu-layer-v0.md",
69
+ "docs/contract-2026-09-12-review-session-viewer.md",
69
70
  "packages/akari-launcher/package.json",
70
71
  "packages/akari-launcher/README.md",
71
72
  "packages/akari-tools/package.json",
@@ -12,6 +12,7 @@
12
12
  | 2026-08-28 | v2 | `packages/frame-engine` の意味論へ統合し、検収をゴールデンフレームへ一本化。出口を OSR と GPU 直結の 2 本に固定し、互換経路を退役節へ移動 |
13
13
  | 2026-08-31 | v2.1 | §5.2 に断片 CSS の `vw` / `vh` 系単位の出力サイズ基準化(`viewport-units.js`。プレビューがウィンドウ幅基準で解いていた実機報告の修正)を追記 |
14
14
  | 2026-09-02 | v2.2 | §2.8 に字幕時計の規約(active cue の判定は両プレビューとも出力秒。共有カーネル `caption-clock`)を追記。Web UI を shell に揃えた 4 点(字幕時計・字幕フォント名・`slot-params.js` の差し込み・最下段 cut の track 規則)の記録 |
15
+ | 2026-09-10 | v2.3 | §5.8 に shell 合成面の内部解像度(auto / 手動倍率・停止時等倍)と構図一致の許容差を追加 |
15
16
 
16
17
  ## 1. 役割分担
17
18
 
@@ -346,3 +347,38 @@ frame-engine が MP4 を全体ストリームとして読むか、`ftyp` / `moov
346
347
  Range として読むかは、完成画の意味論に影響しない。どちらの読み込み経路も同じ presentation 時刻の
347
348
  VideoFrame を §4.1 の評価点へ供給し、`elst.media_time`、B フレームの並べ替え、メディア終端を含めて
348
349
  golden の `diff 0` を満たさなければならない。ソース取得方法の変更をパリティ差の許容理由にしてはならない。
350
+
351
+ ### 5.8 プレビュー内部解像度(render scale)
352
+
353
+ shell の frame-engine 合成面は、辺あたり倍率 `s ∈ {1, 0.5, 0.25}` を使える。
354
+ 設定 `akari.preview.renderScale` の語彙は `'auto' | '1' | '0.5' | '0.25'`、既定は `'auto'`。
355
+ 環境変数 `AKARI_FRAME_ENGINE_RENDER_SCALE` は設定より優先し、不正値は `auto` とする。
356
+ 設定項目のみとし、専用ボタンやポップアップは設けない。
357
+
358
+ `auto` は canvas の `getBoundingClientRect()` に `devicePixelRatio` を掛けた表示寸法に対し、
359
+ `output.width × s ≥ 表示幅` かつ `output.height × s ≥ 表示高` を満たす最小の倍率を選ぶ。
360
+ 上限は `1`、表示寸法が 0 の場合も `1` とする。canvas の `ResizeObserver` と
361
+ `matchMedia('(resolution: <dpr>dppx)')` の change で再評価し、100 ms デバウンスする。
362
+ 内部寸法は各辺を `roundEven(output寸法 × s)`(最寄りの偶数へ丸め、中間は上へ)とし、下限は 2 px。
363
+
364
+ `auto` では再生停止・スクラブ終了から 250 ms 後に `s = 1` で 1 コマ描き直し、
365
+ 再生・スクラブの再開で表示寸法に応じた倍率へ戻す。手動倍率は停止中も固定し、停止による追加描画はしない。
366
+ 倍率変更は scheduler・評価 plan・compose が共有する `renderOutput` の width / height を in-place で更新する。
367
+ scheduler を作り直して warmup を捨てず、停止中の寸法更新は 1 コマの再描画へ反映する。
368
+ developerMode の計測パネルに倍率・内部寸法・等倍寸法・モードを 1 行表示する。
369
+
370
+ エンジンのレイヤー / layer-style cut の幾何は出力 px 基準(box = crop × 素材 px × scale、
371
+ 出力中心 + (x, y))なので、shell は評価 plan の px 基準の transform(x / y、および px 基準の scale)を
372
+ `s` で射影してから合成する。fit 基準の通常 cut の scale と正規化座標は不変とし、入力 plan を変更せず、
373
+ `plan.output` は共有参照を保つ。エンジン・ゴールデン検収・書き出しは不変。
374
+
375
+ 一致条件は**構図一致 = 位置・大きさ・時刻・ツマミ値の一致**であり、内部画素数は異なってよい。
376
+ [vgpu レイヤー契約 §4](./contract-2026-09-06-vgpu-layer-v0.md#4-api解像度ツマミ) の例外を
377
+ shell の合成面全体へ拡張する。等倍の完成画を縮小した画像と縮小倍率で描いた画像を比較し、
378
+ `packages/frame-engine/src/metrics/frame-diff.ts` の MAD で **≤ 2.0 / 255** を要求する。
379
+ 粒状ノイズ FX と dissolve 区間はこの比較から除外する。DOM 層(字幕 / overlay / 3D / ペン)、
380
+ `summary.output`、`frameScale`、当たり判定、インスペクター、書き込み経路の規約は不変。
381
+
382
+ **書き出しとゴールデン検収は常に等倍で、本設定の対象外**。GPU / OSR の page-runtime、
383
+ 書き出し receipt、§4.1・§4.2 のゴールデンと許容差、`packages/frame-engine` とその生成バンドルは変更しない。
384
+ Web UI の合成面、デコード解像度、vgpu 固有の `previewScale`、3D の `PREVIEW_3D_MAX_RENDER_SIZE` も対象外とする。
@@ -46,6 +46,7 @@
46
46
  | `panel:<id>` | シェルの主要パネル | `panel:assets` / `panel:inspector` / `panel:review` / `panel:timeline` |
47
47
  | `tab:<id>` | タブ | `tab:assets-builtin` |
48
48
  | `timeline:cut:<n>` | タイムラインのカット(cuts[] index) | `timeline:cut:3` |
49
+ | `timeline:item:<id>` | v2 タイムラインのカット(tracks[].items[].id。compile 時に legacy cuts[] index へ射影) | `timeline:item:cut-4` |
49
50
  | `timeline:overlay:<id>` | タイムラインのオーバーレイ | `timeline:overlay:o-0002` |
50
51
  | `asset:<path>` | 素材(プロジェクト相対 or カタログ id) | `asset:assets/broll/city.mp4` |
51
52
  | `asset:<category>/<id>` | 素材(カタログ由来カード。key = `<category>/<id>`) | `asset:still/br-typing-laptop` |
@@ -27,6 +27,7 @@
27
27
  "t_end": 12.44,
28
28
  "word": "最高",
29
29
  "emotion": "joy",
30
+ "style_preset": "neon",
30
31
  "style_hint": "size-pulse"
31
32
  }
32
33
  ],
@@ -49,11 +50,12 @@
49
50
  `captions.json.emphasis_words` へ移す。
50
51
  2. `edit.json` v2 へは書かない。v0/v1 の旧席は後方互換の読取専用として残す。
51
52
 
52
- したがって各レコードは `{ id, word, emotion, src?, t_start, t_end, style_hint? }` で、`id` は
53
+ したがって各レコードは `{ id, word, emotion, src?, t_start, t_end, style_preset?, style_hint? }` で、`id` は
53
54
  `^e-\d{4}$` かつファイル内一意、`word` と `emotion` は空でない文字列、時刻は source 秒で
54
55
  `0 <= t_start < t_end` とする。`emotion` は `joy` / `pain` / `surprise` / `anger` / `sadness` /
55
56
  `emphasis` を標準語彙として使うが、v1 契約どおり enum 強制はしない。`style_hint` も描画側への
56
- 提案に留まる。
57
+ 提案に留まる。`style_preset` は任意で、字幕テンプレと同じ `textstyle-catalog` の id を語の見た目として
58
+ 提案する。台本パネルの単語選択から「🎨 テンプレ」を適用すると、この席へ範囲ごとに 1 件を書く。
57
59
 
58
60
  ## 3. 読取優先順
59
61
 
@@ -75,3 +77,21 @@
75
77
  語と `captions[].words[]` の実測値の突き合わせは v1 契約と同じく書き手の規律であり、静的検証では
76
78
  行わない。
77
79
  edit-lint は object ルートの `emphasis_words` を受理し、同じ規則で検証する。
80
+
81
+ ## 5. style_preset の描画
82
+
83
+ 共有字幕カーネルは、`style_preset` を持つ `emphasis_words[]` が投影後の語へ当たった場合にだけ、
84
+ display cue へ `words[]` と `word_styles[]` を追加する。`words[]` は出力秒の `start` / `end`、本文
85
+ `text`、`display_lines` の行番号 `line` を持つ。`word_styles[]` は `words[]` の半開区間 `from` / `to`、
86
+ プリセット id `preset_id`、解決済み CSS 変数 `style_vars` を持つ。時間範囲が語の途中だけと重なる場合も、
87
+ その語全体へ丸める(含む側)。該当語が無い cue には両キーとも追加せず、従来の出力を変えない。
88
+
89
+ 描画 DOM は通常の語を `akari-caption__tok`、プリセット付きの語を
90
+ `akari-caption__tok akari-caption__tok--preset` とし、後者へ `data-emphasis-preset` と解決済み
91
+ `style_vars` のインライン CSS を付ける。shell プレビュー、Web プレビュー、render-cut、gpu-export の
92
+ 4 出口はこの同じ規則で描く。台本パネルは語 span の `data-emphasis-preset` を読み取れる形で残し、
93
+ プリセット色と薄い下線だけを表示する。既存の行テンプレチップは維持する。
94
+
95
+ `style_preset` の無いレコードは従来の `emotion` / `style_hint` 経路のままである。現状、語へ渡す
96
+ `style_vars` は color / font-size / font-weight / line-height / stroke 系だけであり、glow、shadow、
97
+ `letter_spacing`、`text_transform` は未対応とする。
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  lifecycle: implemented
3
3
  created: 2026-08-23
4
- updated: 2026-08-23
4
+ updated: 2026-09-12
5
5
  ---
6
6
 
7
7
  # 注釈ストローク永続表示契約
@@ -20,12 +20,24 @@ updated: 2026-08-23
20
20
  変更で座標は変わらない。
21
21
  - pointerup 後は従来のグロー・きらめき・600 ms フェードをそのまま再生し、その後段の静的
22
22
  ビットマップへ同じ正規化図形を残す。新しい録音セッションの開始時に前セッションの表示を
23
- クリアし、録音終了では消さない。
23
+ クリアし、録音終了では消さない。※ 2026-09-12 改訂(§1.1)
24
24
  - 描線 canvas は非描画モードで `pointer-events: none` とする。ペンまたは四角モードのドラッグ中
25
25
  だけ既存どおり入力面になる。
26
26
  - 注釈パネルの「描線を表示」チェックは既定 ON。OFF は残留描線と明示的に再表示した描線を隠し、
27
27
  データを削除しない。ON に戻すと保持した正規化座標から即時再描画する。
28
28
 
29
+ ### 1.1 表示の寿命(2026-09-12 追記)
30
+
31
+ - 描線はプレイヘッド近傍表示とする。録音中は `recT - recTEnd`、録音外の再表示では
32
+ `|playheadT - frame.timelineT|` を距離として、直近または近傍の複数描線だけを表示する。
33
+ - 表示規則の単一正本は `PEN_TUNING.visibleWindowSec`(既定 8 秒)と
34
+ `PEN_TUNING.fadeOutMs`(既定 1500 ms)である。時間窓内は不透明とし、窓を超えた描線は
35
+ `fadeOutMs` をかけて薄れて非表示になる。
36
+ - `fadeOutMs` は表示寿命のための値であり、pointerup 直後のきらめきと描き味を担う既存の
37
+ `fadeDurationMs`(600 ms)とは別物である。
38
+ - 録音停止時は画面上の表示プールをクリアするが、記録側の `strokes.json` は変更しない。
39
+ 録音済みセッションの描線は再表示できるため、手動のクリアボタンは設けない。
40
+
29
41
  ## 2. 既存セッションの読み出しと再表示
30
42
 
31
43
  `readReviewSessionStrokes({projectRootUri, sessionId})` は
@@ -0,0 +1,97 @@
1
+ ---
2
+ lifecycle: draft
3
+ created: 2026-09-12
4
+ updated: 2026-09-12
5
+ ---
6
+
7
+ # レビューセッション見返しビューア契約
8
+
9
+ - 日付: 2026-09-12
10
+ - 状態: draft
11
+ - 前提: `contract-2026-08-11-review-session-ui-events.md`、
12
+ `contract-2026-08-23-stroke-persistence.md`
13
+ - スコープ: 録音時計 `recT` を基準にした音声・出力プレビュー・描線・文字起こしの同期表示と、
14
+ 録音時点の `edit.snapshot.json` と現在の `edit.json` の差分表示
15
+
16
+ ## 0. 版と互換
17
+
18
+ 本機能は `review/sessions/s-NNNN/` の原本の形を変えず、すべて読むだけで扱う。欠けたファイル、
19
+ 壊れた行、未知フィールドは警告または情報なしへ縮退させ、既知の残りを表示する寛容リーダーとする。
20
+ 記録原本、manifest、edit.json の migration や書き戻しは行わない。
21
+
22
+ ## 1. `readReviewSessionBundle` 読み出し口
23
+
24
+ 入力は次のとおり。
25
+
26
+ | フィールド | 型 | 意味 |
27
+ |---|---|---|
28
+ | `projectRootUri` | `string` | ワークスペース内のプロジェクトルート URI |
29
+ | `sessionId` | `string` | `s-NNNN` 形式のセッション ID |
30
+
31
+ 出力は次のとおり。
32
+
33
+ | フィールド | 型 | 意味 |
34
+ |---|---|---|
35
+ | `sessionId` | `string` | 読み出したセッション ID |
36
+ | `audioUri` | `string \| null` | `audio.wav` の file URI。欠落時は `null` |
37
+ | `audioDurationSec` | `number` | WAV ヘッダから得た録音尺。読めなければ `0` |
38
+ | `events` | `ReviewSessionEvent[]` | 有効行を `recT` 昇順で安定ソートしたイベント |
39
+ | `strokes` | `ReviewStroke[]` | 既存の寛容な strokes リーダーが返す描線 |
40
+ | `transcript` | `ReviewSessionTranscriptSegment[] \| null` | 発話列。未コンパイル時は `null` |
41
+ | `proposals` | `ReviewSessionProposalSummary[] \| null` | 対象解決の表示用要約。欠落時は `null` |
42
+ | `editSnapshotText` | `string \| null` | 8 MiB 以下の snapshot 生テキスト |
43
+ | `warnings` | `string[]` | 読み飛ばした原本・行の説明 |
44
+
45
+ 入口の不正 ID、ワークスペース外、セッションディレクトリ不在だけは例外とする。それ以外の欠落・
46
+ 破損は残りを返し、原本へ書き込まない。
47
+
48
+ ## 2. `recT` から `timelineT` への写像
49
+
50
+ 状態は `{playing, anchorTimelineT, anchorRecT, rate}` とし、位置を次で求める。
51
+
52
+ `playing ? anchorTimelineT + (recT - anchorRecT) * rate : anchorTimelineT`
53
+
54
+ | イベント | anchor と状態の更新 |
55
+ |---|---|
56
+ | `start` | `timelineT` / `recT` を anchor、`playing` を記録値、`rate=1` |
57
+ | `play` | 先に現位置を求め、有効な `timelineT` または現位置を anchor、`playing=true` |
58
+ | `pause` | 有効な `timelineT` または現位置を anchor、`playing=false` |
59
+ | `seek` | `to` を timeline anchor、イベント `recT` を rec anchor にする |
60
+ | `rate` | 先に現位置を anchor にし、正の `value` を rate にする |
61
+ | `tick` | イベント `timelineT` / `recT` で anchor を打ち直す |
62
+ | `end` | 有効な `timelineT` または現位置を anchor、`playing=false` |
63
+
64
+ この意味論は `compile-review-session` の時刻写像と同一である。ビューアは `audio.currentTime` を
65
+ `recT` の正本とし、出力プレビューへの seek は既存の requestAnimationFrame 経路で間引く。
66
+
67
+ ## 3. 描線の再表示
68
+
69
+ 描線の寿命と薄れ方は `contract-2026-08-23-stroke-persistence.md` および
70
+ `PEN_TUNING.visibleWindowSec` を正本とする。ビューアはセッションの描線をプレビューへ attach し、
71
+ 録音プレイヘッドを動かし、閉じると detach するだけである。描画規則や原本は変更しない。
72
+
73
+ ## 4. 文字起こしと対象表示
74
+
75
+ `transcript.json` があれば発話単位で並べ、現在の `recT` に該当する発話を強調する。発話クリックは
76
+ その開始 `recT` へシークする。`compile-proposals.json` は発話と同じ index で突き合わせ、
77
+ `target`、`sourceT`、low confidence の要確認表示を添える。本票は人間が解決結果を目視確認する
78
+ 表示のみで、対象を修正する UI は次段とする。未コンパイル時の導線は定型文をコピーするだけで、
79
+ compile 自体を実行しない。
80
+
81
+ ## 5. `edit.snapshot.json` との差分
82
+
83
+ 両文書を `readInternalEdit` で読み、全 track の item と再帰的な children を ID で突き合わせる。
84
+ 表示する変化は追加、削除、`at` の移動、`duration` の尺変更、media source の `in/out` の素材区間変更の
85
+ 5 種である。1 item に複数の変化があれば別々に表示する。v0 / v1 snapshot は「旧形式のため差分を
86
+ 出せない」と明示し、migrate しない。
87
+
88
+ ## 6. 映像
89
+
90
+ 映像面には現在の `edit.json` の出力プレビューを使う。当時の素材や映像を探索・復元しない。
91
+
92
+ ## 7. 非目標
93
+
94
+ - audio、events、strokes、snapshot、transcript、proposals の書き換え
95
+ - compile の実行や文字起こし生成
96
+ - compile の対象解決や注釈内容の編集
97
+ - 当時の映像・素材の復元
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akari-video",
3
- "version": "0.1.62",
3
+ "version": "0.1.64",
4
4
  "description": "AKARI Video launcher CLI — start an AI-edited video project from any directory: scaffold, connection check, then hand over to Claude Code (or opencode). AKARI Video を opencode や Claude Code で、どのディレクトリからでも始めるための `akari` ランチャー CLI。接続確認(doctor)→ 未セットアップならプロジェクト雛形を作成 → AI エージェントを起動する。外部 npm 依存ゼロ(Node.js 組み込みモジュールのみ)。 [akari-video npm vendor: bin/akari.mjs is reference-only. These CLI entrypoints are not included in the akari-video npm package. Use `akari doctor --json` and run the path reported in `render_cut.path`. Full installations provide it in a monorepo checkout, ~/.akari/app, /Applications/AKARI Video.app/Contents/Resources/packages, or %LOCALAPPDATA%\\Programs\\@akari-videoshell\\resources\\packages.]",
5
5
  "type": "module",
6
6
  "files": [
@@ -42,15 +42,26 @@ item. Each source is probed once, and media finding paths include the source ID.
42
42
  warnings unless `--silence-error-seconds` promotes long intervals to errors.
43
43
  - `media.volume`: reports mean and maximum volume. Findings are warnings unless
44
44
  `--max-volume-error-db` promotes an over-limit maximum to an error.
45
+ - `media.source-range`: errors when a media item asks for a span the source does not have. Every
46
+ lane is covered (visual cuts, `bgm` / `narration` / `sfx` items, nested bag items) plus the v1
47
+ `audio.*` declarations, and the container duration is used so sources without an audio stream are
48
+ checked too. `source.in` at or beyond the duration and an effective `source.out` past the duration
49
+ are both errors; sources whose container duration is unavailable are skipped with a reason.
45
50
  - `media.audio-shorter-than-out`: warns for each visual media item whose effective source `out`
46
- exceeds that source's audio-stream duration. The message includes the missing duration.
51
+ exceeds that source's audio-stream duration while staying inside the container duration (the
52
+ source plays but its audio ends early). The message includes the missing duration. Items that run
53
+ past the container duration are reported by `media.source-range` instead.
47
54
  - `media.caption-silence-coverage`: warns when more than 30% of caption display time overlaps a
48
55
  silence interval of at least one second. `--caption-silence-warn-percent` changes the threshold.
49
56
  - `audio.narration.trim`: warns when a narration media item's `in` is at or beyond its audio-stream
50
- duration. Invalid or reversed narration `in`/`out` values are errors even without `--media`.
57
+ duration but still inside the container duration. Invalid or reversed narration `in`/`out` values
58
+ are errors even without `--media`; an `in` past the container duration is a `media.source-range`
59
+ error.
51
60
 
52
61
  Silence and volume checks are skipped for a source without an audio stream or when ffprobe cannot
53
62
  inspect it. Duration-dependent checks are skipped when the audio-stream duration is unavailable.
63
+ One ffprobe invocation per source path reads both the container duration and the first audio
64
+ stream's duration.
54
65
  Caption/silence coverage runs only when the captions can be associated with exactly one referenced
55
66
  visual source: either every caption declares the same `src`, or the timeline references a single
56
67
  visual source and captions do not contradict it. Missing, empty, or multi-source/ambiguous captions