@mthines/reaper-mcp 0.19.0 → 0.70.2
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/README.md +19 -570
- package/bridge-ui/mcp_bridge.html +129 -0
- package/bridge-ui/mcp_bridge.webmanifest +16 -0
- package/bridge-ui/mcp_bridge_icon_192.png +0 -0
- package/bridge-ui/mcp_bridge_icon_512.png +0 -0
- package/bridge-ui/mcp_bridge_sw.js +35 -0
- package/claude/agents/plugin-researcher.md +188 -0
- package/claude/knowledge/reference/aesthetics-scoring.md +48 -0
- package/{knowledge → claude/knowledge}/reference/common-mistakes.md +1 -1
- package/claude/knowledge/reference/lorekit-setup.md +36 -0
- package/claude/knowledge/reference/memory-protocol.md +377 -0
- package/{knowledge → claude/knowledge}/reference/metering.md +5 -5
- package/claude/knowledge/reference/perceived-loudness.md +182 -0
- package/{knowledge → claude/knowledge}/workflows/editing.md +4 -0
- package/{knowledge → claude/knowledge}/workflows/gain-staging.md +21 -23
- package/{knowledge → claude/knowledge}/workflows/learn-plugin.md +15 -48
- package/{knowledge → claude/knowledge}/workflows/master-bus.md +13 -1
- package/claude/knowledge/workflows/section-levels.md +138 -0
- package/{knowledge → claude/knowledge}/workflows/session-prep.md +4 -0
- package/claude/knowledge/workflows/transient-lighting.md +52 -0
- package/claude/skills/critique/SKILL.md +131 -0
- package/claude/skills/editing/SKILL.md +281 -0
- package/claude/skills/learn-plugin/SKILL.md +210 -0
- package/claude/skills/mastering/SKILL.md +151 -0
- package/claude/skills/mix-memory/SKILL.md +140 -0
- package/claude/skills/mixer/SKILL.md +253 -0
- package/claude/skills/new-extension/SKILL.md +324 -0
- package/main.js +7843 -1940
- package/package.json +17 -15
- package/reaper/CLAUDE.md +22 -4
- package/reaper/mcp_actions_lib.lua +375 -0
- package/reaper/mcp_analyzer.jsfx +27 -12
- package/reaper/mcp_arrange_lib.lua +949 -0
- package/reaper/mcp_bridge.lua +2321 -758
- package/reaper/mcp_edit_views_lib.lua +1378 -0
- package/reaper/mcp_envelopes_lib.lua +748 -0
- package/reaper/mcp_extensions_lib.lua +55 -0
- package/reaper/mcp_fxstate_lib.lua +144 -0
- package/reaper/mcp_gain_trace.jsfx +126 -0
- package/reaper/mcp_items_lib.lua +877 -0
- package/reaper/mcp_lufs_meter.jsfx +16 -13
- package/reaper/mcp_midi_lib.lua +555 -0
- package/reaper/mcp_mixing_lib.lua +1021 -0
- package/reaper/mcp_plan_lib.lua +801 -0
- package/reaper/mcp_prefs_lib.lua +127 -0
- package/reaper/mcp_project_lib.lua +1088 -0
- package/reaper/mcp_recording_lib.lua +595 -0
- package/reaper/mcp_render_lib.lua +492 -0
- package/reaper/mcp_snapshot_lib.lua +547 -120
- package/reaper/mcp_snapshot_next.lua +10 -4
- package/reaper/mcp_snapshot_prev.lua +11 -4
- package/reaper/mcp_snapshot_quick_save.lua +7 -32
- package/reaper/mcp_snapshots_ui_lib.lua +258 -0
- package/reaper/mcp_tracks_lib.lua +409 -0
- package/sidecar/analysis.py +661 -0
- package/sidecar/chords.py +96 -0
- package/sidecar/mixcheck.py +295 -0
- package/sidecar/requirements-chords.txt +6 -0
- package/sidecar/requirements-separation.txt +3 -0
- package/sidecar/requirements.txt +17 -0
- package/sidecar/separation.py +142 -0
- package/sidecar/server.py +622 -0
- package/sidecar/tests/test_analysis.py +249 -0
- package/sidecar/tests/test_chords.py +117 -0
- package/sidecar/tests/test_mixcheck.py +163 -0
- package/sidecar/tests/test_separation.py +73 -0
- package/sidecar/tests/test_server.py +464 -0
- package/sidecar/tests/test_verify.py +243 -0
- package/sidecar/tests/test_voice_render.py +268 -0
- package/sidecar/tests/test_voice_sketch.py +140 -0
- package/sidecar/verify.py +224 -0
- package/sidecar/voice_render.py +295 -0
- package/sidecar/voice_sketch.py +280 -0
- package/claude-agents/critique.md +0 -147
- package/claude-agents/editor.md +0 -184
- package/claude-agents/levels.md +0 -107
- package/claude-agents/mastering.md +0 -129
- package/claude-agents/mixer.md +0 -248
- package/claude-agents/preflight.md +0 -149
- package/claude-agents/producer.md +0 -159
- package/claude-agents/setup.md +0 -150
- package/claude-agents/stems.md +0 -135
- package/claude-rules/architecture.md +0 -39
- package/claude-rules/development.md +0 -54
- package/claude-rules/lua-bridge.md +0 -50
- package/claude-rules/testing.md +0 -42
- package/claude-skills/learn-plugin.md +0 -123
- package/knowledge/CLAUDE.md +0 -71
- package/knowledge/plugins/_template.md +0 -82
- package/knowledge/plugins/fabfilter/pro-c-2.md +0 -117
- package/knowledge/plugins/fabfilter/pro-l-2.md +0 -95
- package/knowledge/plugins/fabfilter/pro-q-3.md +0 -112
- package/knowledge/plugins/neural-dsp/helix-native.md +0 -104
- package/knowledge/plugins/stock-reaper/js-1175-compressor.md +0 -94
- package/knowledge/plugins/stock-reaper/rea-comp.md +0 -100
- package/knowledge/plugins/stock-reaper/rea-delay.md +0 -95
- package/knowledge/plugins/stock-reaper/rea-eq.md +0 -103
- package/knowledge/plugins/stock-reaper/rea-gate.md +0 -99
- package/knowledge/plugins/stock-reaper/rea-limit.md +0 -75
- package/knowledge/plugins/stock-reaper/rea-verb.md +0 -76
- package/knowledge/reference/perceived-loudness.md +0 -122
- package/reaper/mcp_snapshot_manager.lua +0 -1001
- /package/{knowledge → claude/knowledge}/genres/_template.md +0 -0
- /package/{knowledge → claude/knowledge}/genres/electronic.md +0 -0
- /package/{knowledge → claude/knowledge}/genres/hip-hop.md +0 -0
- /package/{knowledge → claude/knowledge}/genres/metal.md +0 -0
- /package/{knowledge → claude/knowledge}/genres/orchestral.md +0 -0
- /package/{knowledge → claude/knowledge}/genres/pop.md +0 -0
- /package/{knowledge → claude/knowledge}/genres/rock.md +0 -0
- /package/{knowledge → claude/knowledge}/reference/compression.md +0 -0
- /package/{knowledge → claude/knowledge}/reference/frequencies.md +0 -0
- /package/{knowledge → claude/knowledge}/workflows/delivery.md +0 -0
- /package/{knowledge → claude/knowledge}/workflows/drum-bus.md +0 -0
- /package/{knowledge → claude/knowledge}/workflows/low-end.md +0 -0
- /package/{knowledge → claude/knowledge}/workflows/stem-prep.md +0 -0
- /package/{knowledge → claude/knowledge}/workflows/vocal-chain.md +0 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
-- =============================================================================
|
|
2
|
+
-- Shared tokens for the status page (apps/bridge-ui, Settings → LoreKit)
|
|
3
|
+
-- =============================================================================
|
|
4
|
+
-- The page keeps the viewer's read-only LoreKit token (lk_ro_) in ~/.config/reaper-mcp/lorekit.json instead of the
|
|
5
|
+
-- browser's localStorage, which is per origin (dev server :8098, REAPER's :8099, a PWA window) and
|
|
6
|
+
-- is wiped with the browser's site data. One file means every way of opening the page, and every
|
|
7
|
+
-- reinstall, sees the same tokens. Through REAPER's web interface ExtState (the page has no file access):
|
|
8
|
+
--
|
|
9
|
+
-- lorekit_tokens = {"v":1,"read":…,"req":…,"ok":…,"error":…}
|
|
10
|
+
-- Published once on start and after every request. REAPER's web server
|
|
11
|
+
-- answers anyone who can reach its port, so only a READ-ONLY token goes
|
|
12
|
+
-- through here: a token that doesn't start with lk_ro_ is refused, and the
|
|
13
|
+
-- write token (lk_rw_, publishing into LoreKit's built-in layer) stays in
|
|
14
|
+
-- the browser, never in this file or in ExtState.
|
|
15
|
+
-- tokens_req = <id>-<control token>-<hex read>
|
|
16
|
+
-- Replaces the token (an empty hex removes it). The control token is
|
|
17
|
+
-- the bridge's per-run token, only readable from the status feed.
|
|
18
|
+
--
|
|
19
|
+
-- The file is JSON {"readToken":…}, created with mode 600 where chmod exists. A file that holds anything
|
|
20
|
+
-- else (an earlier version also kept a publishToken) is rewritten without it when the bridge starts.
|
|
21
|
+
-- Loaded by mcp_bridge.lua (keeps the bridge under Lua's 200-locals limit).
|
|
22
|
+
-- =============================================================================
|
|
23
|
+
|
|
24
|
+
local M = {}
|
|
25
|
+
|
|
26
|
+
local ctx
|
|
27
|
+
local loaded = false
|
|
28
|
+
local state = { read = nil }
|
|
29
|
+
local TOKEN_MAX = 512
|
|
30
|
+
local FILE = "lorekit.json"
|
|
31
|
+
|
|
32
|
+
-- The folder of the shared config: $XDG_CONFIG_HOME/reaper-mcp, else ~/.config/reaper-mcp (macOS and Linux),
|
|
33
|
+
-- %APPDATA%/reaper-mcp on Windows. getenv is injected so it can be tested.
|
|
34
|
+
function M.default_dir(getenv, windows)
|
|
35
|
+
local xdg = getenv("XDG_CONFIG_HOME")
|
|
36
|
+
if xdg and xdg ~= "" then return (xdg:gsub("\\", "/")) .. "/reaper-mcp/" end
|
|
37
|
+
if windows then
|
|
38
|
+
local appdata = getenv("APPDATA")
|
|
39
|
+
if appdata and appdata ~= "" then return (appdata:gsub("\\", "/")) .. "/reaper-mcp/" end
|
|
40
|
+
end
|
|
41
|
+
local home = getenv("HOME") or getenv("USERPROFILE")
|
|
42
|
+
if not home or home == "" then return nil end
|
|
43
|
+
return (home:gsub("\\", "/")) .. "/.config/reaper-mcp/"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
-- ctx: api (reaper), section (ExtState section), dir (the config folder with a trailing slash, or nil),
|
|
47
|
+
-- decode, encode (JSON), read_file, token() (the control token), chmod(path) (owner-only access; optional).
|
|
48
|
+
function M.init(c)
|
|
49
|
+
ctx = c
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
-- Only a read-only token: a write token must never reach the file or the web interface
|
|
53
|
+
local function valid_token(t)
|
|
54
|
+
return type(t) == "string" and #t <= TOKEN_MAX and t:sub(1, 6) == "lk_ro_" and #t > 6 and not t:find("%c") and not t:find("%s")
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
-- Returns true when the file held more than the read token and needs rewriting
|
|
58
|
+
local function load()
|
|
59
|
+
state = { read = nil }
|
|
60
|
+
local text = ctx.dir and ctx.read_file(ctx.dir .. FILE)
|
|
61
|
+
if not text then return false end
|
|
62
|
+
local ok, data = pcall(ctx.decode, text)
|
|
63
|
+
if not ok or type(data) ~= "table" then return false end
|
|
64
|
+
if valid_token(data.readToken) then state.read = data.readToken end
|
|
65
|
+
for k in pairs(data) do if k ~= "readToken" then return true end end
|
|
66
|
+
return false
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
local function publish(req, ok, err)
|
|
70
|
+
ctx.api.SetExtState(ctx.section, "lorekit_tokens", ctx.encode({
|
|
71
|
+
v = 1, read = state.read, req = req, ok = ok, error = err,
|
|
72
|
+
-- the page tells "no file to share" from "the bridge can't write one"
|
|
73
|
+
writable = ctx.dir ~= nil,
|
|
74
|
+
}), false)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
local function save()
|
|
78
|
+
if not ctx.dir then return nil, "No home folder to keep the tokens in" end
|
|
79
|
+
ctx.api.RecursiveCreateDirectory(ctx.dir, 0)
|
|
80
|
+
local path = ctx.dir .. FILE
|
|
81
|
+
-- Create the file and close its permissions before a token goes in it
|
|
82
|
+
local f, err = io.open(path, "w")
|
|
83
|
+
if not f then return nil, err or "Can't write " .. path end
|
|
84
|
+
f:close()
|
|
85
|
+
if ctx.chmod then pcall(ctx.chmod, path) end
|
|
86
|
+
f = io.open(path, "w")
|
|
87
|
+
if not f then return nil, "Can't write " .. path end
|
|
88
|
+
f:write(ctx.encode({ readToken = state.read }))
|
|
89
|
+
f:close()
|
|
90
|
+
return true
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
local function unhex(s)
|
|
94
|
+
if #s % 2 ~= 0 then return nil end
|
|
95
|
+
return (s:gsub("%x%x", function(h) return string.char(tonumber(h, 16)) end))
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
local function handle(req)
|
|
99
|
+
local id, token, read_hex = req:match("^([%w_]+)%-(%w+)%-(%x*)$")
|
|
100
|
+
-- Anything but a request carrying this run's control token is ignored, like the snapshot requests
|
|
101
|
+
if not id or token ~= ctx.token() then return end
|
|
102
|
+
local read = unhex(read_hex)
|
|
103
|
+
if read == nil then return publish(id, false, "Malformed request") end
|
|
104
|
+
if read ~= "" and not valid_token(read) then return publish(id, false, "Only a read-only token (lk_ro_…) is kept here") end
|
|
105
|
+
local before = state.read
|
|
106
|
+
state.read = read ~= "" and read or nil
|
|
107
|
+
local ok, err = save()
|
|
108
|
+
if not ok then state.read = before end
|
|
109
|
+
publish(id, ok and true or false, err)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
-- Called every defer tick
|
|
113
|
+
function M.poll()
|
|
114
|
+
if not loaded then
|
|
115
|
+
loaded = true
|
|
116
|
+
-- An older file also kept the write token: take it out
|
|
117
|
+
if load() then save() end
|
|
118
|
+
publish(nil, true)
|
|
119
|
+
end
|
|
120
|
+
local req = ctx.api.GetExtState(ctx.section, "tokens_req")
|
|
121
|
+
if req ~= "" then
|
|
122
|
+
ctx.api.DeleteExtState(ctx.section, "tokens_req", false)
|
|
123
|
+
handle(req)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
return M
|