executable.md
Open source · v0.12.0 · Star on GitHub ↗

Minimize agentic work.

Turn what you've done before into a program. Use agents only for the judgment that remains.

Install xmd →Read the spec ↗
release.md
# Release

Run the tests.

```bash exec
npm test
```

Choose the next version.

<Prompt>
  Current version and release history:

  <File path="package.json" />
  <File path="CHANGELOG.md" />

  What should the next version be: patch, minor, or major?
</Prompt>

Make instructions executable.

README
$ xmd README.md#Test/Complete

Headings become entrypoints. Add frontmatter for typed arguments.

AGENTS
$ xmd AGENTS.md#Implement --props-issue=342

Load the issue, files, and other known context before the agent starts instead of asking it to rediscover them.

The instructions become part of the program instead of something humans, CI, or agents have to remember to follow.

When you know how, make it a program.

When you know what you want but don't know how to get there, use an agent. When you know how to get there, make it a program. Don't keep paying an agent to work out something you already know how to do.

The point

Use the least autonomy that gets the job done.

Don't know how

Use an agent to figure it out.

Know how

Make it a program.

Judgment remains

Keep only that part agentic.

One-off work can stay agentic. Repeated work that you know how to do can become an xmd workflow.

Designing workflows →

Plans are made to be followed.

CLI
$ xmd plan "1. Read package.json and
  CHANGELOG.md.
2. Ask an agent to recommend the
  next semantic version and
  explain why.
3. Validate the answer.
4. Ask me to approve it.
5. Write RELEASE.md." > release.md
XMD
<File path="release.md">
  <Plan>
  1. Read package.json and
    CHANGELOG.md.
  2. Ask an agent to recommend the
    next semantic version and
    explain why.
  3. Validate the answer.
  4. Ask me to approve it.
  5. Write RELEASE.md.
  </Plan>
</File>

xmd plan is command-line shorthand for <Plan>. It turns your instructions into an XMD program using the components available from xmd syntax.

Review it. Change it. Commit it. Then run the program instead of asking an agent to figure the workflow out again.

<Plan> is itself written in XMD. Read the planner source ↗

A Plan is text, so it composes. xmd plan writes the approved program to standard output and runs none of it. xmd run - takes a whole program from standard input — so the two are one command when you want no file in between.

Plan produces a program. Run executes a program from the host or CLI. Composition decides whether and when a planned program runs.

$ xmd plan "prepare the release" | xmd run -

The runtime composes intent.

Known control flow stays in the program.

Retries have a limit.

SafeParse decides whether the answer is valid, because that rule is already known. If branches on the result, Break ends the loop on success, and the retry prompt shows the same schema and asks only for a correction. max={2} is in the document, so the runtime knows when to stop trying.

<Loop max={2}>
  <SafeParse schema={proposalSchema}
             as="parsedProposal">
    {proposalCandidate}
  </SafeParse>

  <If condition={parsedProposal.ok}>
    <Break />
    <Else>
      <Prompt as="proposalCandidate"
              throwOnError>
        Correct your previous response
        without changing its meaning.

        Return only corrected JSON matching:

        <Json value={proposalSchema} />
      </Prompt>
    </Else>
  </If>
</Loop>
<Let value={{
  type: "object",
  required: ["bump"],
  properties: {
    bump: { enum: ["patch", "minor", "major"] }
  }
}} as="schema" />

<Parse schema={schema} as="release">
  <Prompt>
    Which version bump is required?
    Return JSON matching:

    <Json value={schema} />
  </Prompt>
</Parse>

<Elicit as="release" schema={{
  type: "object",
  required: ["confirmed"],
  properties: { confirmed: {
    type: "boolean" } }
}}>
  Publish this release?
</Elicit>

Schemas make judgment usable.

Whether the answer comes from an agent or a person, XMD validates it before the workflow continues.

Agents pass values.

Architect's result is captured as approvedPlan; Implementor receives it as plan. No hidden conversation and no file needed.

Memory lives only in this run and its nested scopes.

<Architect as="approvedPlan" />
<Implementor plan={approvedPlan} />

Build your own components.

Angle-bracket components resolve to Markdown files. <Implementor /> can be defined by Implementor.md, so your own components compose exactly like the ones shown here.

The runtime owns the workflow.

draft.md
<TempDir>
  <File path="notes/draft.md">
  Draft
  </File>

  ```sh exec
  cat notes/draft.md
  ```

  <Glob include={["**/*.md"]}
        as="drafts" />
</TempDir>

The nesting is the model. Components establish context for everything inside them, and the enclosing scope owns their lifetime.

Effects become execution history. Component expansions, evaluations, and exec operations are journaled automatically, without adding logging statements.

When the scope ends, XMD cleans up what it owns.

The run can outlive the process.

A retry must not repeat an external side effect, and a process can stop while work remains. So the run keeps a record of what already happened.

01

Keep a diagnostic trace.

$ xmd run review.md --journal journal.jsonl

--journal writes a JSONL trace of what ran and where it stopped. It is for this run, not retained workflow history.

02

Workflows keep their history.

Experimental
$ xmd workflow start review.md

Workflow mode is experimental. It keeps its own journal and effect records, separate from --journal.

03

Replay starts at the first gap.

Experimental
journaldurable effectreplayrecoverrepair
$ xmd workflow resume <run-id>

Resume reuses the effects the history records as completed and stops at the first unresolved boundary, instead of repeating an external effect.

04

Repair a failed run.

If CI fails after some effects finish, those completions stay recorded. Fix the cause and resume; only the unresolved part needs attention.

Install once. Run anywhere.

The standalone binary needs no runtime. The same CLI also runs under Deno, Node, and Bun.

$ curl -fsSL https://executable.md/install.sh | sh
$ xmd README.md --help

Deno

Run the CLI directly from JSR.

$ deno run -A \
  jsr:@executablemd/cli \
  run README.md

Node

Install the CLI from npm, then run the same command.

$ npm install -g \
    @executablemd/cli
$ xmd README.md --help

Bun

Install the same npm package with Bun.

$ bun add -g \
    @executablemd/cli
$ xmd README.md --help

Standalone binary · Deno · Node · Bun

Open source · v0.12.0

Star the repository to follow releases.

Star on GitHub ↗