layer3/client.ts
A client for builders who prefer the sharp edges visible.
exine is a code-shaped ECCP client. It keeps keyboard-first workflows, structured output, and plugin hooks close at hand so developers and operators can compose their own interface without rewriting the protocol.
exine / host shell
$ exine login --homeserver https://node.eccp.dev
$ exine rooms watch --tag incident-response --format ndjson
$ exine plugins enable bot-host --capability rooms:write
$ exine sync tail --since state://shadow-room/main
CLI-native
Pipe room events into scripts, tail sync state, and automate operational workflows from the same client surface.
Plugin host
Extensions can subscribe to events, add commands, and host automation without forking the entire application.
Composable output
Structured results make exine useful inside CI systems, moderation dashboards, and custom bot operators.
Bot host capability in plain TypeScript.
Plugins can register commands, inspect federation peers, and host automation inside the client with explicit capability grants instead of hidden side channels.
plugins/ops-bot-host.ts
TypeScript
import { definePlugin } from "@eccp/exine-sdk";
export default definePlugin({
name: "ops-bot-host",
capabilities: ["rooms:read", "rooms:write", "bot:host"],
async activate(host) {
host.on("message.received", async (event) => {
if (!event.room.tags.includes("ops")) return;
await host.bot.reply(event.roomId, {
body: \`ack \${event.eventId}\`,
shadow: true
});
});
await host.commands.register("peers", async () => {
const peers = await host.federation.listPeers();
return peers.map(({ serverName, latencyMs }) => ({
serverName,
latencyMs
}));
});
}
});Why exine exists
ECCP needs a client that treats automation, observability, and extensibility as product features. exine is that Layer 3 surface.