Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Your first reflex

A reflex is a directory: a manifest and the file it runs. evoke new writes a working one. evoke check keeps it honest. A project next to it lets you try it before anyone installs it.

1. Make it

$ evoke new hello
+ hello/reflex.toml
+ hello/hello.mts
+ hello/reflex.d.ts

Three files, from a template that already works:

# hello/reflex.toml
reflex = 1

description = """
Say hello to someone.
The name is the text in quotes, "like this"; the greeting is printed and nothing changes."""
not_for = ["saying goodbye"]
effect = "read"
confirm = "Say hello to {who}?"
run = "hello.mts"

[args.who]
ask  = "Who should be greeted?"
pick = "quoted"

[examples]
'say hello to "Ada"'   = { who = "Ada" }
'greet "Grace"'        = { who = "Grace" }
'a hello for "Edsger"' = { who = "Edsger" }

[tests]
'wave at "Linus"'      = { who = "Linus" }
"say hello"            = { who = false }
"bid everyone goodbye" = false
// hello/hello.mts
import type { Reflex } from "./reflex.d.ts"

export default (async ({ who }) => `Hello, ${who}!`) satisfies Reflex

reflex.d.ts is generated from the manifest. It holds Args, with who: string, and the Reflex type that checks the body's arguments and its return. The body imports that one file and nothing else.

For a playbook, a reflex whose body is a plan of steps, evoke new --playbook <name> writes reflex.toml alone:

$ evoke new --playbook drill
+ drill/reflex.toml

2. Check it

$ cd hello && evoke check
  hello  read  runs hello.mts

evoke check reads the manifest and names every line to fix. It confirms that the file run names exists, loads, and exports a function by default. It reports lint. When the arguments changed, it rewrites reflex.d.ts and prints + reflex.d.ts. Inside a git repository with a version tag, it also diffs the contract against that tag: Publishing.

$ evoke check
  broken: run: "nothing.ts" must end in .mts or .mjs  →  ~/broken/reflex.toml:4:1
[3]

3. Try it

A reflex is decided on inside a project. Keep one next to your reflexes while you work: a file naming the adapter, and evoke add ./hello writes the rest.

~/dev/
├── evoke.toml
└── hello/
# ~/dev/evoke.toml
adapter = "jev"

A project outside home must be trusted once. Edits to the reflex itself never need it again. Trust binds to the project's own files, not to the reflexes.

$ cd ~/dev && evoke trust
+ trusted ~/dev
$ cd ~/dev && evoke add ./hello
+ hello  ./hello  read  runs hello.mts
$ cd ~/dev && evoke try 'say hi to "Ada"'
  "say hi to \"Ada\""

  which reflex            hello 0.97   (none of them 0.03)
                          Say hello to someone.
  who                     "Ada" 0.98   (not said 0.02)
  holds all you said      0.90
  → runs: hello who="Ada"  0.97
    a read runs at 0.80 or more, and its least sure judgment is which reflex, 0.97; it holds all you said at 0.90, and a call runs at 0.30 or more

  replay answered 5 questions in 2 rounds
$ cd ~/dev && evoke 'wave at "Grace"'
  hello who="Grace"  0.96
Hello, Grace!

evoke test hello runs the manifest's own examples and tests against the classifier, and reports every miss. evoke run hello who=Ada calls the body without the classifier at all.

4. Make it yours

From here, three pages carry the rest: the manifest key by key, the four kinds of argument, and what a body receives and returns. Then the rules, which say how to write a manifest so that what people type reaches your reflex. And publishing, which is a git tag.

This page took you through the first steps of working on a reflex. Rule 45 lists every step, in the order that finds each fault first. Read your reflex against the checklist before its first tag.

Next: The manifest.

FAQPrivacyGitHub