オーディオ/MIDI トラックを右クリックして、そのトラック専用のメモと TODO を書き留められる Ableton Live 拡張機能です。パネルからトラック名の変更もでき、グループトラックの親で開くと子トラックの内容を一覧できます。保存ごとに日時が記録され、過去の状態を履歴として閲覧・復元できます。データは SQLite に、Live プロジェクト単位で保存されます。
Built with
@ableton-extensions/sdk1.0.0-beta.0(beta)。
- トラックごとのメモ:自由記述のテキストエリア。最終更新日時を表示。
- トラックごとの TODO:追加/チェック(完了)/編集/削除。各項目に作成・更新日時。未完了が上に並びます。
- トラック名の変更:ヘッダーの名前欄を編集して保存すると、Live 側のトラック名も変更され、保存済みメモ/TODO も新しい名前へ移行します。
- グループの子トラック一覧:グループトラックの親で開くと「子トラック」タブが現れ、各子トラックのメモ/TODO を読み取り専用で一覧できます。
- 保存履歴:保存するたびに「メモ+TODO の全スナップショット」と日時・変更サマリを記録。履歴タブで展開して中身を確認でき、**「この状態を復元」**で過去の内容を呼び戻せます。
- プロジェクト単位の分離:Live プロジェクトごとに別々の SQLite データベース。別の曲を開けば別のメモ。
- Live のダークテーマに馴染む UI:タブ式(メモ/TODO/履歴/子トラック)、
Cmd/Ctrl+Sで保存、Escでキャンセル。
注:Live の実トラック「作成日時」を取得する API は SDK に無いため、作成日時の表示は行いません。
- Live のセッション/アレンジ画面で、オーディオまたは MIDI トラックのタイトルバーを右クリック。
- コンテキストメニューの 「Track Notes…」 を選択。
- モーダルパネルが開く:
- メモ タブ … トラックの覚え書き。
- TODO タブ … 「ミックス調整」「サンプル差し替え」などのタスク。
- 履歴 タブ … いつ何を保存したかの一覧。展開して過去のメモ/TODO を確認・復元。
- 保存 で SQLite に書き込み、履歴に 1 件追加。キャンセルまたは
Escで破棄。
このSDKのモーダルダイアログは「開く→閉じる時に文字列を1つ返す」単発往復モデルです(公式 modal-dialog サンプルと同じ data: URL 方式)。本拡張もこれに沿っています。
┌──────────────── Extension (Node.js / dist/extension.js) ─────────────────┐
│ activate() │
│ └─ registerContextMenuAction("AudioTrack"/"MidiTrack", "Track Notes…")│
│ └─ registerCommand("trackNotes.open") │
│ │
│ openPanel(handle): │
│ 1. handle → Track(getObjectFromHandle)→ track.name │
│ 2. resolveProject() …… プロジェクト用 SQLite のパスを決定(project.ts) │
│ 3. store.loadTrack() …… メモ/TODO/履歴を読み出し(store.ts, SQLite) │
│ 4. ui.html に初期状態(JSON)を差し込み、data: URL で showModalDialog() │
│ 5. 閉じたら返り値(JSON)を受け取り、save なら store.saveTrack() │
└──────────────────────────────────────────────────────────────────────────┘
▲ 初期状態(JSON) │ 返り値(JSON: action/memo/todos)
│ ▼
┌──────────────── WebView UI (src/ui.html, 単一HTML) ──────────────────────┐
│ メモ / TODO / 履歴 の3タブ。編集はすべてメモリ上のモデルで管理し、 │
│ 「保存」時に現在の全状態を JSON で host に postMessage して閉じる。 │
└──────────────────────────────────────────────────────────────────────────┘
- UI ↔ Extension の通信:UI は
window.webkit.messageHandlers.live(macOS)またはwindow.chrome.webview(Windows)に{ method: "close_and_send", params: [JSON] }を送って閉じます。返ってくる JSON がshowModalDialog()の解決値です。 - タイムスタンプは Extension 側で付与:保存日時・作成/更新日時は Node 側で
new Date().toISOString()(ISO-8601, UTC)で確定します。WebView の時計には依存しません。 - 保存は1トランザクション:メモの upsert、TODO の差分反映(追加/更新/削除)、履歴スナップショットの追記を
BEGIN…COMMITでまとめ、失敗時はROLLBACK。
@ableton-extensions/sdk には「現在の Live Set のパス/ID を取得する API」が存在しません。そこで本拡張は次の方法でプロジェクトを識別します(src/project.ts):
- 一時ファイル(マーカー)を作成。
resources.importIntoProject(marker)でそれを現在のプロジェクトフォルダへコピー。返り値はコピー先の絶対パス。- そのフォルダパスの SHA-256 先頭16文字を プロジェクトキー とする。
- データベースは拡張の
environment.storageDirectory/projects/<projectKey>.sqliteに置く(書き込みが常に保証される拡張専用領域。ユーザのプロジェクトツリーは汚さない)。
プロジェクト未保存・インポート不可の場合は、共有の
default.sqliteにフォールバックします。
トラックはトラック名でキー化されます(track_key)。日時はすべて ISO-8601(例:2026-06-03T09:00:00.000Z)。
-- トラックのレジストリ
tracks(
track_key TEXT PRIMARY KEY, -- 正規化したトラック名
name TEXT, created_at TEXT, updated_at TEXT
)
-- 1トラック1メモ
memos(
track_key TEXT PRIMARY KEY,
text TEXT, updated_at TEXT
)
-- TODO 項目
todos(
id INTEGER PRIMARY KEY AUTOINCREMENT,
track_key TEXT, text TEXT,
done INTEGER, -- 0 / 1
created_at TEXT, updated_at TEXT
)
-- 保存ごとのスナップショット(履歴)
history(
id INTEGER PRIMARY KEY AUTOINCREMENT,
track_key TEXT, saved_at TEXT,
memo_snapshot TEXT,
todos_snapshot TEXT, -- JSON 文字列
summary TEXT -- 例: "memo updated, +1 todo · 3 total"
)ストレージは Node 組み込みの node:sqlite(DatabaseSync) を使用。ネイティブアドオンのビルドが不要なので、Extension Host の Node ABI に依存しません。
ableton_todo/
├── manifest.json # 拡張メタデータ(name/author/entry/minimumApiVersion)
├── package.json # スクリプトと依存(vendor の tgz を参照)
├── tsconfig.json # 型チェック設定(公式サンプル準拠)
├── build.ts # esbuild バンドル(.html を文字列としてインライン)
├── .env.example # EXTENSION_HOST_PATH のひな型
├── vendor/ # SDK / CLI の beta tgz(リポジトリ自己完結のため同梱)
│ ├── ableton-extensions-sdk-1.0.0-beta.0.tgz
│ └── ableton-extensions-cli-1.0.0-beta.0.tgz
└── src/
├── extension.ts # エントリ。コンテキストメニュー登録&パネル制御
├── project.ts # プロジェクト識別と DB パス解決
├── store.ts # SQLite ストレージ(load/save、履歴、差分反映)
├── ui.html # リッチ UI(3タブ・単一HTML)
└── html.d.ts # `import ui from "./ui.html"` の型宣言
- Node.js 24.14.1 以上(CLI 要件)。
node:sqliteの安定版が必要です。 - Ableton Live(Extension 対応ビルド)。
cd ableton_todo
npm installSDK/CLI は npm 非公開のため、
vendor/内の.tgzをpackage.jsonから参照しています。
extensions-cli run は ExtensionHostNodeModule.node の場所を EXTENSION_HOST_PATH(環境変数または .env)から読みます。
cp .env.example .env
# .env を編集して EXTENSION_HOST_PATH を設定macOS の例:
EXTENSION_HOST_PATH=/Applications/Ableton Live 12 Suite.app/Contents/App-Resources/Extensions/ExtensionHostNodeModule.node
正確な場所は SDK 同梱ドキュメント(docs の development セクション)の「ExtensionHostNodeModule.node の見つけ方」を参照してください。
# 型チェック + バンドル(dist/extension.js を生成)
npm run build
# ビルドして Live の Extension Host で実行
npm startnpm start 後、Live でオーディオ/MIDI トラックを右クリック →「Track Notes…」。
VS Code が PATH にあれば、scaffold 同様に F5 デバッグ構成を追加できます(extensions-cli run --inspect)。
npm run package # .ablx アーカイブを生成(本番ビルド)このSDKは beta であり、いくつかの制約があります。設計上の割り切りを明記します。
- トラックの識別はトラック名:SDK は安定したトラック ID をプロジェクト保存後に提供しません(
Handle.idはセッション内のみ有効)。そのためtrack_key = トラック名。- パネルから名前を変更した場合は、メモ/TODO を新キーへ自動移行します(Live 側のトラック名も変更)。
- 一方、Live 上で直接トラック名を変更した場合は引き継がれません(旧名のまま DB に残ります)。
- 同名トラックが2つあると、メモ/TODO を共有します。
- グループ判定:右クリックしたトラックを親に持つ子トラック(
song.tracksのうちgroupTrackが一致するもの)を集約表示します。グループトラック上でコンテキストメニューが出ない Live ビルドでは利用できません。 - プロジェクト識別の副作用:
importIntoProjectを使うため、初回プローブ時に小さなマーカーファイルがプロジェクトへ取り込まれます(track-notes-probe.txt、削除可)。- フォールバック:プロジェクト未保存/インポート不可なら共有 DB(
default.sqlite)。 - セッション中の「名前を付けて保存(別フォルダ)」はその場では再検出されません(Live 再起動で反映)。
- フォールバック:プロジェクト未保存/インポート不可なら共有 DB(
- 保存はダイアログを閉じた時のみ:モーダルが単発往復モデルのため、リアルタイム自動保存ではありません。
Cmd/Ctrl+Sまたは「保存」ボタンで確定。 node:sqlite依存:Extension Host の Node にnode:sqliteが含まれている必要があります(Node 24 系で安定提供)。
- リネーム追従:リネーム検知時に旧キーのメモ/TODO を移行する UI。
- 全トラック横断ビュー:プロジェクト内の全 TODO を一覧する集約パネル(モーダルではなく localhost サーバ方式に切り替えるとリアルタイム化も可能)。
- クリップ/シーン単位のメモ:コンテキストメニューのスコープを
MidiClip/AudioClip/Sceneへ拡張。 - エクスポート:メモ/TODO を Markdown や CSV へ書き出し。
- 検索・タグ付け:TODO のフィルタ(未完了のみ等)やタグ。
@ableton-extensions/sdk(Ableton AG, beta)に依存します。SDK のライセンスは配布 zip 内 LICENSE.md を参照してください。