evoke Get started

Run your first reflex.

Two routes, each ending in one real result. Your terminal on a Mac or Linux machine, or a Node application. About ten minutes either way.

Change the example →

  1. Choose the route

    The binary runs on macOS and Linux, and on Windows through WSL. The first-party collection, the thirteen reflexes this route installs, is for macOS. On Linux, write a reflex of your own first, or take the app route.

    The SDK needs Node 24.5 or newer and ES modules. It carries the core as WebAssembly, so it has no build step and no dependencies.

    The two buttons above switch every step below.

  2. Know what you need

    • The binaryThe install script fetches the release for your machine and checks its digest.
    • Node 24.5 or newerAnd "type": "module" in your package, or .mts files.
    • gitFor evoke add, which fetches reflexes from a repository. Your own git credentials apply.Only when you install reflexes from a repository beside your app.
    • Node 24 or newerFor reflexes written in JavaScript, which most of the collection is. A reflex that runs a program directly needs none.
    • A classifier keyFrom TypeSafe AI, in TYPESAFE_API_KEY. Or from OpenJEV, an independent service, in OPENJEV_API_KEY.

    The key's provider bills its use, under its own terms. evoke is free. A sentence you repeat is answered from a cache and costs nothing. Nothing else is billed and there is no account to make.

  3. Install and configure

    Two lines install software. The script puts evoke in ~/.local/bin. The add line fetches the collection from git and pins it.

    curl -fsSL https://evoke.build/install.sh | sh
    evoke add evoke-build/reflexes

    Two lines configure. The key is read from your shell, only at the moment of a decision, and never written to a file. The reflexes that open your folders wait for a word from you, and the second line gives them one.

    export TYPESAFE_API_KEY=<value>
    evoke vocab places add desktop "The desktop." --value ~/Desktop

    One line installs. The key is read from the environment at the moment of a decision.

    npm install @evoke-build/evoke
    export TYPESAFE_API_KEY=<value>

    One file holds the whole loop. A reflex handed as code, nothing on disk, and one call that decides, asks, confirms and runs.

    app.ts
     
    import { load, reflex } from "@evoke-build/evoke"
    import { jev } from "@evoke-build/evoke/jev"
    
    const timer = reflex({
      description: "Start a countdown timer.",
      effect: "write",
      confirm: "Start a {duration} timer?",
      args: { duration: { ask: "How long?", pick: "duration" } },
      examples: { "timer for 10 minutes": { duration: "10 minutes" } },
    }, async ({ duration }) => {                       // duration: number, in seconds
      setTimeout(() => console.log("ring"), duration * 1000)
      return `ringing in ${duration} s`
    })
    
    const project = await load({ reflexes: { timer }, adapter: jev() })
    const handled = await project.handle(process.argv[2] ?? "", {
      confirm: async d => { console.log(d.prompt.template); return true },
      ask: async d => ({ duration: "10 minutes" }),
    })
    console.log(handled.outcome === "ran" ? handled.result.text : handled.outcome)
  4. Inspect the request

    evoke try decides and runs nothing. It prints every answer: the ranking, each input, how well each reflex fits, and what would happen.

    evoke try "kill the wifi"
    evoke try
      wifi 0.90 · none 0.06 · power 0.02 · lock 0.02
      state  off 0.72 · on 0.20 · unstated 0.08
      fits   wifi 0.75 · lock 0.05 · power 0.05 · awake 0.02 · download 0.02 · mail 0.02 · note 0.02 · open 0.02 · screenshot 0.02 · timer 0.02 · trash 0.02 · volume 0.02
      confirm · wifi state="off" · write · weakest: state 0.72

    The weakest answer, 0.72, sits under the write bar of 0.8. So this sentence would ask before it runs.

    decide() makes a decision and runs nothing. It is a typed union: narrow it by outcome, then by reflex.

    decide only
     
    const d = await project.decide("timer for 10 minutes")
    if (d.outcome === "run") console.log(d.call, d.confidence)
    // timer duration="10 minutes" 0.9…
  5. Perform the action

    Type the sentence. The call and its confidence print, then the reflex's one line. A less certain decision asks first, with [y]es [n]o [t]each. Teach records your phrase and runs.

    evoke "set the volume to 40 percent"
    evoke
      volume level="40 percent"  0.93
    volume 40%

    Run the file with a sentence. handle() decides, asks for what is missing, confirms, and runs. Here it prints ringing in 600 s, and rings ten minutes later.

     
    node app.ts "timer for 10 minutes"

A successful install is preparation.

The first completed action is the outcome. When it works, the manual's first ten minutes take you the rest of the way, from your first lesson to looking inside a decision.