ACRYL

Agentic apps from day one

ACRYL, the IDE that writes its own plugins, and ACRYL Blends, the framework it is built with.

ownMyAI · Vienna · 20 October 2026 · acryl.dev

Join the event: RSVP on Luma

Tuesday 20 October 2026 · 18:00 to 21:00
IT-Services der Sozialversicherung, Johann-Böhm-Platz 1, 1020 Wien
luma.com/2mxma8s0

A new kind of software: composable software 2.0, agentic from day one

It writes itself

Ask for a feature and the agent inside builds it as a plugin, live, while you keep working.

It repairs itself

The agent tests what it built, finds what is wrong and fixes it; a broken plugin is reverted without a trace.

It adapts to its use

Two people start from the same app and end up with two different apps, each shaped by how they work.

It is made of parts

Small plugins you can add, swap, remove, version, share and reuse, so nothing has to be rebuilt from zero.

And it is yours: it runs on your machine, with your data, from files you can commit to your own git.

The SaaSpocalypse

When agents write code, any product that is not agentic can be copied, rebuilt cheaper, or open-sourced.

Features are no longer a moat

A competitor's agent rebuilds your feature list in a weekend.

Fixed software ages instantly

Every user wants it slightly different; a fixed product serves the average user, and no one exactly.

What stays valuable

Software that keeps evolving with each user, with an agent inside that knows the app and grows it.

Cordis

The plugin kernel under DeepSeek Harness, and under everything in ACRYL.

A kernel that grew up in chatbots

  • Koishi: a cross-platform chatbot framework (Discord, Telegram, Matrix and more) with 4,000+ community plugins
  • Cordis (2022): its plugin kernel, extracted as a meta-framework. It knows nothing about LLMs, agents or tools
  • DeepSeek Harness forked it (@deepseek-ai/cordis) and built the agent on top: model adapters, tools, sessions, sandboxes, the UI, all plugins
  • Backed by a paper: A Programming Paradigm for Spatiotemporal Composability, Peking University and DeepSeek-AI
Koishichatbots, years of production plugins
Cordisthe plugin kernel, extracted
DeepSeek Harnessan agent made of Cordis plugins
ACRYLapps made of Cordis plugins, shareable as Blends

The session lives longer than its parts

A group chat or a coding session runs for days. Its capabilities arrive, leave and get replaced while it runs. Cordis guarantees two things so that never breaks it:

Temporal composability

When a component leaves, everything it did to the shared environment is reverted: routes, tools, timers, subscriptions. No residue, and unrelated work survives.

Spatial composability

Components declare what they need. A consumer activates only when its requirements exist, and stops cleanly before its provider is withdrawn.

component = requirements + provisions + effects with undo

One plugin, mounted: a Fiber with its own Context

Plugina definition:name, inject, apply()ctx.plugin()Fiberone mounted, live instancelifecycle stateits own child Contexteffect disposersdependency snapshotchild FibersownsContext (ctx)what the plugin can see and change· resolves services by name· owns effects, listeners, plugins· dispatches typed events· carries scope: isolate, interceptOne plugin can be mounted many times: each mount is its own Fiber with its own Context.

Context: the world a plugin may see and change

  • Find capabilities by name: ctx.llm, ctx.tools
  • Own what it creates: ctx.effect, ctx.plugin, ctx.on
  • Talk through typed events: ctx.emit, ctx.waterfall
  • Scope the world below it: extend for metadata, isolate for a separate service, intercept for scoped config

Isolation changes which provider a name resolves to. It is not a security sandbox.

root ctxtools · llm · shellplugin ctxextend(): inherits allyour pluginctx.tools worksgroup Aisolate('shell')group Bisolate('shell')LocalShelltimeout 5 sLocalShelltimeout 60 sagent Actx.shell = A'sagent Bctx.shell = B's

Fiber: the lifecycle of one mounted plugin

