{"id":51033722,"url":"https://github.com/launchapp-dev/animus-plugin-sdk-ts","last_synced_at":"2026-06-22T03:01:52.444Z","repository":{"id":363353049,"uuid":"1252841581","full_name":"launchapp-dev/animus-plugin-sdk-ts","owner":"launchapp-dev","description":"TypeScript SDK for authoring Animus plugins (subject backends, providers, triggers, transports, log storage)","archived":false,"fork":false,"pushed_at":"2026-06-08T13:53:54.000Z","size":193,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-08T15:29:53.367Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://animus-docs.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/launchapp-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-28T23:34:43.000Z","updated_at":"2026-06-08T13:54:04.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/launchapp-dev/animus-plugin-sdk-ts","commit_stats":null,"previous_names":["launchapp-dev/animus-plugin-sdk-ts"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/launchapp-dev/animus-plugin-sdk-ts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/launchapp-dev%2Fanimus-plugin-sdk-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/launchapp-dev%2Fanimus-plugin-sdk-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/launchapp-dev%2Fanimus-plugin-sdk-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/launchapp-dev%2Fanimus-plugin-sdk-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/launchapp-dev","download_url":"https://codeload.github.com/launchapp-dev/animus-plugin-sdk-ts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/launchapp-dev%2Fanimus-plugin-sdk-ts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34632723,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-22T02:00:06.391Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-22T03:01:51.614Z","updated_at":"2026-06-22T03:01:52.438Z","avatar_url":"https://github.com/launchapp-dev.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @launchapp-dev/animus-plugin-sdk\n\nTypeScript SDK for authoring [Animus](https://github.com/launchapp-dev/animus-cli) plugins. Ship a plugin for **any** Animus role in TypeScript without reading the Rust source.\n\n\u003e Status: **0.1.x, protocol 1.1.0.** All plugin roles are wired (subject, provider, trigger, transport, log-storage, queue, workflow-runner, durable-store, memory-store, notifier). Types are generated as **Zod schemas** from the Rust protocol crates — Rust is the single source of truth.\n\nThis repo is the canonical home of the TypeScript plugin SDK. The Rust\norchestrator lives in\n[`launchapp-dev/animus-cli`](https://github.com/launchapp-dev/animus-cli); this\npackage is published independently to npm so plugin authors can depend on a\nstable TypeScript contract without pulling the Rust toolchain.\n\n## Install\n\n```bash\nnpm install @launchapp-dev/animus-plugin-sdk\n# or\npnpm add @launchapp-dev/animus-plugin-sdk\n```\n\nRequires Node 20+.\n\n## Layered, subpath imports\n\nThe package is one publishable module with **subpath exports** that mirror the\nRust protocol crates. Import `definePlugin` and the base/runtime surface from\nthe root; import a role's contract + generated Zod types from its subpath.\n\n```ts\nimport { definePlugin, PluginKind, PROTOCOL_VERSION } from '@launchapp-dev/animus-plugin-sdk';\n\n// Role contracts + generated Zod schemas + role helpers:\nimport type { SubjectBackend } from '@launchapp-dev/animus-plugin-sdk/subject';\nimport type { Provider } from '@launchapp-dev/animus-plugin-sdk/provider';\nimport type { TriggerBackend } from '@launchapp-dev/animus-plugin-sdk/trigger';\nimport type { TransportBackend } from '@launchapp-dev/animus-plugin-sdk/transport';\nimport type { LogStorageBackend } from '@launchapp-dev/animus-plugin-sdk/log-storage';\nimport type { Queue } from '@launchapp-dev/animus-plugin-sdk/queue';\nimport type { WorkflowRunner } from '@launchapp-dev/animus-plugin-sdk/workflow-runner';\nimport type { DurableStore } from '@launchapp-dev/animus-plugin-sdk/durable-store';\nimport type { MemoryStore } from '@launchapp-dev/animus-plugin-sdk/memory-store';\nimport type { Notifier } from '@launchapp-dev/animus-plugin-sdk/notifier';\n\n// Generated Zod schemas are exported alongside the types, e.g.:\nimport { AgentRunRequestSchema } from '@launchapp-dev/animus-plugin-sdk/provider';\nimport { SubjectFilterSchema, WireSubjectSchema } from '@launchapp-dev/animus-plugin-sdk/subject';\n```\n\nThe base/runtime layer (root export) holds the wire transport, handshake, the\nJSON-RPC loop, the manifest/capabilities builder, error codes, and\n`PROTOCOL_VERSION`. Each subpath layer adds that role's generated Zod\ntypes, its role-contract interface(s), and role-specific helpers. The root\nexport also re-exports every role contract for backward compatibility.\n\n## Rust is the source of truth (Zod codegen)\n\nAll wire types are generated as Zod schemas from the Rust-emitted JSON Schema\nbundles vendored under `schemas/\u003ccrate\u003e/_all.json`. Each protocol crate becomes\na module under `src/types/generated/\u003ccrate\u003e.ts`:\n\n```ts\nexport const SubjectFilterSchema = z.object({ /* ... */ }).passthrough();\nexport type SubjectFilter = z.infer\u003ctypeof SubjectFilterSchema\u003e;\n```\n\nThe runtime uses these schemas to **validate inbound params** before routing to\nyour `impl` — a malformed request gets a `-32602` (`invalid_params`) reply with\nthe Zod issue list in `error.data`, not a crash.\n\nRegenerate after updating the vendored schemas:\n\n```bash\nnpm run codegen        # emit src/types/generated/*.ts from schemas/*/_all.json\nnpm run codegen:check  # CI drift guard — fails if committed output is stale\n```\n\nOpen-string Rust enums (`PluginKind`, `TriggerActionHint`, `TriggerAckStatus`)\nwiden to a literal-union plus `z.string()` so you get autocomplete on the known\nvalues while unknown values still validate (forward-compat). JSON-RPC envelope\nfields (`params`/`result`/`payload`/`data`/`id`) stay permissive (`z.unknown()`).\n\n## Hello world: a subject backend\n\n```ts\n#!/usr/bin/env node\nimport { definePlugin } from '@launchapp-dev/animus-plugin-sdk';\n\ndefinePlugin({\n  kind: 'subject_backend',\n  name: 'animus-subject-hello',\n  version: '0.1.0',\n  description: 'One hard-coded subject — proof the SDK works',\n  subject_kinds: ['task'],\n  impl: {\n    // Return `subjects` (not `items`). The SDK auto-fills `fetched_at` and\n    // backstops missing `status`/`created_at`/`updated_at` for demos.\n    list: () =\u003e ({\n      subjects: [\n        {\n          id: 'task:HELLO-1',\n          kind: 'task',\n          title: 'Hello from TS!',\n          status: 'ready',\n          created_at: new Date().toISOString(),\n          updated_at: new Date().toISOString(),\n        },\n      ],\n    }),\n    // `kind` is parsed from the inbound method (e.g. `subject/get`) and supplied via ctx.\n    get: ({ id }, ctx) =\u003e ({\n      id,\n      kind: ctx.kind,\n      title: 'Hello from TS!',\n      status: 'ready',\n      created_at: new Date().toISOString(),\n      updated_at: new Date().toISOString(),\n    }),\n  },\n}).run();\n```\n\nThe Animus daemon dispatches subject calls as canonical `subject/\u003cverb\u003e` (with\nlegacy `\u003ckind\u003e/\u003cverb\u003e` routes still honored) — the SDK routes those to your\n`impl` automatically and exposes the resolved kind via `ctx.kind`.\n\n```bash\nanimus plugin install ./pack.toml\nanimus subject list --kind task\n```\n\n## A provider (streaming)\n\n```ts\nimport { definePlugin } from '@launchapp-dev/animus-plugin-sdk';\n\ndefinePlugin({\n  kind: 'provider',\n  name: 'animus-provider-demo',\n  version: '0.1.0',\n  description: 'Echo provider',\n  impl: {\n    run: async (params, ctx) =\u003e {\n      await ctx.stream.thinking({ text: 'planning…' });\n      await ctx.stream.output({ text: `echo: ${params.prompt}` });\n      return {\n        session_id: 'sess-1',\n        exit_code: 0,\n        output: `echo: ${params.prompt}`,\n        metadata: [], tool_calls: [], tool_results: [], thinking: [], errors: [],\n        duration_ms: 12, backend: 'demo:1.0.0',\n        tokens_used: { input: 0, output: 0, cached: 0, cache_writes: 0 },\n      };\n    },\n  },\n}).run();\n```\n\n`ctx.stream` emits the `agent/output|thinking|toolCall|toolResult|error`\nnotifications; the resolved return value is the final `AgentRunResponse`.\n\n## What the SDK does for you\n\n- Handles `--manifest` / `--help` CLI shortcuts (the host calls `--manifest` during install).\n- Runs the newline-delimited JSON-RPC 2.0 loop on stdin/stdout (UTF-8 safe across chunk boundaries; serialized write queue; EOF-as-exit).\n- Implements `initialize`, `$/ping`, `health/check`, `shutdown`, `exit`.\n- Validates the host's `protocol_version` (strict major-version match) and tolerates the additive v1.1.0 `init_extensions` field.\n- **Validates inbound domain params with the generated Zod schemas** and routes them to your `impl`.\n- Advertises only the methods your `impl` can actually serve, so the host's preflight never misroutes.\n- Emits the v1.1.0 `kind_capabilities` map for the new kinds; leaves it empty for v1.0.0 kinds so wire output stays byte-identical.\n- Returns `-32001` (`method_not_supported`) for optional methods you didn't implement, and `-32601` (`method_not_found`) for unknown methods.\n\nStdout is reserved for protocol frames. The SDK writes diagnostics to stderr; you should too.\n\n## Roles\n\nAll roles from the protocol spec are wired. Advertise only the methods you\nimplement — optional methods you omit return `-32001` so the host can fall back.\n\n| Kind                  | Subpath              | Methods wired |\n| --------------------- | -------------------- | ------------- |\n| `subject_backend`     | `/subject`           | `subject/list`, `subject/get`, `subject/schema`, optional `subject/create`, `subject/update`, `subject/status`, `subject/next`, `subject/delete`; legacy `\u003ckind\u003e/*` routes |\n| `provider`            | `/provider`          | `agent/run`, optional `agent/resume`, `agent/cancel`; streams `agent/output|thinking|toolCall|toolResult|error` |\n| `trigger_backend`     | `/trigger`           | `trigger/watch` (→ `trigger/event` notifications), `trigger/schema`, optional `trigger/ack` |\n| `transport_backend`   | `/transport`         | `transport/start`, `transport/shutdown`, `transport/schema` |\n| `log_storage_backend` | `/log-storage`       | `log_storage/store`, `log_storage/schema`, optional `log_storage/query`, `log_storage/tail` (→ `log_storage/event`) |\n| `queue`               | `/queue`             | `queue/enqueue|list|lease|stats|hold|release|drop|mark_assigned|completion|reorder` |\n| `workflow_runner`     | `/workflow-runner`   | `workflow/execute`, `workflow/run_phase` |\n| `durable_store`       | `/durable-store`     | `durable/begin_workflow_run|begin_step|commit_step|abandon_step|recover_in_flight|query_run` |\n| `memory_store`        | `/memory-store`      | `memory/put|get|query|list_scopes|delete_scope` |\n| `notifier`            | `/notifier`          | `notifier/notify`, `notifier/schema`, optional `notifier/flush` |\n\n## Scripts\n\n```bash\npnpm install\npnpm run codegen        # regenerate Zod modules from vendored schemas\npnpm run codegen:check  # drift guard\npnpm run build          # tsc → dist/ (all subpath entrypoints)\npnpm run typecheck      # strict-mode tsc\npnpm test               # vitest\n```\n\n## License\n\nElastic License 2.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flaunchapp-dev%2Fanimus-plugin-sdk-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flaunchapp-dev%2Fanimus-plugin-sdk-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flaunchapp-dev%2Fanimus-plugin-sdk-ts/lists"}