Metadata-Version: 2.5
Name: dikolab-horde-sdk
Version: 0.0.2
Summary: Write a horde plugin: the boilerplate and the language-agnostic algorithms.
Project-URL: Homepage, https://diko316.gitlab.io/dikolab-horde/
Project-URL: Documentation, https://diko316.gitlab.io/dikolab-horde/
Project-URL: Funding, https://paypal.me/dikolab
Author-email: Diko TechSlave <diko316@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: horde,json-rpc,monorepo,plugin,sdk
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: dikolab-horde-common>=0.0.2
Requires-Dist: dikolab-horde-ipc>=0.0.2
Description-Content-Type: text/markdown

<img src="https://diko316.gitlab.io/dikolab-horde/assets/horde-logo.png" alt="horde" width="140">

# dikolab-horde-sdk

**Write a horde plugin without writing any protocol code.** A plugin is a
separate process that speaks JSON-RPC over stdio: it cannot touch the disk, spawn
a program, or print to the terminal — it asks horde, and horde decides. The SDK
is the side of that conversation you would otherwise write by hand.

Install this if you are writing a plugin. To *use* horde, install
[dikolab-horde](https://pypi.org/project/dikolab-horde/).

> **Status: alpha.** `0.0.2` ships `Plugin`, `Context`, `Outcome`, the fake
> horde for testing, and the `horde-sdk` CLI. It accepts commands beyond the
> ten, which is the release `dikolab-horde-plugin-c` was waiting for. The
> interfaces may still move.

## Prerequisites

- Python 3.11 or newer
- [horde](https://pypi.org/project/dikolab-horde/), to run your plugin

## Getting started

```sh
uv add dikolab-horde-sdk
```

It brings `dikolab-horde-common` and `dikolab-horde-ipc` with it, and
`dikolab_horde_sdk.testing` ships a fake horde — one install is enough to write
a plugin *and* test it.

### A whole plugin

```python
from dikolab_horde_sdk import Outcome, Plugin

plugin = Plugin(name="mytool", requires=["mytool"])


@plugin.command("lint", tools=("ruff", "mypy"))
def lint(ctx, argv) -> Outcome:
    return ctx.run_chain([("ruff", "check"), ("mypy",)], ctx.target(argv))


plugin.main()
```

`main()` claims `stdout`, parses argv, performs the handshake, and serves until
horde says stop. It guarantees **exactly one** completion message whatever your
handler did — including raising.

**You maintain no lists.** `commands` is the handler table and `requires` is the
union of what those handlers declared they invoke, so the two can never disagree.

### Effects go through the context

```python
@plugin.command("create")
def create(ctx, argv) -> Outcome:
    ctx.mkdir(["python/greeter/src"])
    ctx.write("python/greeter/pyproject.toml", rendered)
    result = ctx.run(["uv", "build"], cwd="python/greeter")
    return Outcome(exit_code=result.exit_code)
```

Reading: `read`, `read_all`, `entries`, `tree`. Writing: `write`, `write_all`,
`mkdir`, `move`, `delete`, `symlink`. Tools: `run`, `run_chain`. Never use
`open()` — a write horde did not broker is one it cannot undo.

### Testing needs no filesystem

```python
from dikolab_horde_sdk import testing


def test_it_runs_both_linters() -> None:
    horde = testing.Workspace()
    lint(horde, [])
    assert horde.ran == [["ruff", "check"], ["mypy"]]
```

Your handler runs for real; every effect is recorded instead of performed. The
workspace keeps `tree`, `ran`, `links`, `printed` and more, so an assertion
names the one it means.

### Develop without a workspace

```sh
horde-sdk init                # scaffold a plugin project
horde-sdk stub build          # the JSON horde would send
horde-sdk mock greeter build  # run your handler against a fake horde
```

**The authoring guide, the twenty protocol methods, and API examples:**
https://diko316.gitlab.io/dikolab-horde/authoring/

## Documentation

- [Authoring a plugin](https://diko316.gitlab.io/dikolab-horde/authoring/) — the tutorial track
- [The protocol](https://diko316.gitlab.io/dikolab-horde/authoring/protocol/) — the twenty methods in five namespaces
- [API reference](https://diko316.gitlab.io/dikolab-horde/dikolab-horde-sdk/api/) — with runnable [examples](https://diko316.gitlab.io/dikolab-horde/dikolab-horde-sdk/api/examples/)
- [Manual](https://diko316.gitlab.io/dikolab-horde/dikolab-horde-sdk/manual/) · [Release notes](https://diko316.gitlab.io/dikolab-horde/dikolab-horde-sdk/release-notes/)

## Support

If horde saves you time, you can support its development:
https://paypal.me/dikolab

---

© 2025–2026 dikolab. Released under the MIT License.
