moebius-plugins
/moebius-plugins
Pisze wtyczkę Moebius, czyli decydenta, który odpowiada na punkt decyzyjny skryptu kolumny, gdy decyzja wymaga kodu.
- Autor
- Code000-211 ↗
- Repozytorium
- Moebius ↗
- Licencja
- Apache-2.0
- Ostatnia zmiana repozytorium
- 13.11.2026
Ocena i bezpieczeństwo
- Pliki w paczce
- 1
- Skrypty
- 0
- Komentarze HTML
- 0
- Adresy URL w SKILL.md
- 0
Brak sygnałów. Repozytorium zmienione 13.11.2026, bez odwołań do wycofanych modeli i API.
Apache-2.0, otwarta: można używać i zmieniać, z zachowaniem licencji i informacji o zmianach.
Co robi i kiedy
Pisze wtyczkę Moebius, czyli decydenta, który odpowiada na punkt decyzyjny skryptu kolumny, gdy decyzja wymaga kodu.
Oryginalny opis (EN)
Write a Moebius plugin, a decider compiled in or run as its own process, that answers a decision point a column script asks with moebius.decide. Use it when a decision needs code - a lookup, a policy too large for Luau, a check against another system - or the person asks for a plugin, a decider or the plugin API.
Jak działa
- Steps
- Example
- As its own process
- Try it
- What can go wrong
- Details
Podgląd SKILL.md
---
name: moebius-plugins
description: Write a Moebius plugin, a decider compiled in or run as its own process, that answers a decision point a column script asks with moebius.decide. Use it when a decision needs code - a lookup, a policy too large for Luau, a check against another system - or the person asks for a plugin, a decider or the plugin API.
---
# Decider plugins
Goal: a Rust type that answers one decision kind, tested with cargo, registered in the server and asked from a column
script. A plugin is compiled into the `moebius` binary, so that work happens in a checkout of Moebius itself and the
person rebuilds and restarts the server; or it is a program of its own, in any language, named under `[[plugins]]` in
`moebius.toml`, which needs only a restart. Prefer the program when the person does not build Moebius themselves.
## Steps
1. Implement `moebius_plugin_api::Plugin`: `manifest()` returns its `name`, `version` and `kinds: vec![Kind::Decider]`;
`call(call)` answers the method `decide`. Its `params` are a `DecideRequest` (`kind`, `context` of text to text with
secrets already redacted, `options`); return a `Decision` (`choice`, exactly one of the options, a `reason` in a
sentence, `by` optionally) as JSON. Return `PluginError::BadParams` for params that are not a `DecideRequest` and
`PluginError::Failed` for anything you cannot answer. It may be called from several threads at once.
2. Test it through a `Host`, as the core calls it: `Host::new(Duration::from_secs(5))`, `host.add(MyPlugin)`, then
`host.decide("my-plugin", &request)` and assert the choice. Cover every option and a kind it does not take.
3. Register it in `Server::new` (`crates/moebius-core/src/server/mod.rs`) next to the guard with `host.add(...)`, and route
the kind after `App::new` with `app.decisions.route("start_card", "my-plugin")`. Never route `tool_call`: that
removes the guard, the built-in rules and the teacher.
4. Ask it from a column script with `moebius.decide(kind, context, options, fail_closed)` (see the `moebius-workflows`
skill).
## Example
The working decider is `crates/moebius-plugin-api/examples/allow_reads.rs`; start from it. Its heart:
```rust
impl Plugin for AllowReads {
fn manifest(&self) -> Manifest {
Manifest { name: "allow-reads".into(), version: "0.1.0".into(), kinds: vec![Kind::Decider] }
}
fn call(&self, call: Call) -> Result<Value, PluginError> {
if call.method != "decide" {
return Err(PluginError::Failed(format!("no method {:?}", call.method)));
}
let request: DecideRequest = serde_json::from_value(call.params)
.map_err(|e| PluginError::BadParams(e.to_string()))?;
let tool = request.context.get("tool").map_or("", String::as_str);
let (choice, reason) = if READ_ONLY.contains(&tool) {
("allow", format!("{tool} only reads"))
} else {
("refuse", format!("only reads are allowed, not {tool}"))
};
let decision = Decision { choice: choice.into(), reason, by: None };
serde_json::to_value(decision).map_err(|e| PluginError::Failed(e.to_string()))
}
}
```
## As its own process
The program writes its manifest as its first line on standard output, then answers each call it reads on standard
input with a reply carrying the call's `id`, one JSON object per line; nothing else may go to standard output, and it
exits when standard input closes. In Rust, `moebius_plugin_api::serve(&plugin, stdin, stdout)` does this for any
`Plugin` (see `crates/moebius-plugin-api/examples/allow_reads_process.rs`); `guide/plugins.md` has a Python decider.
Name it in `moebius.toml`, with the kinds it answers in `decides`, and ask the person to restart the server:
```toml
[[plugins]]
name = "start-gate"
path = "python3"
args = ["plugins/start_gate.py"]
decides = ["start_card"]
```
`"$MOEBIUS" api GET /v1/plugins` shows its `process.state` (`running`, or `restarting` with the `error` why it stopped),
and its standard error is in `<data_dir>/plugins/<name>.log`. Test it by piping a call into it:
`echo '{"type":"call","id":1,"call":{"kind":"decider","method":"decide","params":{"kind":"start_card","context":{"title":"[wip] x"},"options":["start","hold"]}}}' | python3 plugins/start_gate.py`.
## Try it
```sh
cargo run -p moebius-plugin-api --example allow_reads
cargo test -p moebius-core
cargo clippy --workspace --all-targets -- -D warnings
```
Run the tests you wrote and read their output. Then say what the person has to do: merge, rebuild `moebius`, restart the
server (`"$MOEBIUS" server restart` only when they ask), and commit the column script that asks the kind.
## What can go wrong
The host turns every failure into a refusal, and the script gets its fail-closed option with a reason that starts
`refused:`: no route for the kind (`no decider answers`), more than 30 seconds, a panic, an error, a `choice` that is
not one of the options, or a kind not in the manifest; for a process also a crash, a line that is not a reply, or a
process that is not running (`is not running: <why>`). A script runs every tick, so a held card is decided again every
tick; keep `call` fast.
## Details
In the `moebius` skill: `guide/plugins.md` (the whole walk-through with a `start_card` decider) and
`reference/plugin-api.md` (every type, the host's guarantees and the wire format of a plugin process).
Wersje
W bazie nie ma innych skilli o nazwie moebius-plugins.
Migawka bazy z 13.11.2026 · wersja paczki 301ee1591510 (skrót SHA-256 całej paczki)
Pobrania w ostatnich 30 dniach: 0 · ranking
Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.
Podobne skille
- 90moebius-report
Zgłasza poprawkę lub problem w Moebius do oficjalnego repozytorium jako pull request albo issue, po wcześniejszym zapytaniu użytkownika. - 100moebius-workflows
Pisze skrypty kolumn w Luau i tablicę Kanban repozytorium, gdy karty mają być traktowane inaczej niż domyślnie. - 100decikit
Obsługuje projekty Decider toolkit: potoki decyzyjne z funkcji Pythona i wersjonowanych dokumentów JSON, drzewa decyzyjne, zestawy reguł, tablice decyzyjne, scorecardy, eksperymenty i rozszerzenie VS Code. - 100writing-plugins
Pomaga pisać, budować i publikować wtyczki Nuclear: strukturę, manifest, punkt wejścia, typy dostawców i dostępne API. - 100godot-moebius-rendering
Przerabia projekty 3D Godot w styl inspirowany Moebiusem: profile artystyczne, przebudowę modeli i osobne kolory i kontury. - 100neko-plugin
Tworzy, zmienia, sprawdza i uruchamia pluginy N.E.K.O, w tym plugin.toml, interfejs i kontrakty systemu wtyczek.