エージェントのコマンド¶
agent/commands/ に置く JSON({"cmd": "...", ...})と、lemonade send <cmd> key=value … で使えるコマンドの一覧です
(原文は英語。プロジェクトフォルダの AGENTS.md と同じ内容)。
- ファイルは一時ファイルに書いてからリネームして置きます。名前順に処理され、結果は
agent/results/<name>.jsonに{"ok": true, ...}か{"ok": false, "error": "..."}で書かれます。 - ノードの id は
state.jsonのidです。アプリが動いている間だけ有効で、開き直したショーでは変わります。 cellを省くと編集中のセルになります。
cmd |
Fields | Result |
|---|---|---|
add_glsl |
name? (file stem in shaders/), source? (GLSL; else a starter template), cell?, position? [x, y], out? (connect to the cell's Out) |
node, shader, file |
add_node |
kind (built-in name), cell?, position?, parent? (a Base's or Particle's id: add inside it; required for In / Out and particle nodes) |
node |
remove_node |
node (not an Out, nor a Particle's own in / out) |
|
reset_particles |
node (a Particle) — every particle starts over at its pixel |
|
video |
node (a Video), seek? (seconds), cue? (a..h: jump there, or set it at the current position when empty), clear_cue?, play? (bool), reverse? (bool: play backwards), speed? (0–4, 1 = normal; to 0.001), auto_sync? (bool: play at the show's BPM / bpm), bpm? (the clip's tempo, 40–240) |
|
group |
nodes (ids in one network, not an Out) — moved into a new Base; connections crossing them go through new In / Out nodes |
node (the Base), inputs, outputs |
ungroup |
node (a Base, not a Particle) — its nodes move out into the network around it and the Base with its In / Out nodes goes; connections through its ports are rewired |
nodes (the moved ids) |
expose |
base, node (inside it, any depth), param, remove? — shows the node's param on the Base's NODE tab (edited on the node; its MIDI / bindings stay on the node), or stops showing it |
exposed ([{ node, param }], also in state.json on Bases) |
save_component |
node (a Base or Particle), name — saves it with everything inside as presets/components/<name>.ron in the data dir (overwrites) |
components (saved names) |
cell_preset |
action? (list (the default), save: cell + name, load: cell + name — replaces the cell's nodes) — a pack's presets are <pack>/<name> |
presets (names); load: problems |
node_preset |
node, action? (list (the default): the presets of its kind, save + name, apply + name: its params, bindings and shader copy) — a pack's presets are <pack>/<name> |
presets (names); apply: problems |
pack |
action? (list (the default), install (path: a folder or a .zip; or url: a .zip URL or a git repository, installed in the background — list again to see it), remove (name), export (name, title?, author?, description?, version?, home? (its URL), notes? ({"cells/<name>": "…"}), cells?, components?, nodes? ([[kind folder, name]]) — the user's presets —, to: a folder, or a .zip file)) — packs share cell presets, components and node presets; theirs are named <pack>/<name> (in cell_preset, add_component) |
packs ([{ name, title, author, version, description, shipped, source, cells, components, nodes }]), installing, message; install: installed; export: written |
add_component |
name, cell?, position?, parent? (a Base to add it inside) — adds a saved component, shader files copied |
node (the new Base) |
connect |
from, from_port? (default out), to, to_port? (default: the only input, else the first free texture input) |
|
disconnect |
to, to_port |
|
set_param |
node, param, value (number, bool, [r,g,b(,a)], string, or a choice label) |
value |
set_expr |
node, param, expr (null or "" removes it) |
error if it doesn't parse |
set_wires |
node, param, count 0..4, combine? (mul add min max avg) |
wire port names |
select |
node (also shows its cell in the EDITOR) |
|
edit_cell |
cell |
|
launch |
cell (play it on its layer), quantize? (off beat bar 2bars 4bars; default: the layer's, see layer) — starts at the next quantize point of the beat clock (off: now) with the layer's transition |
pending (waits for its point), at_beat (the beat it starts on: the beat clock count, as engine.beats in inspect) |
layer |
layer (1–4), opacity? (0–1), mode? (a blend mode name: Normal, Add, Screen, …), bypass?, solo?, side? (a thru b), quantize? (off beat bar (the default) 2bars 4bars: where a launch on the layer starts), transition? (cut (the default) crossfade wipe zoom slide dissolve glitch flash: how the layer changes cells), transition_beats? (0.25–32) — while a transition runs both cells play; a launch during one starts from the cell that showed more |
layer (as in state.json layers: opacity, mode, bypass, solo, side, quantize, transition, transition_beats, pending_slot, fading_from, progress, autopilot) |
tempo |
bpm? (20–400: a manual tempo, like typing it), auto? (follow the music again), tap?, sync? (now = the start of a beat) |
tempo (bpm, beats: the clock's beat count, source: auto / manual; also in state.json) |
master |
level? (0 = black … 1; after the post FX) |
master_level |
palette |
preset? (a built-in palette: neon, sunset, ocean, acid, …), colors? (8 colors), index? (1–8) + color? — a color is [r, g, b] (0–1) or "#rrggbb" |
palette (colors: 8 #rrggbb, preset: its name when it is one; also in state.json) |
post_fx |
kind? (fade / one_shot) + slot? (1–8) with fx? (a post FX name: strobe, rgb split, trails, …) and level? (fades, 0 = off … 1), layers? ("all": on the master output, or layer numbers [1, 3]: on those layers before the mix) |
post_fx (fade: [{ fx, level }], one_shot: effects, layers; also in state.json) |
autopilot |
layer (1–4), enabled?, mode? (next: the next cell that plays something; random; random_of: random among cells), every? (1–64 events per change), on? (bars, trigger1–trigger4: a pad firing, hit_sub hit_low hit_mid hit_high: a band hit), cells? (1-based slots for random_of) — the layer changes cells by itself with its quantize / transition; a launch by hand (or a scene) starts the count over; off by default |
layer (as in state.json layers: autopilot { enabled, mode, every, on, cells, count }) |
scene |
action? (list (the default), capture: save the mix now into slot, launch: at the next point of quantize? (default bar; off now), rename, clear), slot (1–8; not for list), name?, glide_beats? (0–32: opacities, crossfader, master, fade levels and palette glide this long) — a scene is the mix state (each layer's cell and mix settings, crossfader, master level, post FX picks / levels / layers, palette), not node params; at its point each layer launches its cell with its own quantize / transition |
scenes (slots: per slot null or { slot, name, glide_beats, cells }, active, pending, glide progress; also in state.json); launch: pending, at_beat |
timeline |
action? (list (the default), play (from_bar?, default 1: starts on the next bar line; cues before from_bar are skipped), stop, rec (on?, default true; on while stopped also plays from bar 1: scenes, cells and triggers launched by hand — scene, launch, trigger included — become cues where they land, from bar 1 on; a trigger keeps its strength), add (bar, beat? (1–4.75, snapped to quarters, default 1) and one of scene (1–8), cell, trigger (1–4; value? = its strength, default 1), knob (layer1–layer4 opacity, master, crossfader, fade1–fade8) + value? (0–1, default the value now)), move (index, bar, beat?), remove (index), clear) — a cue sheet for a fixed set; a cue on the same beat with the same target (any scene, the same layer, pad or knob) replaces the old one; a cell cue switches on its beat whatever the layer's quantize |
timeline (state: stopped / armed / playing, recording, position (bar.beat.sixteenth from bar 1 — before it, -beats, or the bar before from_bar), beats, start_beat (the clock's beat count at bar 1), next (index), cues: [{ index, at, position, bar, beat, label, scene / cell / trigger + strength / knob + value }]; also in state.json); add / move: index |
ask |
prompt?, node? (rewrite that node's shader; a built-in node gets its own copy first) or edit? (the selected node), else a new GLSL node in the cell being edited; run? (start the user's agent command from the app, like the SHADER panel's ASK — one at a time), stop? (stop it) — for people asking for a shader in words; an agent working here already writes the files itself |
node, shader_file (the file to write), file (the request in agent/requests/), request, ask (state: idle / running / done / failed / stopped, node, file, seconds, error, log; also in state.json) — without a prompt just ask |
remote |
enabled?, port? (0: any free port), new_token? — the remote: a page in a phone's browser on the LAN that plays the show (launch, scenes, triggers, tempo, faders, the timeline's transport) through the same commands; the address carries a key |
remote (enabled, running, port, url with the key, clients, error; also in state.json) |
trigger |
pad (1–4), strength? (0–1, default 1) — fire it now, like its key or MIDI pad |
triggers (the 4 envelopes now) |
crossfader |
position? (0 = side A … 1 = side B), curve? (linear, smooth: eased ends, cut: both sides full until the last 5 %), layer? + side? (1–4; a, thru, b) — layers on A show toward 0, on B toward 1, THRU always (the default) |
crossfader (position, curve, gain_a, gain_b; also in state.json, each layer's side in layers) |
arrange |
cell? (lay the nodes out in columns) |
|
undo / redo |
cell? (the cell's edit history, like ⌘Z / ⇧⌘Z; each command is one step) |
can_undo, can_redo; node ids change when nodes were added / removed |
snapshot |
node? or cell? (its Out; default: the master output) or mapped: true (the mapped output, see mapping), timeout_ms? (default 5000) |
png, width, height, pipeline, error, engine |
mapping |
mode? ("surfaces": slices of the show warped onto surfaces after the graph; "atlas": the whole graph draws in the sending layout of set_slot's slots, every node at its pixels' world position, so content runs on across slots without seams — the first switch adds a slot of the whole frame), size? ("window": the output window's, 1920×1080 without one; or [w, h]; in atlas mode also the node size × render scale), reset? (one full-frame master surface: mapping off), test_pattern? (send a grid with each surface's / slot's number and corners 1–4 instead of the show), load? (a saved mapping replaces this one, first), save_as? (save it, last: presets/mappings/<name>.ron in the data dir — a venue's mapping for any show) |
presets (saved mapping names), mapping (mode, active, test_pattern, size, mapped_size, node_size, world_size, surfaces, slots; also in state.json) |
set_slot |
slot? (1-based; none = add one), remove?, name?, enabled?, atlas? ([x0, y0, x1, y1] in mapped-output UV: where it sits in the sending layout), center? ([x, y] in world UV: the show's own frame), size? ([w, h] in world UV, before turning), angle? (degrees clockwise, kept in -180..180), flip? (mirrored left to right), one_to_one? (set size so the atlas rect gets the world's pixels 1:1, after atlas) — atlas mapping slots (mapping mode=atlas): each sends the world rect it shows, drawn there by the nodes themselves (GLSL nodes: world_uv() / sample_world(), see the shader conventions); the first slot holding a world point is the one effects read |
slot, mapping, warning? |
set_surface |
surface? (1-based; none = add one), remove?, name?, enabled?, source? ("master" or a layer 1–4), input? ([x0, y0, x1, y1] or corners TL TR BR BL in source UV: a perspective slice), input_turn? (quarter turns clockwise), input_flip? ("horizontal" / "vertical"), output? (corners TL TR BR BL in output UV, convex), opacity?, brightness? (0–2), feather? (0–0.5), mask? ({ points: [[x, y], …] in output UV (3–32; fewer removes it), mode?: "show_inside" | "hide_inside", feather?: px }) — projection mapping surfaces, drawn in order; the output window and Syphon / Spout Output show the mapped output while the mapping isn't the default |
surface, mapping, warning? |
inspect |
nodes? (ids; default: the edited cell) |
current param values (with bindings applied), SIG outputs, engine (clock, audio level / bands / hits, triggers, meters: LUFS, true peak, peak / RMS L R, correlation, width, balance, pitch, key) |
view |
tab? (editor performance), side? (node shader palette audio), levels? / perf? / packs? / remote? (open / close those windows), output? (window off, or fullscreen / fullscreen N: borderless on display N, default 1 — the output window), preview? (master mapped: what the PERFORMANCE output preview shows; state.json performance_preview) |
|
midi |
note or cc (0..127), value? (velocity / controller value, default 127; a note with 0 releases), channel? (1..16, default 1), device? (input name as in state.json midi.devices, default agent) — handled like a message from that device: its mappings act (holds don't stay down) |
|
sequencer |
applied in this order: preset? (a built-in pattern — default, 4x4, house, trance, dnb, … — or a saved one), rows? (4 rows of 16 x / ., spaces ignored: t1 kick, t2 snare / clap, t3 hats, t4 accent), clear?, set? ([{"pad": 1..4, "step": 1..16, "on"?: bool}], on left out toggles), enabled?, save_as? (save as a user pattern) |
enabled, rows, preset (the built-in pattern it matches, if any) |
drop_media |
cell, path? / paths? / media? (library ids) — adds a Video (Image for image files) node per file and connects it to the cell's Out (a video with a tempo in the library gets it as bpm, with auto sync on) (its other nodes stay); more files go to the following cells of the layer. Like dragging media from the media browser or Finder / Explorer onto a PERFORMANCE cell; one undo step per cell |
nodes |
media_browser |
open? (bool) — the media browser window |
open |
library_add_root / library_remove_root |
path (a folder: scanned recursively and watched) / root (its id) |
roots (id, path, count, missing) |
library_status |
rescan?, hap? (off, auto: HAP / HAP Alpha copies of videos, made beside them as <name>.hap.mov (in the cache when the folder is read-only) and played on the GPU; high: HAP R) |
status (media, pending: still to probe / thumbnail, hap_pending, converting, hap_mode, scanning, missing, …), roots |
library_query |
text? (words matched in names, folders, tags), tags_all? / tags_any? / tags_none? (names), kind? (video image), folder? + recursive?, min_width? max_width? min_height? max_height?, min_short_side? (720 = 720p or more either way up), min_duration? max_duration? (s), min_bpm? max_bpm? (videos with a tempo set), orientation? (landscape portrait square), codec?, sort? (name modified added duration resolution size last_used bpm), desc?, include_missing?, limit? (50) |
total, items (id, path, name, kind, width, height, duration, fps, codec, tags, bpm, hap, hap_path, …) |
library_tag / library_untag |
media? (ids) or paths?, tag |
items with their tags |
library_set_bpm |
media? (ids) or paths?, bpm (40–240, clamped; null clears) — the tempo of videos (images are skipped), like the media browser's bpm field; drop_media of a video with a tempo sets its Video node's bpm and turns auto sync on |
items (id, path, bpm) |
state |
writes state.json now |
例: {"cmd": "add_glsl", "name": "tunnel", "out": true} の次に {"cmd": "snapshot", "cell": {"layer": 1, "slot": 1}}。