PENDINGwaiting for injectdeps readyLOADINGapply(ctx) runsapply() finishedACTIVEeffects ownedapply or config errorFAILEDerror reportedprovider changed, restart, updateUNLOADINGeffects revertedrequirements gone: back to waitingstill met: new episodedispose()DISPOSEDremoved for good

PENDING is not an error: the plugin is mounted and waiting for its environment. Losing a dependency sends it back to PENDING, not to DISPOSED.

A plugin waits for what it needs, and leaves no trace

plugin my-tool · inject: ['llm']
PENDING
llm service: missing
    effects owned by my-tool

      Every registration is an effect with an inverse. Unloading runs the inverses in reverse order. States: PENDING, LOADING, ACTIVE, FAILED, UNLOADING, DISPOSED.

      Services and inject: depend on a name, not on a provider

      ctx.llma named servicellm providerDeepSeek adapterprovidessummarizerinject: ['llm']chat agentinject: ['llm']resolvesresolvesllm provideranother model, replacing itswap inReplace the provider: every consumer unloads and reactivates against the new one. No restart, no stale reference.

      Events: five ways to dispatch

      emitsync broadcastctxL1L2L3every listener runs now; results ignoredparallelawait all at oncectxL1L2L3all listeners run concurrently; wait for every oneserialfirst answer winsctxL1L2L3returns a value: stopawait each in turn; a value stops the chainbailsame, synchronousctxL1L2L3returns a value: stopfirst non-empty value is the resultwaterfallwraps a defaultctxL1L2default handlereach listener wraps the next; next() continues

      Use a service call when you need one answer from a known capability; use an event when the producer should not know who listens.

      Waterfall: middleware around a default

      Each listener receives the input and next. Call next() to continue to the inner layer; return without it to answer or veto.

      An observer that logs, measures or annotates must call next(). Event listeners are effects too: they disappear when their plugin unloads.

      default handlersends the model requestlistener 2: policyif (blocked) return 'blocked' // vetoreturn next()listener 1: loggerlog(request); return next()requestresult
      every registration is an effect with an inverselisteners, tools, routes, services, child plugins1tool summarize registered2route GET /summary mounted3timer every 60 s startedapply(): 1, 2, 3unload: 3, 2, 1

      Effects: everything comes with its undo

      Every resource a plugin acquires lives inside an owned effect with a disposer. Unloading runs the disposers newest first, once.

      That is why a plugin can be removed, replaced or hot-reloaded while the session keeps running.

      Loader: rows of YAML become the live plugin tree

      cordis.patch.yml- id: brand name: acryl-brand config: { name: Music }- id: acryl-music name: acryl-music- id: workspace name: acryl-workspaceLoaderapp rootone ContextbrandFiber · ACTIVEacryl-musicFiber · ACTIVEworkspaceFiber · ACTIVEChange one row's config: only that Fiber reloads.Remove a row: its Fiber unloads and reverts its effects.

      All of it in one small plugin

      • Context: the scoped environment a plugin receives; services, events and effects live on it
      • Service: a named capability, ctx.tools, ctx.llm; replaceable by another provider
      • inject: a live dependency contract, not a load order
      • Effects: everything a plugin acquires is owned and released with it
      • Loader: rows in cordis.patch.yml become the live plugin tree; change a row, the tree updates
      // a Cordis plugin, simplified: needs the tools service, adds one tool
      export const name = 'word-count'
      export const inject = ['tools']
      
      export function apply(ctx) {
        ctx.tools.register(defineTool({
          name: 'word_count',
          description: 'Count words in a text',
          parameters: { text: { type: 'string' } },
          async execute({ text }) {
            return text.split(/\s+/).filter(Boolean).length
          },
        }))
        // unloading the plugin unregisters the tool: no cleanup code
      }

      It composes a running process. It does not describe, version or share an app.

      No app definition

      A profile is a local list of bundles on one machine. There is no file that says "this is my app" and travels.

      No reproducibility

      No lock of exact versions and checksums; two machines drift apart.

      No sharing

      No registry of whole apps, no verified pull, no way to start from someone else's setup and keep their updates.

      That gap is why the DeepSeek Harness community already has thousands of plugins that solve the same problems again and again.

      ACRYL Blends

      A protocol for composable software that people can share and reuse.

      Cordis composes; Blends describes, locks, shares and grows

      Cordiscontext · services · inject · revertible effects · fibers · LoaderDeepSeek Harnessthe agent loop, tools, models, sessions, as Cordis servicesACRYL Blendsmanifest · lock · registries · plugin hub · save to git · acryl new --from · acrylblends CLIyour appsACRYL IDE · GTD · accounting · music · anything, each with an agent inside

      An app in one file

      • kind: a Blueprint to start from, or a Blend grown from one
      • extends: inherit another app's rows; override only what differs
      • rows: Cordis plugins and their config, the same rows the Loader runs
      • Validated by @webboxes/blends-core; the lock pins every plugin by version and checksum
      # registry/blends/acryl.music/blend.yaml (real)
      apiVersion: blends.acryl.dev/v1alpha1
      kind: Blueprint
      metadata:
        id: acryl.music
        name: Music
        version: 0.1.0
        category: creative
        license: MIT
        visibility: public
      spec:
        runtime: cordis
        extends: acryl.blank
        rows:
          - id: brand
            name: acryl-brand
            config:
              name: Music
              tagline: Say the beat, hear the beat.
          - id: acryl-music
            name: acryl-music

      Write a piece once. Everyone can reuse it.

      Compose

      An app is rows of Cordis plugins. Add, override or remove one without forking anything.

      Lock

      blend.lock.json pins every plugin: a local folder by content hash, npm by integrity, a pulled plugin by source and sha512.

      Share

      Push a plugin or a whole app to git or a registry, private or public. Others pull it by name, verified.

      Reuse and grow

      acryl new --from starts from anyone's app; the agent inside adds plugins; a snapshot records it all again.

      The same packages run ACRYL and the open framework: @webboxes/blends-core, @webboxes/plugin-hub, @webboxes/app-persistence on npm, MIT.

      How it all fits together

      Cordisthe kernel: Context · services and inject · events · effects with undo · Fibers · LoaderDeepSeek Harnessthe agent as Cordis plugins: agent loop · tools · models · sessions · authorizationACRYL runtimeapp instances and homes · surfaces · agent control (Claude Code, Codex, ACP) · blends-core (manifest, lock, upgrade)core pluginsacryl-*uisystem-promptplugin-context (the builder)plugin-hubapp-savebrandBlendsblend.yaml + lockACRYL IDE+ IDE pluginsGTD+ acryl-gtdAccounting+ acryl-accountingMusic+ acryl-musicyours+ what you needsurfacesDesktopWebTerminalpull a plugin or a Blend by name: registries, npm, gitacrylblends.github.io · cordisplugins.github.ioEvery box above Cordis is plugins in rows. An app is which rows, with which config.

      ACRYL IDE is a Blend too

      acryl.blankthe same core every app starts fromacryl-uithe shell and its slotsacryl-system-promptwho the agent isacryl-plugin-contextthe builder insideacryl-app-savesave to gitacryl-brandname, colours, logo+ACRYL IDE pluginsrows in the same Loader, nothing specialacryl-app-shellprojects list, tabs, right panelacryl-workspaceprojects, worktrees, terminals, filesacryl-agent-controlClaude Code, Codex, ACP agentsacryl-plugin-hubpull, verify, pin pluginsacryl-plugin-adminturn plugins on and offacryl-settings · acryl-sign-inkeys, accounts+ the plugins you or the agent add<project>/.acryl-plugins/: the Pomodoro timer, the GitHub issues tool/blend snapshotblend.yaml + lock: share your IDE like any appThe IDE is not a special program: it is a Blend with more plugins.

      Three apps, one shape

      acryl.blankbrand · plugin-context (the builder inside) · system-prompt · ui · app-save + acryl-app-shell: the app frameextends:acryl.gtdbrand: GTD Planner, accent #4dabf7+ acryl-gtdindex.js13 tools: gtd_capture,gtd_triage, gtd_next, ...lib/domain.jsGTD ruleslib/store.js.acryl/gtd.jsonclient.jsthe board is the windowacryl.accountingbrand: Accounting, accent #51cf66+ acryl-accountingindex.js6 tools: invoice_create,expense_add, vat_summarylib/domain.jsVAT and totalslib/store.js.acryl/accounting.jsonclient.jsthe books are the windowacryl.musicbrand: Music, accent #b197fc+ acryl-musicindex.js12 tools: music_beats,music_tempo, music_savelib/domain.jspattern ruleslib/store.js.acryl/music.jsonclient.jsthe sequencer is the windowOne shape: tools the agent calls, rules, local data, and its own window with the agent beside it. The agent operates it and extends it.

      Your daily IDE

      Projects, worktrees, every coding agent side by side.

      One worktree per idea, any agent in it

      • Projects and git worktrees in one tree; each branch gets its own chat
      • Claude Code, Codex, Grok, Copilot, OpenCode, Pi and ACRYL's own agent as tabs
      • Terminal, browser, file editor, diff, board and doc tabs
      • Comment on a line, send it to the agent; review and commit in the right panel
      • A shared brief every agent in the workspace reads
      ClaudeCodexGrokGitHub CopilotOpenCodePiACRYL chat
      ACRYL with a project, a feature worktree and Claude Code running in it

      It builds itself

      Ask for a feature your workflow lacks. It becomes a plugin, live.

      The agent's steps writing and installing a Pomodoro plugin, the timer visible in the header
      Build me a plugin that adds a Pomodoro timer to the top bar: one click starts 25 minutes, another stops it. Install it so I can use it now.
      ~90 s button live4 files0 restarts

      It reads ACRYL's plugin docs, writes the plugin, verifies and installs it, then clicks its own button to test it. In rehearsal it found an accessibility flaw in its own code and fixed it while the timer kept running.

      Build a plugin that gives you a tool to list the open issues of any GitHub repository. Then show me the newest issues of deepseek-ai/deepseek-harness.
      2 min 47 s built and used3 files

      Not a button this time: a tool the agent itself can call from now on. Made for your workflow in minutes, then shared through one registry so the next person pulls it instead of rebuilding it.

      The agent listing open issues with the tool it just wrote

      How it builds a plugin, live

      you askone sentenceread docsACRYL plugin guidewrite4 small filesverifyacryl_verify_plugininstalllive, no restartself-testclicks its own UIfound a problem: fix and reinstall

      package.json

      Name, version, what it needs and provides.

      index.js

      Host side: services and tools for the agent.

      client.js

      UI side: fills a slot such as the header.

      cordis.patch.yml

      Where it sits in the app's composition.

      Agentic apps,
      any direction

      Same framework. The agent operates the app, not only its code.

      Getting Things Done

      acryl.gtd

      acryl new my-planner --from acryl.gtd
      Capture: call the dentist tomorrow, buy a birthday gift for Anna by Friday, and plan the Vienna talk as a project with three next actions. Ask Marco for the venue access, I'm waiting for him.
      45 ssix cards land on the board while you watch
      The GTD app: the board is the window, the agent beside it has filed six items into Next Actions and Waiting For
      The Accounting app: the books are the window, Q3 VAT payable 915 euro, and the agent beside them gives the same figure

      Invoices, expenses, VAT

      acryl.accounting

      Add an invoice for ACME, 1200 EUR net, due in 14 days.
      4 to 5 sthen "Which invoices are overdue?" and "Summarize Q3 VAT", about 5 s each

      Six agent tools over the app's own data. "Add a CSV export" makes it write a new plugin with its tests in about two minutes.

      The drum machine is the app

      acryl.music

      The Music app: the step sequencer fills the window, the agent beside it slowed the beat to 90 bpm, removed the clap and saved the pattern as Warehouse

      "Slow it down to 90, take the clap out, and save it as Warehouse." 5 s. No page to open: you start the app and it is a drum machine with an agent inside.

      A drum machine the agent plays

      acryl.music

      124 bpm
      Make a 128 bpm techno beat.
      Add a closed hi-hat track: on the page, synthesized, playable by the tools.
      12 s operate~2.5 min extend

      This grid is a small copy running in the slide. Sounds are synthesized; nothing is downloaded.

      Real ACRYL Blend apps, running

      Every shot: an app made with acryl new --from from the public registry, run isolated with the real model on 2026-10-19. The window is the app; the agent sits beside it. Click any shot to enlarge.

      Blends and plugins people can reuse

      · Blends reading

      · Cordis plugins reading

      The life of a Blend

      your appmade and pulled/blend snapshotrecords the appblend.yaml + lockversions, checksumsgit or registryprivate or publicacryl new --fromanyone startsnew apppulls pluginsit grows again: the agent adds plugins, you snapshot again

      Snapshot it, clone it, it restores itself

      /plugin pull github:inboxxobni/acryl-quick-notes@0.3.0
      /blend snapshot
      blend.yaml + blend.lock.json: every plugin, version and source
      acryl new planner-copy --from ./my-planner
      the copy pulls its plugins on first start
      {
        "formatVersion": 3,
        "origin": { "id": "app.my-planner", "kind": "Blend" },
        "lineage": { "blueprint": "acryl.gtd", "blueprintVersion": "0.1.0" },
        "parameters": {},
        "rows": [ ... ],
        "modules": [
          { "name": "acryl-quick-notes", "origin": "pulled",
            "version": "0.3.0",
            "spec": "github:inboxxobni/acryl-quick-notes@0.3.0",
            "digest": "sha512-m9bN..." }
        ]
      }

      A new agentic app in three seconds

      npx acrylblends@0.2.0 init my-agent --agent --yes
      cd my-agent && npm install && npm start
      my-agent listening on http://127.0.0.1:PORT
      curl -X POST $URL/ask -H 'content-type: application/json' -d '{"question":"create route hello /hello Hello"}'
      hello: installed, active.
      curl $URL/hello
      {"text":"Hello"}

      The app grows from inside: the agent adds a route as a plugin while the server runs. Node 22.19+, MIT, on npm and GitHub.

      95 features, all real

        macOS, Windows, Linux. Desktop, Web, terminal.

        Desktop

        Installers for macOS (Apple silicon, Intel), Windows 10 and 11, Ubuntu and Debian.

        Web

        The same app in your browser, from one command.

        Terminal

        A full terminal UI and CLI: npm install -g acryl

        curl -fsSL https://acryl.dev/install | bash

        Software that evolves, built from parts that last

        Self-evolving

        The agent inside writes, tests and repairs the app's plugins as your use of it changes.

        Composable

        An app is a list of plugins in blend.yaml. Add, override or remove one without forking.

        Stable

        Every plugin is verified before it installs, pinned by version and checksum, reverted cleanly on failure.

        Interoperable

        Cordis plugins run in ACRYL and in stock DeepSeek Harness; one registry lists both.

        Reusable

        Share a plugin or a whole app; others pull it by name instead of rebuilding it.

        Yours and open

        Your machine, your data, your git. MIT, on GitHub and npm.

        What we are building now

        • next The Blends page: save, share, pull another Blend with a diff of every plugin change
        • next Software factory: see every agent session on the machine, hand off in one click (moving work between Claude Code, Codex and Pi through the shared workspace brief works today)
        • next Workflows that travel with a Blend: one main agent, workers in isolated worktrees, spec-driven
        • next Settings and workspaces inside a Blend

        Own your AI.

        Alex Muzychenko

        Alex Muzychenko · let's connect

        LinkedIn

        Own Your AI #5 · Tuesday 20 October 2026 · IT-Services der Sozialversicherung, 1020 Wien · luma.com/2mxma8s0

        npm: acryl, acrylblends · the whole talk on one page: acryl.dev/demo/ownmyai/spe