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

Publishing

Publishing is a git tag. A reflex's identity is its location, owner/repo[/dir]. Its version is the tag it was fetched at. There is no account, no registry API, no build step, and no upload.

A repository of reflexes

radhi/home                        a repository is a collection
├── lights/{reflex.toml, lights.mts, reflex.d.ts}
└── blinds/{reflex.toml, blinds.mts, reflex.d.ts}
  • evoke add radhi/home installs every directory directly under it that holds a reflex.toml. evoke add radhi/home/lights installs one. Directories may nest: name a deeper directory, or the one above it.
  • A repository may also be a single reflex at its root. An author may keep a project inside that directory: evoke.toml, evoke.lock, overlays/, vocab/, evoke.d.ts. None of it ships. Those five names are skipped when a reflex is fetched and hashed.
  • Symlinks and submodules are refused at fetch. Everything a body needs is a committed file in its directory.
  • A LICENSE at the listed root is needed for a Hub listing. The collection uses MIT, since its scripts are meant to be copied into reflexes of your own.

Design a collection before you word its reflexes: rules 37 to 42.

Tags and versions

$ git tag v1.2.0 && git push --tags
  • Tags are X.Y.Z or vX.Y.Z. The newest is the highest. A repository without a version tag cannot be installed.
  • Published tags never change. The lock records the tag, the commit and the content hash. sync refuses a tag that moved. Publish a fix as a new tag.
  • One tag covers the whole repository. Every reflex in a collection moves together, and evoke check reads the contract diff for each from the same series.

What the next version must be

Run evoke check in a reflex directory inside a git repository. It diffs the manifest's contract against the repository's newest version tag, and says what the next tag must carry:

$ evoke check
  lights  write  runs lights.mts
  lint  lights: args.power has no record that leaves it out; assert power = false once
  lint  lights: args.brightness has no record that leaves it out; assert brightness = false once
  lint  lights: examples holds 2 requests; write three at least
+ reflex.d.ts
  1.2.0 → 2.0.0  major
    args.state  renamed power

Each lint line reports a rule the manifest breaks. Lint never refuses: What evoke checks for you.

LevelWhen
sameWording only: description, not_for, tags, confirm, any ask, option meanings, records. Also a declaration narrowed
minorAdditions, like an argument, an option, a config key, a field under [yields], a returns name or a platform. Also a config key removed, an argument made optional, a secret made plain, or a declaration widened
majorSomething a user's files or calls may not survive: an argument or option removed or renamed, a source, a range or recent changed, run or steps changed, an argument made required, a config key made secret, a yield or a returns name removed or changed, a taken argument added, removed or changed, a platform dropped

A was violation is refused outright. That means a retired name returning, or a name dropped from the list. With no repository, no tag, or no reflex at this directory in the tag, no diff prints.

Read this diff before every tag: rule 46. The checklists list what else to check before a tag.

Renaming safely

was lists an argument's former names, which stay listed forever:

[args.power]
was = ["state"]

Every user's overlay and call follows at merge time, and update tells them so. Rename an argument with was: rule 46. An option key has no was, and removing one is major.

What users see at update

evoke update never prompts, never blocks and never rewrites a user's files. It reports your rewritten description as taken, unless they overrode it. It reports each contract change, and what they override that you changed. It reports a loosened effect, which they keep until they accept it. A tightened effect applies at once.

What add checks

Each install lints the manifest, as evoke check does. It also routes every installed example over the new set. A steals line names an example your reflex would take from the reflex that owns it. An also fits line names an example your reflex also fits: two reflexes claim the sentence, and one worded like it may reach either. For a playbook, add names each step whose reflex lacks the playbook's tag. None of these lines stops the install.

Before a tag, install your reflexes beside the ones they will live with, and read every such line: rules 40 and 41.

The Hub

The Hub is where reflexes are found. Until about twenty third-party reflexes exist, it is the first-party collection, evoke-build/reflexes, reviewed and published as one repository. After that, it becomes one index repository. A listing is a one-line pull request. Static pages at evoke.build show a preview, a diff, and a search over examples. No install ever depends on it. add and sync reach git directly.

The Hub publishes no per-engine pass rates. An engine's terms may forbid them.

Next: The collection, or the SDK.

FAQPrivacyGitHub