akari-video 0.1.7 → 0.1.9
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/vendor/.akari-capability-sources.json +8 -0
- package/vendor/docs/contract-2026-08-02-setup-remote-v0.md +64 -5
- package/vendor/docs/contract-2026-08-11-review-session-ui-events.md +19 -7
- package/vendor/docs/contract-2026-08-12-chat-approval-v0.md +99 -0
- package/vendor/docs/contract-2026-08-12-color-range-normalization-v0.md +59 -0
- package/vendor/docs/contract-2026-08-12-region-filter-layer-v0.md +98 -0
- package/vendor/packages/akari-launcher/package.json +1 -1
- package/vendor/packages/analysis-report/render-analysis-report.mjs +15 -0
- package/vendor/packages/chat-bridge/package.json +14 -0
- package/vendor/packages/chat-bridge/src/telegram.mjs +272 -0
- package/vendor/packages/decision-cards/report-helper.mjs +98 -6
- package/vendor/packages/overlay-runtime/README.md +48 -16
- package/vendor/packages/schemas/analysis.schema.json +9 -0
- package/vendor/packages/schemas/bin/validate-asset.mjs +51 -1
- package/vendor/packages/schemas/bin/validate-connections.mjs +1 -1
- package/vendor/packages/schemas/bin/validate-edit.mjs +41 -3
- package/vendor/packages/schemas/connections.schema.json +1 -1
- package/vendor/packages/schemas/edit.schema.json +59 -3
- package/vendor/packages/schemas/examples/connections-v0-invalid-kind/connections.json +33 -0
- package/vendor/packages/schemas/examples/connections-v0-notify-valid/connections.json +36 -0
- package/vendor/packages/schemas/examples/edit-layers-filter-invalid-lut-missing-id/edit.json +15 -0
- package/vendor/packages/schemas/examples/edit-layers-filter-invalid-missing-filter/edit.json +14 -0
- package/vendor/packages/schemas/examples/edit-layers-filter-invalid-src-present/edit.json +16 -0
- package/vendor/packages/schemas/examples/edit-layers-filter-invalid-unknown-type/edit.json +15 -0
- package/vendor/packages/schemas/examples/edit-layers-filter-invert-valid/edit.json +15 -0
- package/vendor/packages/schemas/examples/edit-layers-filter-lut-valid/edit.json +15 -0
- package/vendor/packages/schemas/examples/edit-layers-filter-saturation-valid/edit.json +19 -0
- package/vendor/packages/schemas/test/analysis-face-contour-pointer.test.mjs +19 -0
- package/vendor/packages/schemas/test/edit-layer-filter-schema.test.mjs +65 -0
- package/vendor/packages/schemas/test/fixtures/asset/invalid-scene3d-model-missing-glb/scene3d/hero-missing-glb/fragment.html +1 -0
- package/vendor/packages/schemas/test/fixtures/asset/invalid-scene3d-model-missing-glb/scene3d/hero-missing-glb/meta.json +23 -0
- package/vendor/packages/schemas/test/fixtures/asset/invalid-scene3d-model-missing-glb/scene3d/hero-missing-glb/preview.png +0 -0
- package/vendor/packages/schemas/test/fixtures/asset/invalid-scene3d-neither/scene3d/hero-neither/fragment.html +1 -0
- package/vendor/packages/schemas/test/fixtures/asset/invalid-scene3d-neither/scene3d/hero-neither/meta.json +23 -0
- package/vendor/packages/schemas/test/fixtures/asset/invalid-scene3d-neither/scene3d/hero-neither/preview.png +0 -0
- package/vendor/packages/schemas/test/fixtures/asset/valid-scene3d-texts-only/scene3d/hero-texts-only/fragment.html +1 -0
- package/vendor/packages/schemas/test/fixtures/asset/valid-scene3d-texts-only/scene3d/hero-texts-only/meta.json +23 -0
- package/vendor/packages/schemas/test/fixtures/asset/valid-scene3d-texts-only/scene3d/hero-texts-only/preview.png +0 -0
- package/vendor/packages/schemas/test/validate-asset.test.mjs +19 -0
- package/vendor/packages/schemas/test/validate-connections.test.mjs +15 -0
- package/vendor/skills/analyze-footage/bin/vision-tracks/vision-tracks-helper.swift +24 -8
- package/vendor/skills/analyze-footage/bin/vision-tracks/vision-tracks.mjs +1 -0
- package/vendor/skills/analyze-footage/references/vision-tracks.schema.json +14 -2
- package/vendor/skills/analyze-footage/test/fixtures/vision-tracks/dummy-helper.mjs +3 -0
- package/vendor/skills/analyze-footage/test/vision-tracks-assembly.test.mjs +5 -1
- package/vendor/skills/analyze-footage/test/vision-tracks-schema.test.mjs +11 -0
- package/vendor/skills/compile-review-session/bin/compile-review-session.mjs +25 -0
- package/vendor/skills/compile-review-session/bin/core/compiler.mjs +6 -2
- package/vendor/skills/compile-review-session/test/compiler.test.mjs +117 -0
- package/vendor/skills/overlay-authoring/3d.md +204 -1
- package/vendor/skills/setup-chat-approval/SKILL.md +41 -0
- package/vendor/skills/setup-chat-approval/bin/doctor.mjs +132 -0
- package/vendor/skills/setup-chat-approval/bin/find-chat-id.mjs +68 -0
- package/vendor/skills/setup-chat-approval/setup-token.md +70 -0
- package/vendor/skills/setup-chat-approval/smoke-test.md +52 -0
- package/vendor/skills/setup-remote/SKILL.md +6 -3
- package/vendor/skills/setup-remote/serve-preview.md +26 -2
- package/vendor/skills/setup-remote/taildrop-inbox.md +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akari-video",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
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": {
|
|
@@ -33,6 +33,9 @@
|
|
|
33
33
|
"docs/contract-2026-08-05-fx-v0.md",
|
|
34
34
|
"docs/contract-2026-08-11-analysis-vision-tracks-v0.md",
|
|
35
35
|
"docs/contract-2026-08-11-review-session-ui-events.md",
|
|
36
|
+
"docs/contract-2026-08-12-chat-approval-v0.md",
|
|
37
|
+
"docs/contract-2026-08-12-color-range-normalization-v0.md",
|
|
38
|
+
"docs/contract-2026-08-12-region-filter-layer-v0.md",
|
|
36
39
|
"packages/akari-launcher/bin/akari.mjs",
|
|
37
40
|
"packages/akari-launcher/package.json",
|
|
38
41
|
"packages/akari-launcher/README.md",
|
|
@@ -51,6 +54,8 @@
|
|
|
51
54
|
"packages/bake-layer/bin/bake-layer.mjs",
|
|
52
55
|
"packages/bake-layer/package.json",
|
|
53
56
|
"packages/bake-layer/README.md",
|
|
57
|
+
"packages/chat-bridge/package.json",
|
|
58
|
+
"packages/chat-bridge/src/telegram.mjs",
|
|
54
59
|
"packages/creator-root/package.json",
|
|
55
60
|
"packages/decision-cards/package.json",
|
|
56
61
|
"packages/decision-cards/README.md",
|
|
@@ -158,6 +163,9 @@
|
|
|
158
163
|
"skills/setup-audio-library/gallery.md",
|
|
159
164
|
"skills/setup-audio-library/SKILL.md",
|
|
160
165
|
"skills/setup-audio-library/store-unlock.md",
|
|
166
|
+
"skills/setup-chat-approval/setup-token.md",
|
|
167
|
+
"skills/setup-chat-approval/SKILL.md",
|
|
168
|
+
"skills/setup-chat-approval/smoke-test.md",
|
|
161
169
|
"skills/setup-library/fetch-and-validate.md",
|
|
162
170
|
"skills/setup-library/SKILL.md",
|
|
163
171
|
"skills/setup-library/starter-pack.md",
|
|
@@ -25,7 +25,7 @@ OK / 差し戻しを言う」だけ — その閲覧と素材の受け渡しを
|
|
|
25
25
|
|
|
26
26
|
| 論点 | 決定 |
|
|
27
27
|
|---|---|
|
|
28
|
-
| 手段 | **Tailscale**(tailnet 限定)。閲覧 = `tailscale serve`
|
|
28
|
+
| 手段 | **Tailscale**(tailnet 限定)。閲覧 = `tailscale serve` でプレビューサーバーと承認レポートヘルパーを tailnet 限定 HTTPS 化。素材 = **Taildrop**(共有シートからデバイス直送。クラウド不経由・実用上サイズ無制限・画質劣化なし) |
|
|
29
29
|
| 不採用 / 保留 | Cloudflare Tunnel + Access(tailnet 外の人への共有が要件になったときの**別契約**。「公開してからゲートで守る」構造は既定にしない)。Cloudflare Pages(レポートはローカル随時生成のため噛み合わない) |
|
|
30
30
|
| 素材搬送路の優先順位 | **Taildrop(v0 で実装)** → Dropbox カメラアップロード → iCloud 写真 → Google Drive(順次。v0 では選択肢として提示のみ)。Google フォトは対象外(Library API 制限により自動取得不可) |
|
|
31
31
|
| 対応 OS | macOS / Windows 両対応を前提に書く(Tailscale / Taildrop とも両対応。手順の分岐は SKILL.md 側) |
|
|
@@ -37,7 +37,17 @@ OK / 差し戻しを言う」だけ — その閲覧と素材の受け渡しを
|
|
|
37
37
|
2. **導入ガイド — 人間手番の受け渡し**: インストーラーの sudo・GUI ログイン・スマホ側アプリ導入は
|
|
38
38
|
**自動化しない**(macOS の cask は .pkg で sudo 対話必須 — 実測済み)。スキルは
|
|
39
39
|
「ここはあなたの番」を明確に指示 → 完了を doctor で確認 → 次へ進む、を繰り返す構造とする
|
|
40
|
-
3. **serve 設定**: `tailscale serve`
|
|
40
|
+
3. **serve 設定**: `tailscale serve` で許可リスト(§3)の 2 件を tailnet 限定 HTTPS URL にする。
|
|
41
|
+
外部から見える口を安定させるため、**外部ポートを固定し内部ポートを写像する**形を既定とする:
|
|
42
|
+
|
|
43
|
+
| 外部 | 内部 | 中身 |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `https://<host>.ts.net/` | 4567 | プレビューサーバー |
|
|
46
|
+
| `https://<host>.ts.net:8443/` | ヘルパーの動的ポート | 承認レポート + `decisions.json` |
|
|
47
|
+
|
|
48
|
+
レポートヘルパーの内部ポートは起動ごとに変わりうるが、外部 URL は固定される(チャットに
|
|
49
|
+
貼ったリンクが起動のたびに死なない)。パス分岐(`--set-path /report`)はプレフィックス
|
|
50
|
+
除去の挙動を実測してから選択肢に加える — 未実測の間は既定にしない
|
|
41
51
|
4. **Taildrop 受信設定**: 受信先フォルダを固定し、作業場の `inbox/` へ接続する
|
|
42
52
|
(直接指定できる場合は直接、できない場合は受信箱 → `inbox/` への移送手順を案内)
|
|
43
53
|
5. **疎通確認**: 別デバイスから (a) serve URL が開ける (b) テストファイルを Taildrop 送信して
|
|
@@ -47,7 +57,13 @@ OK / 差し戻しを言う」だけ — その閲覧と素材の受け渡しを
|
|
|
47
57
|
|
|
48
58
|
- 既定は **tailnet 限定のみ**。公開インターネットへ出す `tailscale funnel` は**既定で使わない・
|
|
49
59
|
提案もしない**。ユーザーが明示的に要求した場合のみ、リスク説明 + 明示承認を経て扱う
|
|
50
|
-
- serve
|
|
60
|
+
- serve してよい対象は**次の許可リスト 2 件に限る**(2026-08-12 拡張):
|
|
61
|
+
- (a) **プレビューサーバー**(`akari --preview`、既定 4567)
|
|
62
|
+
- (b) **decision-cards レポートヘルパー**(`packages/decision-cards/report-helper.mjs`。
|
|
63
|
+
承認レポートの配信と `decisions.json` の read / write / commit を担う。`127.0.0.1` バインド)
|
|
64
|
+
|
|
65
|
+
これ以外のポート・アプリ・ファイルシステムは serve しない。許可リストを増やすときは
|
|
66
|
+
**本契約を改訂してから**行う(スキル側の判断で足さない)
|
|
51
67
|
- secrets を作業場・プロジェクトに書かない(creator-root v1 の原則。Tailscale の認証情報は
|
|
52
68
|
Tailscale 側が管理し、スキルは一切保持しない)
|
|
53
69
|
- スキルが勝手にインストールを完遂しない(§2-2 の人間手番)。ネットワーク設定の変更は
|
|
@@ -68,8 +84,9 @@ OK / 差し戻しを言う」だけ — その閲覧と素材の受け渡しを
|
|
|
68
84
|
|
|
69
85
|
- **L0**: SKILL.md の体裁・スキル lint が通る
|
|
70
86
|
- **L1**: doctor が 3 状態(未導入 / 未ログイン / 構成済み)を正しく判定する
|
|
71
|
-
- **L2**: 実機スモーク — 別デバイスから serve URL が開ける
|
|
72
|
-
`
|
|
87
|
+
- **L2**: 実機スモーク — 別デバイスから (a) プレビューの serve URL が開ける
|
|
88
|
+
(b) 承認レポートを開いて決定を保存 → `decisions.json` が実際に更新される
|
|
89
|
+
(c) Taildrop のテストファイルが `inbox/` に現れる(§2-5 の疎通確認そのもの)
|
|
73
90
|
|
|
74
91
|
## 6. 将来(非スコープの明示)
|
|
75
92
|
|
|
@@ -79,3 +96,45 @@ OK / 差し戻しを言う」だけ — その閲覧と素材の受け渡しを
|
|
|
79
96
|
- tailnet 外への共有(クライアント・協力者にブラウザだけで見せる): Cloudflare Tunnel +
|
|
80
97
|
Access(One-time PIN)系の別契約
|
|
81
98
|
- `inbox/` からの自動素材選択規約(直近 N 件)と create-project / analyze-footage への自動接続
|
|
99
|
+
|
|
100
|
+
## 7. L2 実測記録(2026-08-12・オーナー実機 iPhone + macOS)
|
|
101
|
+
|
|
102
|
+
**通った項目**:
|
|
103
|
+
|
|
104
|
+
| 検証 | 結果 |
|
|
105
|
+
|---|---|
|
|
106
|
+
| 別デバイスからのプレビュー閲覧 | ✓ tailnet 経由で表示。体感速度は「十分すぎる」(WireGuard 直結のため) |
|
|
107
|
+
| **レポート内に埋めた動画の再生** | ✓ iOS 実機で再生・**シーク成功**(H.264 640x360 / 6 秒) |
|
|
108
|
+
| Taildrop 着弾 | ✓ 受信先の実パス = **`~/Downloads/`**(macOS GUI 版・実測で確定) |
|
|
109
|
+
| Taildrop の無劣化性 | ✓ 92MB / HEVC / 1180x2556 / 60fps / **15.7Mbps のまま**再エンコードなし |
|
|
110
|
+
| Taildrop → 作業場 `inbox/` | ✓ **移送運用**で接続(`~/Akari/inbox/`)。macOS スタンドアロン版は受信先を設定変更できないため、直接指定ではなく移送を採る(§2-4 の想定どおり) |
|
|
111
|
+
| **承認の往復(`decisions.json`)** | ✓ スマホのタップが Mac のファイルへ書き戻ることを実測。単選カード(`thumbnail`: 既定 → 別候補)・整数スライダ(`direction.intensity`: 50 → 75)・**確定(`completedAt` 記入)** の 3 経路が通過。`byDefault: false` / `answeredAt` も期待どおり更新され、ファイルは `0600` を維持 |
|
|
112
|
+
|
|
113
|
+
- Taildrop の実測は「チャット添付は搬送路として筋が悪い」(§非スコープの根拠)を裏づけた —
|
|
114
|
+
同じ 92MB は Telegram Bot API 標準(受信 20MB)では原理的に通らない
|
|
115
|
+
- 受信物が HEVC だった点は、プレビューサーバー側の H.264 自動プロキシ層が実運用で必要になることの実例
|
|
116
|
+
|
|
117
|
+
**未達の項目(L2 は未クローズ)**:
|
|
118
|
+
|
|
119
|
+
| 未達 | 状況 |
|
|
120
|
+
|---|---|
|
|
121
|
+
| HTTPS | **`tailscale serve` の TLS が未成立**。上記の実測は tailnet 内の平文 HTTP で代替した(WireGuard 内側のため機密性は保たれるが、secure context を要する機能は使えない)。**平文 HTTP を既定にはしない** |
|
|
122
|
+
|
|
123
|
+
**HTTPS 失敗の切り分け結果(2026-08-12)** — スキル側・serve 設定側の不備ではないと確定:
|
|
124
|
+
|
|
125
|
+
- tailnet で HTTPS は有効(`tailscale status --json` の `CertDomains` に当該ドメインあり)
|
|
126
|
+
- serve の設定自体は正常(同じ経路が平文 HTTP では 200 / 0.28 秒で応答する)
|
|
127
|
+
- CAA は発行を許可している(`ts.net` に `issue "letsencrypt.org"`)
|
|
128
|
+
- Let's Encrypt の注文が毎回 `status: invalid`(注文 ID は毎回新規 = レート制限ではなく検証失敗)
|
|
129
|
+
- **`_acme-challenge.<host>.<tailnet>.ts.net` に使い捨て TXT が 5 件累積**していた。
|
|
130
|
+
DNS-01 の検証失敗と符合する(現行トークンが正しく公開されていない疑い)
|
|
131
|
+
- → **tailnet 側(Tailscale の DNS / 制御プレーン)の問題**。再試行を重ねても TXT が増えるだけで
|
|
132
|
+
好転しないため、打ち切って次の一手に回す。候補: (a) マシン名を変更して
|
|
133
|
+
`_acme-challenge` の名前ごと作り直す(serve URL が変わる)(b) Tailscale サポートに問い合わせる
|
|
134
|
+
|
|
135
|
+
## 8. 改訂履歴
|
|
136
|
+
|
|
137
|
+
| 日付 | 変更 | 理由 |
|
|
138
|
+
|---|---|---|
|
|
139
|
+
| 2026-08-02 | v0 初版 | — |
|
|
140
|
+
| 2026-08-12 | §3 serve 許可リストを 1 件 → 2 件へ拡張(decision-cards レポートヘルパーを追加)。§2-3 に外部ポート写像を明記。§5 L2 に承認往復の実測を追加 | 元のスコープ(§0「レポートを見て OK / 差し戻しを言う」)は最初から承認を含んでいたが、ハードルールが `serve = プレビューのみ` と狭すぎ、**承認レポートを配信する経路が契約上ふさがっていた**。スコープの拡大ではなくスコープとハードルールの不整合の是正 |
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
| `timeline:cut:<n>` | タイムラインのカット(cuts[] index) | `timeline:cut:3` |
|
|
49
49
|
| `timeline:overlay:<id>` | タイムラインのオーバーレイ | `timeline:overlay:o-0002` |
|
|
50
50
|
| `asset:<path>` | 素材(プロジェクト相対 or カタログ id) | `asset:assets/broll/city.mp4` |
|
|
51
|
+
| `asset:<category>/<id>` | 素材(カタログ由来カード。key = `<category>/<id>`) | `asset:still/br-typing-laptop` |
|
|
51
52
|
|
|
52
53
|
- **登録機構**: 記録対象の要素は `data-akari-ui="<target-id>"` 属性で opt-in する。
|
|
53
54
|
クリック解決は capture-phase のリスナー 1 本で行い、**最近傍の登録済み祖先**に丸める。
|
|
@@ -80,10 +81,21 @@
|
|
|
80
81
|
- 回帰: 新イベント入りの events.jsonl を旧読み手(compile-review-session の手順)が
|
|
81
82
|
処理してもエラーにならないこと
|
|
82
83
|
|
|
83
|
-
## 6.
|
|
84
|
-
|
|
85
|
-
- review.json `annotations[].target`
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
84
|
+
## 6. 注釈の着地契約
|
|
85
|
+
|
|
86
|
+
- review.json `annotations[].target` の **`ui:<element-id>`** は、選択ツール経由の UI 要素注釈に
|
|
87
|
+
使う。§2 と同一の id 空間を使い、たとえばオーバーレイは
|
|
88
|
+
`ui:timeline:overlay:<id>` に着地する
|
|
89
|
+
- render-cut は検証に成功した書き出し成果物を、edit.json v1 の `sources[]` へ自動追記する。
|
|
90
|
+
`path` はプロジェクトルート相対、`proxy` は `null` とし、同じ `path` が既にあれば追記しない。
|
|
91
|
+
既存 id と衝突しない出力 stem 由来の id を使い、既存フィールドと整形は書き換えない。
|
|
92
|
+
edit.json を再読込・パースできない場合は警告だけを残し、書き出し成功を取り消さない。
|
|
93
|
+
v0 は schema 上 `sources` を持てないため自動追記せず、同様に警告する
|
|
94
|
+
- `sources[].path` に一致する動画ファイルを raw preview で開き、そのタブがフォーカスされて
|
|
95
|
+
いる間の注釈は、`src = sources[].id` と raw preview の現在再生位置を source 秒とする
|
|
96
|
+
`sourceT` に着地する。コンポーザーは対象を `🎞 <source id>` チップで表示する。
|
|
97
|
+
一致しないファイルは従来どおり `src: null` の通常注釈とし、新しい target 種は作らない
|
|
98
|
+
- 音の素材区間は新しい `audio:` target を作らず、`src = sources[].id` と半開区間
|
|
99
|
+
`sourceRange: [start, end)` を使う。BGM 等のオーバーレイ音は既存の `overlay:<id>` または
|
|
100
|
+
`ui:timeline:overlay:<id>` で扱う。音声ファイルは専用 audio preview で開かれるため、raw video
|
|
101
|
+
preview の現在位置接続とは別であり、区間選択 UI は本契約の対象外とする
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# chat-approval 契約 v0(チャット通知 + ボタン承認)
|
|
2
|
+
|
|
3
|
+
- 日付: 2026-08-12
|
|
4
|
+
- 状態: **v0 ドラフト・要オーナーレビュー**
|
|
5
|
+
- 前提: `contract-2026-08-02-setup-remote-v0.md`(tailnet 限定の閲覧経路。レポート URL の供給元)、
|
|
6
|
+
`contract-2026-07-25-project-structure-v0.md`(承認レポートの実体)、
|
|
7
|
+
`packages/decision-cards/report-helper.mjs`(`decisions.json` の read / write / commit の唯一の実装)、
|
|
8
|
+
`skills/manage-connections`(接続レジストリと credentials の唯一の入口)
|
|
9
|
+
- スコープ: 承認ゲート到達を**チャットへ通知**し、**ボタンのタップだけで**承認を返せるようにする
|
|
10
|
+
- 非スコープ: チャットからの自由文指示、エージェントの起動・操作、素材のチャット搬送、
|
|
11
|
+
複数チャネル対応(v0 は Telegram 1 本)
|
|
12
|
+
|
|
13
|
+
## 0. 位置づけ — 一言で言い切る
|
|
14
|
+
|
|
15
|
+
**チャットは配管であって頭脳ではない。** 運ぶのは「できました」という通知・レポートへのリンク・
|
|
16
|
+
画像・そして**列挙可能な承認の返事**だけ。編集の判断は従来どおり AKARI のパイプラインが持ち、
|
|
17
|
+
承認の記録は `decisions.json` が持つ。チャット層は SSOT を一切持たない。
|
|
18
|
+
|
|
19
|
+
## 1. 決定事項
|
|
20
|
+
|
|
21
|
+
| 論点 | 決定 |
|
|
22
|
+
|---|---|
|
|
23
|
+
| 何を足すか | **通知と承認だけ**。エージェントをチャットから起動しない(別契約) |
|
|
24
|
+
| 書き込み経路 | ブリッジは `decisions.json` を**自分で書かない**。report-helper の HTTP API(`POST /api/state` / `POST /api/commit`)を 127.0.0.1 経由で叩く。書き込みの原子性・検証・`0600`・二重確定の 409 は既存実装のまま効く |
|
|
25
|
+
| 受信方式 | **long polling**(`getUpdates`)。公開エンドポイント・webhook・トンネルを作らない(受信口をインターネットに開けない) |
|
|
26
|
+
| 入力語彙 | **閉じた語彙のみ**。`callback_data` が既定の集合に一致するものだけ処理し、自由文は処理しない |
|
|
27
|
+
| チャネル | Telegram のみ(v0)。実装は `packages/chat-bridge/` に置き、後で LINE / Discord を足せる形にする |
|
|
28
|
+
|
|
29
|
+
## 2. なぜ自由文を入れないか(この契約の中心)
|
|
30
|
+
|
|
31
|
+
自由文をエージェントへ通すと、`planning`(非公開)の信頼境界契約が扱う prompt injection の
|
|
32
|
+
窓口がそのまま開く。ボタンの `callback_data` は**発行側が定義した有限集合**であり、
|
|
33
|
+
受信側は集合に無い値を捨てるだけでよい。v0 はこの性質を設計の土台にする。
|
|
34
|
+
|
|
35
|
+
- 差し戻しは「確定しない + レポートを開くリンクを返す」で表現する。理由の自由記述はレポート側で行う
|
|
36
|
+
- 自由文メッセージを受けたら、処理せず「レポートで操作してください」と定型文を返す
|
|
37
|
+
|
|
38
|
+
## 3. 安全規律(ハードルール)
|
|
39
|
+
|
|
40
|
+
1. **トークンを git 管理下・レポート・ログ・会話に出さない。** 置き場は
|
|
41
|
+
`~/.config/akari-video/credentials.env`(`600`)のみ。エージェントは値を読まず、KEY 名だけ案内する
|
|
42
|
+
2. **チャット ID の許可リストを必須にする。** 登録済み chat ID 以外からの update は
|
|
43
|
+
一切処理せず破棄する(bot のユーザー名は誰でも到達できるため、これが無いと第三者が承認できる)
|
|
44
|
+
3. **ブリッジはポートを listen しない。** 送信も受信も outbound の long polling のみ
|
|
45
|
+
4. **`decisions.json` を直接書かない**(§1 の決定)。report-helper 経由のみ
|
|
46
|
+
5. **update の重複処理をしない。** `update_id` で冪等化する(Telegram は再配信しうる)
|
|
47
|
+
6. **送ってよいのはレポートの画像とテキストのみ。** 撮影素材の原本・secrets・パスの内部構造を送らない
|
|
48
|
+
7. **疎通確認(実機への通知到達 + ボタンで `decisions.json` 更新)が取れるまで完了と言わない**
|
|
49
|
+
|
|
50
|
+
## 4. 構成要素
|
|
51
|
+
|
|
52
|
+
| 要素 | 置き場 | 役割 |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| ブリッジ本体 | `packages/chat-bridge/telegram.mjs` | 通知送信 + long polling + report-helper API 呼び出し |
|
|
55
|
+
| セットアップスキル | `skills/setup-chat-approval/` | doctor → BotFather 案内(人間手番)→ chat ID 取得 → 疎通確認。`setup-remote` と同じ型 |
|
|
56
|
+
| 接続登録 | `.akari/connections.json` | `manage-connections` の管轄(§5 の判断待ち) |
|
|
57
|
+
|
|
58
|
+
### 送るメッセージの形
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
🎬 <プロジェクト名> — 承認をお願いします
|
|
62
|
+
<要約 1〜2 行>
|
|
63
|
+
[キーフレーム画像 数枚]
|
|
64
|
+
|
|
65
|
+
[ レポートを開く (URL) ] [ おまかせで確定 ] [ あとで ]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
- 「レポートを開く」は URL ボタン(tailnet 限定 URL。Telegram のサーバーからは到達できないため
|
|
69
|
+
リンクプレビューは出ない → `disable_web_page_preview` を付ける)
|
|
70
|
+
- 「おまかせで確定」は全カード既定値のまま `POST /api/commit`(レポート側の `accept-all` と同義)
|
|
71
|
+
- v1 の拡張余地: カードごとに選択肢ボタンを展開する(`data-option` は有限集合なので §2 と両立する)
|
|
72
|
+
|
|
73
|
+
## 5. 判断待ち — `connections.json` の `kind` 拡張
|
|
74
|
+
|
|
75
|
+
現行スキーマの `kind` は `genai / image / video / tts / music / sns / analytics` の閉じた enum で、
|
|
76
|
+
**通知系の枠が無い**。`manage-connections` のハードルール 7(レジストリに無い接続を使わない)を
|
|
77
|
+
守るには、いずれかを選ぶ必要がある:
|
|
78
|
+
|
|
79
|
+
| 案 | 内容 | 評価 |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| **A. `notify` を enum に追加** | スキーマ + 検証 + 例 + `apps/shell` 側ミラーを更新 | **推奨**。通知は既存のどの kind とも性質が違う(発信ではなく往復)。将来の LINE / Discord も同じ枠に入る |
|
|
82
|
+
| B. 既存の `sns` を流用 | 変更ゼロ | `sns` は「SNS へ投稿する」枠であり、承認の往復とは別物。意味が濁る |
|
|
83
|
+
| C. レジストリに載せない | credentials.env だけで完結 | ハードルール 7 違反。採らない |
|
|
84
|
+
|
|
85
|
+
## 6. 成果物と受け入れ基準
|
|
86
|
+
|
|
87
|
+
- **L0**: スキル lint / スキーマ検証 / 既存テストが green
|
|
88
|
+
- **L1**: 決定論の単体テスト — 許可外 chat ID の破棄・未知の `callback_data` の破棄・
|
|
89
|
+
`update_id` の冪等化・自由文の非処理・トークンが出力に混じらないこと
|
|
90
|
+
- **L2**: 実機 — スマホへ通知が届き、ボタンのタップで `decisions.json` が更新される
|
|
91
|
+
|
|
92
|
+
## 7. 将来(非スコープの明示)
|
|
93
|
+
|
|
94
|
+
- カードごとの選択肢ボタン展開(v1)
|
|
95
|
+
- 複数チャネル(LINE / Discord / Slack)
|
|
96
|
+
- チャットからのエージェント起動・自由文指示(信頼境界の別契約が前提。常駐エージェント
|
|
97
|
+
= Hermes 等の検討もここに属する)
|
|
98
|
+
- 承認待ちのエージェント側の再開機構(現状は人間が「続けて」と言う前提。ファイル待ちの
|
|
99
|
+
ポーリングを挟む設計は別途)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Color range normalization v0
|
|
2
|
+
|
|
3
|
+
## 1. 背景と目的
|
|
4
|
+
|
|
5
|
+
full-range(`color_range=pc` / `yuvj420p`)の入力をそのまま H.264 出力へ伝播させると、配信向けの limited range を期待する再生・検証環境で階調とメタデータが一致しない。本契約は Render の全エンコード工程を limited range(FFmpeg の `tv`)へ正規化し、最終成果物と中間生成物の一貫性を保証する。
|
|
6
|
+
|
|
7
|
+
この不具合の起点と再現条件は [公開 issue #21](https://github.com/AkariLabs/akari-video/issues/21) を参照する。
|
|
8
|
+
|
|
9
|
+
## 2. 最終出力の保証
|
|
10
|
+
|
|
11
|
+
MP4 / H.264 の最終映像ストリームは次を満たさなければならない。
|
|
12
|
+
|
|
13
|
+
- pixel format は `yuv420p`
|
|
14
|
+
- `color_range` は `tv`(limited range)
|
|
15
|
+
|
|
16
|
+
この組み合わせを AKARI Video の配信標準出力とする。
|
|
17
|
+
|
|
18
|
+
## 3. 値変換とメタデータの不変条件
|
|
19
|
+
|
|
20
|
+
色域レンジの正規化は、画素値の変換と映像ストリームへのメタデータのタグ付けを常に対で行う。
|
|
21
|
+
|
|
22
|
+
- 各 video filter chain は出力直前に `scale=out_range=tv` 相当の値変換を行う。
|
|
23
|
+
- 各 H.264 encode は `-color_range tv` 相当のメタデータを付ける。
|
|
24
|
+
- full-range の画素値を残したまま `tv` タグだけを付けることを禁止する。
|
|
25
|
+
- 値だけを limited range へ変換し、タグ付けを省略することも禁止する。
|
|
26
|
+
|
|
27
|
+
入力がすでに tv range の場合、`scale=out_range=tv` はレンジ変換について no-op として扱う。
|
|
28
|
+
|
|
29
|
+
## 4. 工程不変
|
|
30
|
+
|
|
31
|
+
cut、tail padding、track stack、layers、overlay composite を含む各エンコード工程の出力フレームは常に tv range とする。これは最終成果物だけでなく、後続工程へ渡す中間生成物にも適用する。
|
|
32
|
+
|
|
33
|
+
複数ソースの cut では、ソースごとの前処理チェーンで tv range へ正規化してから concat / transition へ入力する。これにより pc / tv range が混在したフレームを同じ concat へ直接渡さない。さらに、LUT や合成後の工程出力も終端で tv range に正規化する。
|
|
34
|
+
|
|
35
|
+
映像を再エンコードしない audio-only mux と、alpha を運ぶ非 H.264 overlay 中間生成物は本契約の対象外とする。
|
|
36
|
+
|
|
37
|
+
## 5. Probe と provenance
|
|
38
|
+
|
|
39
|
+
入力ソースの `pix_fmt` と `color_range` を ffprobe の映像ストリームから取得し、既存の duration、audio 有無、width、height、fps と同じ provenance 情報として記録する。ffprobe が入力の `color_range` を報告しない場合は `null` として記録し、推測値で置き換えない。
|
|
40
|
+
|
|
41
|
+
## 6. Verify 契約
|
|
42
|
+
|
|
43
|
+
レンダープランの期待値へ `color_range: "tv"` を追加し、official verify は `verify.color-range` を報告する。
|
|
44
|
+
|
|
45
|
+
- 実測 `color_range` が `pc` の場合は error とする。
|
|
46
|
+
- 実測が `tv` の場合は pass とする。
|
|
47
|
+
- ffprobe が `color_range` を報告しない場合は、H.264 の仕様既定(未指定は limited range)に従って tv とみなし pass とする。
|
|
48
|
+
|
|
49
|
+
`verify.pixel-format` の期待値 `yuv420p` は維持し、`verify.color-range` と独立に判定する。
|
|
50
|
+
|
|
51
|
+
## 7. 予約(今回のスコープ外)
|
|
52
|
+
|
|
53
|
+
次の事項は別契約で扱い、本契約 v0 では実装しない。
|
|
54
|
+
|
|
55
|
+
- BT.601 から BT.709 などの colorspace 変換
|
|
56
|
+
- `-colorspace` / `-color_primaries` / `-color_trc` による colorspace メタデータの正規化
|
|
57
|
+
- 10bit および HDR 入力の変換、tone mapping、出力形式
|
|
58
|
+
|
|
59
|
+
本契約の `tv` 正規化は color range のみに限定され、上記の色域・伝達特性変換を暗黙に保証しない。
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Region filter layer v0
|
|
2
|
+
|
|
3
|
+
## 1. 背景
|
|
4
|
+
|
|
5
|
+
finger-frame の中心表現を、別映像の corner-pin 合成だけでなく、指で作った枠の内側だけベース映像自身のルックを切り替える表現へ拡張する。この用途では貼り込み素材を入力せず、ベース映像からフィルター済みの映像を作り、指定 region の内側だけへ戻す。
|
|
6
|
+
|
|
7
|
+
本書は `edit.json` の additive な拡張である `layers[].kind: "filter"` の v0 契約を定める。
|
|
8
|
+
|
|
9
|
+
## 2. 意味論
|
|
10
|
+
|
|
11
|
+
- `kind: "filter"` の layer は `src` を持たない。ベース映像以外の貼り込み入力を追加しない。
|
|
12
|
+
- `filter` は region の内側にだけ適用し、region の外側はベース映像をそのまま保つ。
|
|
13
|
+
- layer の発動時間窓は既存どおり `t` と `duration` で表す。
|
|
14
|
+
- `opacity`、`track`、および `keyframes[].perspective` は既存 layer の共通フィールドを再利用する。
|
|
15
|
+
- `src`、`chroma_key`、`blend`、`crop`、`transform` は `kind: "filter"` では使用できない。
|
|
16
|
+
|
|
17
|
+
## 3. Region source v0
|
|
18
|
+
|
|
19
|
+
v0 の region source は `perspective.corners` の quad である。表現、4 隅の順序、値域、退化四角形の制約は既存の `layerPerspective` をそのまま再利用する。`keyframes[].perspective` がある場合は既存の perspective keyframe 展開規約に従い、時間区間ごとの静的 quad として合成する。
|
|
20
|
+
|
|
21
|
+
## 4. 凍結インターフェース
|
|
22
|
+
|
|
23
|
+
```jsonc
|
|
24
|
+
{
|
|
25
|
+
"id": "finger-frame-1",
|
|
26
|
+
"kind": "filter",
|
|
27
|
+
"t": 12.0,
|
|
28
|
+
"duration": 2.4,
|
|
29
|
+
"filter": { "type": "invert" },
|
|
30
|
+
// または { "type": "lut", "id": "<presets/luts の id>", "intensity": 1.0 }
|
|
31
|
+
// または { "type": "saturation", "value": 1.6 }
|
|
32
|
+
"perspective": { "corners": [[0, 0], [1, 0], [0, 1], [1, 1]] },
|
|
33
|
+
"keyframes": [
|
|
34
|
+
{
|
|
35
|
+
"t": 0.1,
|
|
36
|
+
"perspective": { "corners": [[0, 0], [1, 0], [0, 1], [1, 1]] }
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"opacity": 1.0
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`filter` は次の closed union とする。
|
|
44
|
+
|
|
45
|
+
```jsonc
|
|
46
|
+
{
|
|
47
|
+
"type": "object",
|
|
48
|
+
"required": ["type"],
|
|
49
|
+
"oneOf": [
|
|
50
|
+
{
|
|
51
|
+
"properties": { "type": { "const": "invert" } },
|
|
52
|
+
"required": ["type"],
|
|
53
|
+
"additionalProperties": false
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"properties": {
|
|
57
|
+
"type": { "const": "lut" },
|
|
58
|
+
"id": { "type": "string", "minLength": 1, "pattern": "\\S" },
|
|
59
|
+
"intensity": { "type": "number", "minimum": 0, "maximum": 1 }
|
|
60
|
+
},
|
|
61
|
+
"required": ["type", "id"],
|
|
62
|
+
"additionalProperties": false
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"properties": {
|
|
66
|
+
"type": { "const": "saturation" },
|
|
67
|
+
"value": { "type": "number", "minimum": 0, "maximum": 3 }
|
|
68
|
+
},
|
|
69
|
+
"required": ["type", "value"],
|
|
70
|
+
"additionalProperties": false
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
LUT の `intensity` 省略時は `1` として描画する。
|
|
77
|
+
|
|
78
|
+
## 5. 予約(今回のスコープ外)
|
|
79
|
+
|
|
80
|
+
- region source `mask`: ピクセル単位のマットを region として使用する予約。v0 では schema、CLI、renderer のいずれにも実装しない。
|
|
81
|
+
- filter type `"pixelate"`: face-mosaic の将来の移行先として予約する。v0 の closed union には含めず、指定された場合は拒否する。
|
|
82
|
+
|
|
83
|
+
予約名は現在利用可能であることを意味しない。
|
|
84
|
+
|
|
85
|
+
## 6. Additive 原則
|
|
86
|
+
|
|
87
|
+
この契約は既存の `kind: "baked"` / `kind: "video"` に対する additive な拡張である。既存 kind の必須フィールド、合成順、フィルターチェーン、examples / fixtures の妥当性と出力は変更しない。filter layer を含まない既存入力は従来とバイト等価に扱う。
|
|
88
|
+
|
|
89
|
+
## 7. 実装対応
|
|
90
|
+
|
|
91
|
+
- `packages/render-cut/src/layers.mjs`: ベース映像の split、ルック適用、白 quad mask、`maskedmerge` による region 内合成を行う。filter layer は追加の `-i` を作らない。
|
|
92
|
+
- `packages/akari-tools/bin/finger-frame.mjs`: `--kind filter --filter invert|lut:<id>|saturation:<value>` から、既存と同じ gesture window と corner keyframes を持つ layer を生成する。
|
|
93
|
+
|
|
94
|
+
## 8. 検証
|
|
95
|
+
|
|
96
|
+
L0 では schemas、akari-tools、render-cut の各 `node --test`、docs-sync、既存 baked / video の非回帰を確認する。ffmpeg コマンド生成テストは filter layer が追加 `-i` を作らず、3 種の filter と perspective keyframe 展開が決定論的なグラフを生成することを確認する。
|
|
97
|
+
|
|
98
|
+
12 秒 window の実素材による invert / LUT の見た目、所要時間、入力数の実測は別途実施し、検証報告へ記録する。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akari-video",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
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": {
|
|
@@ -135,6 +135,21 @@ function validateAnalysisStructure(analysis, label) {
|
|
|
135
135
|
) {
|
|
136
136
|
errors.push("tracks.person_matte は string か null である必要があります");
|
|
137
137
|
}
|
|
138
|
+
for (const field of ["face_landmarks", "hand_pose"]) {
|
|
139
|
+
if (!hasOwn(analysis.tracks, field)) continue;
|
|
140
|
+
const pointer = analysis.tracks[field];
|
|
141
|
+
if (!isRecord(pointer) || !isNonEmptyString(pointer.path) || !(Number(pointer.sample_fps) > 0)) {
|
|
142
|
+
errors.push(`tracks.${field} は path(空でない文字列)・sample_fps(正数) を持つ object である必要があります`);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (hasOwn(pointer, "features") && (
|
|
146
|
+
!Array.isArray(pointer.features)
|
|
147
|
+
|| pointer.features.some((feature) => !isNonEmptyString(feature))
|
|
148
|
+
|| new Set(pointer.features).size !== pointer.features.length
|
|
149
|
+
)) {
|
|
150
|
+
errors.push(`tracks.${field}.features は重複のない空でない文字列配列である必要があります`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
138
153
|
}
|
|
139
154
|
for (const [index, kf] of (analysis.keyframes || []).entries()) {
|
|
140
155
|
if (!isRecord(kf)) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@akari-video/chat-bridge",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "承認ゲートの通知 + ボタン承認ブリッジ v0(Telegram)。decisions.json は report-helper の HTTP API 経由でのみ更新し、ポートは listen しない。外部 npm 依存ゼロ(Node.js 組み込みモジュールのみ)。",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"akari-chat-bridge": "src/telegram.mjs"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node src/telegram.mjs",
|
|
12
|
+
"test": "node --test"
|
|
13
|
+
}
|
|
14
|
+
}
|