akari-video 0.1.63 → 0.1.65
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/package.json +1 -1
- package/src/capture-command.mjs +10 -2
- package/src/repo-assets.mjs +2 -1
- package/vendor/.akari-capability-sources.json +1 -0
- package/vendor/docs/contract-2026-08-02-preview-parity.md +6 -0
- package/vendor/docs/contract-2026-08-11-review-session-ui-events.md +1 -0
- package/vendor/docs/contract-2026-08-23-captions-emphasis-words-v0.md +22 -2
- package/vendor/docs/contract-2026-08-23-stroke-persistence.md +14 -2
- package/vendor/docs/contract-2026-09-12-review-session-viewer.md +97 -0
- package/vendor/packages/akari-launcher/package.json +1 -1
- package/vendor/packages/edit-lint/src/edit-lint.mjs +10 -1
- package/vendor/packages/edit-store/lib/caption-display.d.ts +87 -0
- package/vendor/packages/edit-store/lib/caption-display.js +921 -125
- package/vendor/packages/edit-store/lib/caption-store.d.ts +18 -0
- package/vendor/packages/edit-store/lib/caption-store.js +200 -3
- package/vendor/packages/edit-store/lib/caption-window.d.ts +31 -0
- package/vendor/packages/edit-store/lib/caption-window.js +133 -1
- package/vendor/packages/edit-store/lib/cut-ranges.d.ts +2 -1
- package/vendor/packages/edit-store/lib/cut-ranges.js +27 -0
- package/vendor/packages/edit-store/lib/edit-v2.js +1 -1
- package/vendor/packages/edit-store/lib/generated/textstyle-catalog.js +1 -1
- package/vendor/packages/edit-store/lib/history-store.d.ts +29 -0
- package/vendor/packages/edit-store/lib/history-store.js +186 -0
- package/vendor/packages/edit-store/lib/internal-model.d.ts +2 -0
- package/vendor/packages/edit-store/lib/internal-model.js +60 -8
- package/vendor/packages/edit-store/lib/webview-kernel.d.ts +1 -1
- package/vendor/packages/edit-store/lib/webview-kernel.js +402 -11
- package/vendor/packages/schemas/bin/validate-captions.mjs +23 -4
- package/vendor/packages/schemas/bin/validate-edit.mjs +12 -0
- package/vendor/packages/schemas/captions.schema.json +16 -5
- package/vendor/packages/schemas/edit.schema.json +12 -0
- package/vendor/packages/schemas/fixtures/review/valid-session-fields/review.json +6 -0
- package/vendor/packages/schemas/review.schema.json +27 -0
- package/vendor/packages/schemas/test/edit-cut-reason.test.mjs +81 -0
- package/vendor/packages/schemas/test/edit-v2-schema.test.mjs +28 -0
- package/vendor/packages/schemas/test/validate-captions.test.mjs +62 -0
- package/vendor/skills/analyze-footage/bin/transcribe-cloud.mjs +9 -2
- package/vendor/skills/analyze-footage/test/fixtures/scribe-speakers.json +8 -0
- package/vendor/skills/analyze-footage/test/normalize-scribe.test.mjs +19 -0
- package/vendor/skills/compile-review-session/bin/compile-review-session.mjs +9 -2
- package/vendor/skills/compile-review-session/bin/core/compiler.mjs +3 -1
- package/vendor/skills/compile-review-session/bin/core/install-root.mjs +125 -0
- package/vendor/skills/compile-review-session/bin/core/time-mapping.mjs +138 -11
- package/vendor/skills/compile-review-session/bin/core/transcription.mjs +117 -40
- package/vendor/skills/compile-review-session/compilation-rules.md +3 -0
- package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0010/audio.wav +0 -0
- package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0010/edit.snapshot.json +45 -0
- package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0010/events.jsonl +2 -0
- package/vendor/skills/compile-review-session/dev-fixtures/fixture-project/review/sessions/s-0010/session.json +11 -0
- package/vendor/skills/compile-review-session/test/compiler.test.mjs +233 -0
- package/vendor/skills/compile-review-session/test/install-root.test.mjs +167 -0
- 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.
|
|
3
|
+
"version": "0.1.65",
|
|
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": {
|
package/src/capture-command.mjs
CHANGED
|
@@ -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
|
-
|
|
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
|
|
package/src/repo-assets.mjs
CHANGED
|
@@ -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
|
-
|
|
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",
|
|
@@ -137,6 +137,12 @@ finalFrameNumber **239**、lookahead hits **8**を要求する。
|
|
|
137
137
|
shell のプレビューでは DOM 層として提示し、書き出しでは同じ DOM 規約から overlay sheet を構成する。
|
|
138
138
|
器専用の字幕 HTML や出口専用の再レイアウトを持たない。
|
|
139
139
|
|
|
140
|
+
行用 `style_vars` は `packages/edit-store/src/caption-display.ts` の
|
|
141
|
+
`resolveCaptionLineStyleVars` / `mergeCaptionLineTextStyles` をカーネル単一定義とし、shell、Web UI、
|
|
142
|
+
render-cut、`display_policy` の 4 面が同じ関数を呼ぶ。`display_policy` 経路の stroke も
|
|
143
|
+
`-webkit-text-stroke` として `width_px × 2` を出し、`paint-order: stroke fill` で描く
|
|
144
|
+
(2026-09-13 裁定)。
|
|
145
|
+
|
|
140
146
|
active cue の判定は両プレビューとも**出力秒**で行う。source 秒の cue(`time_domain: "source"` と未宣言の
|
|
141
147
|
legacy)は共有カーネル `packages/edit-store/src/caption-clock.ts` の `normalizeCaptionClock` が cut map
|
|
142
148
|
で出力秒へ射影し、削除区間をまたぐ cue は 1 本ずつに分割する(`<id>-output-<n>`、元 id は
|
|
@@ -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-
|
|
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.
|
|
3
|
+
"version": "0.1.65",
|
|
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": [
|
|
@@ -4086,7 +4086,7 @@ function validateCaptions(captions, edit, analysis, findings, paths, cutsEndSeco
|
|
|
4086
4086
|
continue;
|
|
4087
4087
|
}
|
|
4088
4088
|
const required = ["id", "start", "end", "text", "speaker", "sourceRef", "edited"];
|
|
4089
|
-
const optional = ["src", "time_domain", "words", "unrecognized", "style", "display_text", "display_fragments", "style_preset", "text_style"];
|
|
4089
|
+
const optional = ["src", "time_domain", "words", "unrecognized", "style", "display_text", "display_fragments", "display_timing", "style_preset", "text_style"];
|
|
4090
4090
|
for (const field of required) {
|
|
4091
4091
|
if (!Object.hasOwn(caption, field)) {
|
|
4092
4092
|
captionFinding(findings, "captions.schema", `${field} is required`, itemPath);
|
|
@@ -4180,6 +4180,10 @@ function validateCaptions(captions, edit, analysis, findings, paths, cutsEndSeco
|
|
|
4180
4180
|
if (Object.hasOwn(caption, "display_fragments") && !Array.isArray(caption.display_fragments)) {
|
|
4181
4181
|
captionFinding(findings, "captions.schema", "display_fragments must be an array when present", itemPath);
|
|
4182
4182
|
}
|
|
4183
|
+
if (Object.hasOwn(caption, "display_timing")
|
|
4184
|
+
&& caption.display_timing !== "full" && caption.display_timing !== "speech-tight") {
|
|
4185
|
+
captionFinding(findings, "captions.schema", 'display_timing must be "full" or "speech-tight" when present', itemPath);
|
|
4186
|
+
}
|
|
4183
4187
|
if (Object.hasOwn(caption, "style_preset")) {
|
|
4184
4188
|
if (typeof caption.style_preset !== "string"
|
|
4185
4189
|
|| !/^[a-z0-9][a-z0-9-]*$/.test(caption.style_preset)) {
|
|
@@ -4974,6 +4978,8 @@ const REVIEW_DOC_TARGET_PATTERN = /^doc:(.+)#(.+)$/;
|
|
|
4974
4978
|
const REVIEW_IMAGE_TARGET_PATTERN = /^image:(.+)$/;
|
|
4975
4979
|
const REVIEW_CANVAS_TARGET_PATTERN = /^canvas:(c-\d{4,})$/;
|
|
4976
4980
|
const REVIEW_REQUIRED_FIELDS = ["id", "createdAt", "sourceT", "text", "input", "status"];
|
|
4981
|
+
// review.schema.json の annotation.properties と同じ集合を保つ(issue #73: compile-review-session が
|
|
4982
|
+
// 正式に書く strokeRefs / transcript / session がここに無く、正規の生成物に warning が出ていた)。
|
|
4977
4983
|
const REVIEW_OPTIONAL_FIELDS = [
|
|
4978
4984
|
"src",
|
|
4979
4985
|
"sourceRange",
|
|
@@ -4982,10 +4988,13 @@ const REVIEW_OPTIONAL_FIELDS = [
|
|
|
4982
4988
|
"targetKind",
|
|
4983
4989
|
"region",
|
|
4984
4990
|
"strokes",
|
|
4991
|
+
"strokeRefs",
|
|
4985
4992
|
"refs",
|
|
4986
4993
|
"insertPosition",
|
|
4987
4994
|
"intent",
|
|
4988
4995
|
"audio",
|
|
4996
|
+
"transcript",
|
|
4997
|
+
"session",
|
|
4989
4998
|
"poses",
|
|
4990
4999
|
"response",
|
|
4991
5000
|
];
|
|
@@ -20,6 +20,8 @@ export interface CaptionDisplayPolicy {
|
|
|
20
20
|
max_line_units: number;
|
|
21
21
|
minimum_fragment_duration_seconds: number;
|
|
22
22
|
locale: string;
|
|
23
|
+
lines?: number;
|
|
24
|
+
wrap?: 'multi' | 'fold';
|
|
23
25
|
break_hints?: CaptionBreakHints;
|
|
24
26
|
}
|
|
25
27
|
export interface CaptionDisplayCue {
|
|
@@ -33,11 +35,31 @@ export interface CaptionDisplayCue {
|
|
|
33
35
|
start: number;
|
|
34
36
|
end: number;
|
|
35
37
|
text: string;
|
|
38
|
+
display_lines?: string[];
|
|
36
39
|
units: number;
|
|
37
40
|
line_override: boolean;
|
|
38
41
|
text_style?: Record<string, unknown>;
|
|
39
42
|
style_vars?: Record<string, string>;
|
|
40
43
|
layout?: ResolvedCaptionLayout;
|
|
44
|
+
words?: CaptionDisplayWord[];
|
|
45
|
+
word_styles?: CaptionDisplayWordStyle[];
|
|
46
|
+
overflow?: CaptionDisplayOverflow;
|
|
47
|
+
}
|
|
48
|
+
export interface CaptionDisplayOverflow {
|
|
49
|
+
code: 'NO_WORD_BOUNDARY_SPLIT' | 'INVALID_MANUAL_FRAGMENTS';
|
|
50
|
+
units: number;
|
|
51
|
+
}
|
|
52
|
+
export interface CaptionDisplayWord {
|
|
53
|
+
start: number;
|
|
54
|
+
end: number;
|
|
55
|
+
text: string;
|
|
56
|
+
line: number;
|
|
57
|
+
}
|
|
58
|
+
export interface CaptionDisplayWordStyle {
|
|
59
|
+
from: number;
|
|
60
|
+
to: number;
|
|
61
|
+
preset_id: string;
|
|
62
|
+
style_vars: Record<string, string>;
|
|
41
63
|
}
|
|
42
64
|
export interface CaptionBoundaryProjection {
|
|
43
65
|
source_cue_id: string;
|
|
@@ -72,11 +94,42 @@ export interface ResolvedCaptionLayout {
|
|
|
72
94
|
scale: number;
|
|
73
95
|
}
|
|
74
96
|
type UnknownRecord = Record<string, any>;
|
|
97
|
+
export interface CaptionOccurrence {
|
|
98
|
+
source_cue_id: string;
|
|
99
|
+
src: string | null;
|
|
100
|
+
cut_index: number;
|
|
101
|
+
caption_input_index: number;
|
|
102
|
+
source_start: number;
|
|
103
|
+
source_end: number;
|
|
104
|
+
start: number;
|
|
105
|
+
end: number;
|
|
106
|
+
track: number;
|
|
107
|
+
text: string;
|
|
108
|
+
display_fragments?: string[];
|
|
109
|
+
occurrence_index?: number;
|
|
110
|
+
text_style?: UnknownRecord;
|
|
111
|
+
time_offset?: number;
|
|
112
|
+
time_scale?: number;
|
|
113
|
+
}
|
|
114
|
+
export interface ProjectedCaptionWords {
|
|
115
|
+
displayText: string;
|
|
116
|
+
words: UnknownRecord[] | undefined;
|
|
117
|
+
changed: boolean;
|
|
118
|
+
renderable: boolean;
|
|
119
|
+
}
|
|
75
120
|
export declare class CaptionDisplayError extends Error {
|
|
76
121
|
readonly code: string;
|
|
77
122
|
constructor(code: string, message: string);
|
|
78
123
|
}
|
|
79
124
|
export declare function measureCaptionUnits(text: string): number;
|
|
125
|
+
export interface CaptionWordSpan {
|
|
126
|
+
start: number;
|
|
127
|
+
end: number;
|
|
128
|
+
wordLike: boolean;
|
|
129
|
+
}
|
|
130
|
+
/** 自動分割で採用してはいけない、Latin/数字または Segmenter 語の内部境界を判定する。 */
|
|
131
|
+
export declare function captionBreakBoundaryBlocked(text: string, boundary: number, wordSpans: readonly CaptionWordSpan[]): boolean;
|
|
132
|
+
export declare function joinCaptionLines(lines: string[], locale: string): string;
|
|
80
133
|
export declare function validateCaptionDisplayPolicy(value: unknown): CaptionDisplayPolicy;
|
|
81
134
|
export declare function resolveCaptionDisplay(captionsRoot: unknown, edit: UnknownRecord, options?: {
|
|
82
135
|
output?: {
|
|
@@ -91,16 +144,39 @@ export declare function resolveCaptionDisplay(captionsRoot: unknown, edit: Unkno
|
|
|
91
144
|
* conceal an invalid default (or vice versa).
|
|
92
145
|
*/
|
|
93
146
|
export declare function validateCaptionTextStyle(value: unknown, label?: string): UnknownRecord;
|
|
147
|
+
/**
|
|
148
|
+
* `captions.json` は変更せず、keep cut から外れた語だけを描画用の本文と words から除く。
|
|
149
|
+
* どれかの cut と一部でも交差する語は残す(語の途中で切った場合に欠落させない)。
|
|
150
|
+
*/
|
|
151
|
+
export declare function projectCaptionWords(caption: UnknownRecord, cuts: UnknownRecord[]): ProjectedCaptionWords;
|
|
152
|
+
/**
|
|
153
|
+
* 同じ source cue が同じ出力区間へ複数回射影された場合、下→上の trackOrder で
|
|
154
|
+
* 最後に描かれる occurrence だけを残す。部分重複は境界で分割する。
|
|
155
|
+
*/
|
|
156
|
+
export declare function dedupeCaptionOccurrences<T extends {
|
|
157
|
+
source_cue_id: string;
|
|
158
|
+
start: number;
|
|
159
|
+
end: number;
|
|
160
|
+
track: number;
|
|
161
|
+
source_start?: number;
|
|
162
|
+
source_end?: number;
|
|
163
|
+
}>(occurrences: readonly T[], trackOrder: readonly number[]): T[];
|
|
94
164
|
export declare function splitCaptionFragments(text: string, policy: CaptionDisplayPolicy): {
|
|
95
165
|
fragments: string[];
|
|
96
166
|
boundaries: number[];
|
|
167
|
+
overflow?: CaptionDisplayOverflow;
|
|
97
168
|
};
|
|
169
|
+
export declare function foldCaptionLines(text: string, maxLineUnits: number, lines: number, locale?: string): string[];
|
|
98
170
|
export declare function scheduleCaptionFragments(start: number, end: number, fragments: string[], minimumSeconds: number): Array<{
|
|
99
171
|
start: number;
|
|
100
172
|
end: number;
|
|
101
173
|
text: string;
|
|
102
174
|
}>;
|
|
103
175
|
export declare function mergeCaptionDisplayStyles(base: unknown, override: unknown): UnknownRecord | undefined;
|
|
176
|
+
/** Merge the snake_case captions.json line style vocabulary used by every renderer. */
|
|
177
|
+
export declare function mergeCaptionLineTextStyles(base: unknown, override: unknown): UnknownRecord | null;
|
|
178
|
+
export declare function usesPercentageBackground(background: unknown): boolean;
|
|
179
|
+
export declare function usesExtendedPerLineBackground(background: unknown): boolean;
|
|
104
180
|
/**
|
|
105
181
|
* zone 方式の px 系フィールドに掛ける scale(issue #40 §2)。`reference_height_px` が無ければ 1
|
|
106
182
|
* (既存出力はバイト同一)。あれば output.height / reference_height_px — 基準は高さ(文字サイズは
|
|
@@ -127,6 +203,11 @@ export declare function scaleCaptionPx(value: number, scale: number): number;
|
|
|
127
203
|
* 不正な anchor / vertical_align は未宣言として無視する(書き込み時検証済みが前提の防御)。
|
|
128
204
|
*/
|
|
129
205
|
export declare function captionAnchorPositionVars(anchorValue: unknown, positionValue: unknown, verticalAlignValue: unknown): Record<string, string>;
|
|
206
|
+
/** Resolve the complete snake_case captions.json line style vocabulary to CSS variables. */
|
|
207
|
+
export declare function resolveCaptionLineStyleVars(style: UnknownRecord | null | undefined, output: {
|
|
208
|
+
width: number;
|
|
209
|
+
height: number;
|
|
210
|
+
} | undefined): Record<string, string>;
|
|
130
211
|
export declare function resolveCaptionStyleForOutput(style: UnknownRecord, output: {
|
|
131
212
|
width: number;
|
|
132
213
|
height: number;
|
|
@@ -134,5 +215,11 @@ export declare function resolveCaptionStyleForOutput(style: UnknownRecord, outpu
|
|
|
134
215
|
vars: Record<string, string>;
|
|
135
216
|
layout?: ResolvedCaptionLayout;
|
|
136
217
|
};
|
|
218
|
+
export declare function resolveCaptionWordStyleVars(style: UnknownRecord, output: {
|
|
219
|
+
width: number;
|
|
220
|
+
height: number;
|
|
221
|
+
} | undefined): Record<string, string>;
|
|
222
|
+
export declare function captionTextShadowValue(shadow: unknown, glow: unknown, scale?: number): string | null;
|
|
223
|
+
export declare function colorWithOpacity(color: string, explicitOpacity?: number): string;
|
|
137
224
|
export declare function formatCssNumber(value: number): string;
|
|
138
225
|
export {};
|