# Installing Jason This page takes a machine with nothing on it to an installation that can start work, and then takes it off again. It is written to be followed by a person or by an agent, in order, without reading anything else first. Everything here is per-user. Nothing needs administrator rights, and nothing is installed for other people on the machine. --- ## 1. What you need Jason is used from a release: nothing in its repository is built, cloned or tested to use it, which is for changing Jason (§3). **From a release (§2):** a shell to install it with, and nothing else — the archive carries its own runtime, and the script ends by teaching it its role skills (§4). Teaching it is a fetch of its own: a release takes its skills from the package of them it published, `jason-skills.zip`, over the network, at the tag it was published as. A machine without the network teaches it from a checkout instead, with `--source`, which also takes a git repository at a ref; only that needs `git`. You also need a directory you can write to, and — if you want an agent harness taught — that harness installed, so §4 has somewhere to deploy. To have a host other than Claude Code run the background roles, install it from its own documentation and sign in as yourself; Jason holds no key. For Cursor CLI, install it from [its installation page](https://cursor.com/docs/cli/installation.md), run `agent login` and `jason profile create --host cursor_cli --program agent`. On Windows, where `agent` is not found by the runtime's search path, name the launcher by its full path: `--program `. For Codex CLI, install it from [its own page](https://github.com/openai/codex), run `codex login` and `jason profile create --host codex --program codex`. On Windows, Codex needs a one-time setup by an administrator first, which [the Codex section](execution-profiles.md#codex-cli) describes. For GitHub Copilot CLI, install it from [GitHub's installation page](https://docs.github.com/copilot/how-tos/copilot-cli/set-up-copilot-cli/install-copilot-cli), run `copilot login` and `jason profile create --host copilot_cli --program copilot`. For Gemini CLI, install it from [its own page](https://github.com/google-gemini/gemini-cli), sign in as yourself and run `jason profile create --host gemini_cli --program gemini`. For Antigravity CLI, install `agy` from the CLI tab of [Google's quickstart](https://antigravity.google/docs/getting-started?tab=cli), run `agy` once to sign in as yourself ([how Google describes signing in](https://antigravity.google/docs/install/)), and `jason profile create --host antigravity_cli --program agy`. Each run is given its permissions by a workspace hook the launch writes (built from the host's hooks page, not yet run on an account). If a role is refused on `antigravity_cli`, add two rules to your own `~/.gemini/antigravity-cli/settings.json`, in its `permissions.allow` array: `command(jason)` (on Windows shells, `command(regex:jason .*)`) and `read_file()`; the [host matrix](execution-profiles.md#12-the-hosts) has the two lines of JSON and the details. ### If an agent installs it An act this page marks **Ask first.** needs the word of the person you install for: ask, and do it only on their yes. With nobody to ask, leave it undone and say so. A question tool that comes back with no answer is nobody to ask. This page is served as plain text at `https://get.jasonharness.ai/install`, the address the README's prompt names. - Start your session without external connectors — on Claude Code, `--strict-mcp-config`. The install needs none. - Do §2, then §4 to §6, in order, and stop there. §3 is for a build from the runtime's repository, and §7 takes the installation off again. - Install by the first route that fits. Where §2 names a package for this platform and its package manager is already on this machine, use it (*With a package manager*). Where it is not, where it fails, or where it or your harness refuses it, say so once and take §2 *By hand*: download the archive and `checksums.txt` from the release, check the digest and stop on a mismatch, unpack, keep the two notice files beside the executable, and run `jason --version` by its full path. That is the next route, not a way around the refusal. Never pipe a download into a shell. The install scripts are the person's: where your harness refuses even the route by hand, say so and give the person the one-liner to type themselves. - Write only what those steps write: the executable and its install directory; this account's PATH entry for it; Jason's data directory, which is where the role skills go; the system's temporary directory, which the download goes into; and the directory the executable unpacks its native libraries into when it first runs — under the temporary directory on Windows, under `~/.net` in this home directory on macOS and Linux. Nothing in your own agent's configuration unless the person says so (§4). A package manager's own PATH change is part of the install you were asked for, and so is the one-liner's when the person types it; a PATH edit of your own, by hand (§2) or by the repair (§5), is marked **Ask first.** - With a no to the PATH entry, it is the person's own step: finish everything else, then hand them the exact line `jason status` prints for `path`, and say that `jason status` again proves it. Never end on "not ready" alone: name the step that remains. - Install nothing else and build nothing (§3). A 404 from a download is §2's: stop and report exactly that. Leave no long-running process behind except the runtime that `jason runtime start` starts. - A refusal — by your harness, or by a package manager — is reported once, as it stands, and never worked around. Working around it is a retry, the same command rewrapped, or the refused code run by another means, such as a downloaded script run another way. Taking the next route in the order above is not working around it. - After `jason status` (§5), branch on `ready` in its JSON body, never on the exit code. For each required check that is not ok, run the repair it prints. Optional checks are reported, not repaired: their repairs write into your agent's configuration or into what starts at logon, which is the person's to allow. - A profile you append to is read by a login shell, not by your next non-interactive command (§2): carry the `export` half yourself, or call `jason` by its full path. - Stop when `ready` is true, or when a required check still fails after its repair. Report which checks failed, exactly what you ran, and what it changed. - **The hand-over.** When `ready` is true, tell the person Jason is installed and can work and where it will keep their files — the two lines §2 shows, with the folder the `harness_root` check of `jason status` names, which is the one in force — and ask them once what comes next: [the wiring check](golden-path.md) first, in this session, or their real work at once. Name the wiring check for what it is: a synthetic walk to meet the system, which connects their provider and proves it with their own address, and is not the real work. A skip is honoured: do not offer the walk again. The real work, at once or after the walk, begins with an invitation to tell you about their first campaign in their own words — typed, a link, a file or a voice note, or one of a few examples you offer to start from — and goes on as a campaign planned with the `campaign-planning` skill and worked by Jason's roles. --- ## 2. Install from a release ```sh curl -fsSL https://get.jasonharness.ai/releases/latest/download/install.sh | sh ``` ```powershell irm https://get.jasonharness.ai/releases/latest/download/install.ps1 | iex ``` Jason is released under the MIT licence: [LICENSE](../LICENSE). What it sends off your machine, and what stays your responsibility when it reaches people, is in [responsible-use.md](responsible-use.md). Both lines install the **latest release**. If either answers 404, the release could not be reached — through the address or on GitHub — and that is not a failure of your machine: report it as it stands rather than run the line again, and build nothing instead. Each script works out your platform, downloads the archive for it, **verifies its SHA-256 before unpacking**, installs the executable under your own account — with its licence and the third-party notices beside it, as `jason-LICENSE` and `jason-THIRD-PARTY-NOTICES` — and puts that directory on your PATH. Run again over the version already installed, it downloads nothing and says so, unless a licence file is missing beside the executable: then it downloads the archive, checks it the same way, and writes the file, leaving the executable as it is. Then it teaches the executable it installed its role skills: it runs that executable's `jason skills install --roles-only` (§4), which takes the skills from the release's `jason-skills.zip` and writes them into Jason's data directory and nowhere else, and what it prints is shown. Where that fails — no network, say — Jason is still installed and the run still succeeds: one line says the role skills were not deployed and what to run, and `jason status` names the same line. A script pointed at a feed in a directory, with `--feed` or `-Feed`, leaves this step out and says what to run instead, because the skills verb reads no directory. On macOS and Linux the PATH line goes into the profile a login shell of yours reads, and for `bash` and `zsh` into `~/.bashrc` or `~/.zshrc` as well: the terminal a desktop opens — GNOME's, for one — is not a login shell, reads that file and not the login profile, and so finds `jason` without your signing out. For any other shell the script says to sign out and back in, because only a new sign-in reads the login profile again. Every run ends with the licence it installed under, where the release has one, and then the one command to run next, `jason status` (§5), which says what this installation still needs and the command for each. Then, before the PATH step, each script says where Jason will keep what it learns about your business, and where a campaign goes that names no project. On Windows, for an account whose home directory is `C:\Users\Marta`: ```text Jason keeps what it learns about your business in plain files you can read and edit, one folder per project and campaign, in `C:\Users\Marta\Jason` by default; to keep them somewhere else, set `Harness:Root` in the settings before your first campaign. Campaigns you create without naming a project go to the project `Default`; rename it, or make one project per product. ``` That folder, the harness root, is `Jason` in your home directory — `/home/marta/Jason` on Linux, `/Users/marta/Jason` on macOS — unless `Harness:Root` in `~/.jason/config/settings.json` names another; a script cannot know what the runtime makes of its settings, so it says "by default", and `jason status` names the root in force. The install makes no folder there. The runtime makes the root the first time a project or a campaign is created, and each project and campaign a folder of its own below it, each with the marker that makes it Jason's, `.jason/marker.json`, an empty `AGENTS.md` for your own words, and one line, `@AGENTS.md`, in each file a host reads in its place (`~/Jason/CLAUDE.md` at the root for Claude Code; the [host matrix](execution-profiles.md#12-the-hosts) lists them), so that it reads them too; a `Jason` folder already there is taken as the root then, its marker written and nothing it holds changed, unless it is marked as something else, which `jason status` reports. `Harness:Root` set before that first create is all it takes. A folder you move later is recorded again with `jason project link`, the root's once `Harness:Root` names where it is now. Jason never writes a word of those memory files, never runs `git` there and never writes a `.gitignore`. `git init` in the root is yours to run: it gives the folder a history, and lets Codex — which reads the `AGENTS.md` files from the top of a repository down to the folder it starts in — read the root's and the project's with a campaign's. On Windows, `install.ps1` waits up to 10 seconds for a file another program holds open — a virus scanner reading the executable it has just unpacked or run — before it gives up and names the file, or the directory it was unpacking into. And if the new `jason.exe` cannot move in, it puts the one you had back — or, when it cannot, says where it is — so an install that fails never leaves you without the version you started with. | Default install directory | Platform | |---|---| | `~/.local/bin/jason` | macOS, Linux | | `%LOCALAPPDATA%\Programs\jason\jason.exe` | Windows | Three flags matter — spelled `--version`, `--install-dir` and `--no-modify-path` for `install.sh`, and `-Version`, `-InstallDir` and `-NoModifyPath` for `install.ps1`: - `--version X.Y.Z` installs a particular release instead of the latest. The script checks that the manifest it gets back is the release you asked for, rather than trusting the feed to have answered the question you put to it. - `--install-dir ` installs somewhere else — into a directory of its own, for the reason below. - `--no-modify-path` leaves your PATH alone. Then `jason` is only typeable by its full path until you put it on the PATH yourself, as below. A one-liner takes them like this: ```sh curl -fsSL https://get.jasonharness.ai/releases/download/v0.37.0/install.sh | sh -s -- --version 0.37.0 ``` ```powershell & ([scriptblock]::Create((irm https://get.jasonharness.ai/releases/download/v0.37.0/install.ps1))) -Version 0.37.0 ``` These install 0.37.0 with 0.37.0's own script: a pinned install fetches the script from the release it installs. **A directory of its own.** `jason uninstall` takes a directory's PATH entry off only where the directory holds nothing but Jason. Installed into a directory other programs share — on Windows, the `WindowsApps` folder every account's Path already names — the entry stays, and so does everything else it puts on the PATH. **Putting it on the PATH yourself.** With `--no-modify-path` nothing did this for you. **Ask first.** On Windows, add its directory to your account's `Path`; on macOS and Linux, append an `export` line to the one profile a login shell of yours reads — `~/.zprofile` for `zsh`; for `bash` the first of `~/.bash_profile`, `~/.bash_login` and `~/.profile` that exists, because bash never reads `~/.profile` once one of the others does; `~/.profile` for every other shell — and, for `bash` and `zsh`, to `~/.bashrc` or `~/.zshrc` as well, which a terminal opened without a login reads. `jason status` prints the exact line for your platform — a PowerShell line on Windows, an `sh` line elsewhere — when it finds that `jason` does not resolve (§5), so the simplest path is to run it and type what it says. One thing that line cannot do for you: a profile is read by a shell that starts after it is written. A person opening a new terminal gets it — where the shell has no file of its own for that, as `bash` and `zsh` do, only after signing out and back in; an agent running one command at a time in a non-interactive child shell (`bash -c …`) has written the profile but will not see it in its own next command. If you are an agent, carry the `export` half of that line yourself, or call the executable by its full path until a new login shell exists. Confirm what landed: ```sh jason --version ``` On Windows the PowerShell you installed from is told about the new PATH entry. On macOS and Linux the script ran in a shell of its own, so the one you typed it into has not heard: open a new terminal — or sign out and back in, where the script said so — or type it by its full path — `~/.local/bin/jason --version`. A started runtime asks the release feed whether a newer version exists five minutes after it starts, and once a day after that, at the default settings: one `GET`, carrying nothing about you or your work — it identifies only the runtime's version, including its build. `Update:CheckEnabled` set to `false` in `~/.jason/config/settings.json` turns that off. That request, and the downloads the install scripts, `jason update apply` and `jason ui install` make, go to `get.jasonharness.ai`, an address Reply.io operates, which redirects them to this repository's releases on GitHub. What that address keeps, and for how long, is in [responsible-use.md](responsible-use.md#update-check-and-downloads). The skills are the exception: their package is read from this repository's releases on GitHub directly, by the install scripts' last step, by `jason update apply`'s skills step and by `jason skills`. ### With a package manager On macOS, with Homebrew: `brew install reply-team/tap/jason`. Every macOS route on this page — the one-liner, Homebrew and the archive by hand — is for Apple silicon only: no build for an Intel Mac is published, so on an Intel Mac Homebrew answers "formula requires at least a URL", `install.sh` names the platforms it has, and the way to Jason today is another machine: Linux x64, Windows x64 or an Apple silicon Mac. Installed this way, Jason is under the same MIT licence. The package manager owns that installation: it updates it and takes it off, and `jason update apply` refuses it — it "would replace a file the package manager owns" — and names the manager's command. That command is typed between `jason runtime stop` and `jason runtime start`, because Homebrew's upgrade removes the previous version's keg by default, the path a running runtime starts its plugin hosts from. ### By hand To install without running a downloaded script, take the steps the script takes, yourself: 1. Download the archive for this machine and `checksums.txt` beside it: for the latest release, `https://get.jasonharness.ai/releases/latest/download/jason-win-x64.zip`, `…/jason-linux-x64.tar.gz` or `…/jason-osx-arm64.tar.gz`, and `https://get.jasonharness.ai/releases/latest/download/checksums.txt`. For a particular release, use the address the pinned lines above use, with the file's name in place of the script's. 2. Check the archive's SHA-256 against its line in `checksums.txt` (`Get-FileHash -Algorithm SHA256` on Windows, `sha256sum` or `shasum -a 256` elsewhere), and stop if they differ. 3. Unpack it into a new temporary directory, and move the executable into the install directory — `%LOCALAPPDATA%\Programs\jason` on Windows, `~/.local/bin` elsewhere — with `LICENSE` and `THIRD-PARTY-NOTICES` beside it, named `jason-LICENSE` and `jason-THIRD-PARTY-NOTICES`. On Windows a downloaded archive may carry the mark of the web, and hands it to what it unpacks: `Unblock-File` the executable, as `install.ps1` does. 4. Run `jason --version` there, by its full path. It prints the version you downloaded. 5. Put that directory on the PATH, as *Putting it on the PATH yourself* above says: that is the act it marks. Once `jason --version` answers there, the archive, `checksums.txt` and the temporary directory you unpacked into have done their work: you may delete those three — only those — with `Remove-Item -Recurse ` on Windows and `rm -r ` elsewhere. ### Jason Desktop A person who would rather have a window than a terminal can install [Jason Desktop](desktop.md) instead of, or beside, the executable above, from the latest release's downloads: `jason-desktop-windows-x64-setup.exe` for Windows on x64, `jason-desktop-macos-arm64.dmg` or `jason-desktop-macos-x64.dmg` for macOS, and for Linux on x64 `jason-desktop-linux-x64.deb` (`sudo apt install ./jason-desktop-linux-x64.deb`, the one to take on Ubuntu 24.04 and later) or `jason-desktop-linux-x64.AppImage`; `https://get.jasonharness.ai/desktop/windows`, `/desktop/mac`, `/desktop/mac-intel`, `/desktop/linux-deb` and `/desktop/linux-appimage` send you to the latest release's file. Each carries the release's own `jason` and works on this same installation. The Linux packages are not signed, and are built so, not yet seen on a real machine. Install it only when the person asks for it: the line in this section is the agent's way, and it never needs the desktop. --- ## 3. Build from source This section is for people changing Jason; to use Jason, skip it: section 2 installs a release. A build of the executable from the runtime's repository, rather than a release (§2), needs two things from this page: - **The executable alone, in a directory of its own, on the PATH by hand** — as §2 says for `--install-dir` and `--no-modify-path`. Copy that file alone: the `.pdb` files beside it are debugging symbols, and a directory that holds them as well is not one of its own. - **`--source` when you teach it** (§4). The skill packs are pinned to a tag derived from the build's own version, and a build from a working tree is a development version whose tag has not been published. `--source ` says "take the packs out of this checkout of this repository", which is what you want when you are standing in it. --- ## 4. Teach it Jason's skills are what teach an agent the job — one directory per launched role, which the runtime reads at every launch, and two packs for your own agent: one for operating the installation, one for the SDR profession. **A runtime with no role skills launches every role untaught**, so the first half is not optional. The install script did the first half as its last step (§2), and what it printed says where the role skills went. Installed with a package manager or by hand, or where that step said it could not, do it now with the lines below; they are also how it is done again. Look first. Nothing is deployed, and the one target root is printed — the runtime's own, inside its data directory: ```sh jason skills install --roles-only --dry-run ``` On a first install the dry run fetches the skills first, from the release's package of them, into Jason's staging directory inside the data directory, so that there is something to show; it deploys nothing. The line below deploys them: it prints its one root before it writes a skill there, and writes nowhere else. Then do it: ```sh jason skills install --roles-only ``` Both take the skills from `jason-skills.zip`, the package of them the release this build was published as holds, checked against that release's `checksums.txt` (§1). `--source` takes them from somewhere else instead: a checkout, or a git repository at a ref, which needs `git`. Then place the browser UI, the page `jason ui open` opens: ```sh jason ui install ``` It downloads `jason-ui.zip` from the release this build was published as, checks it against that release's `checksums.txt`, and places it in the data directory as the default UI. A runtime works without it. A build from source has no published UI, so it refuses and says where a build of `ui/` goes instead: `ui/custom/` in the data directory, which is served first whenever it holds one. The role skills are everything a runtime needs, and none of these lines writes outside its data directory. The other two packs go into the skills root of each agent host found on this machine (the [host matrix](execution-profiles.md#12-the-hosts) names them) — which is yours to allow rather than Jason's to assume. **Ask first.** Without `--roles-only` the same verb deploys all three, again printing every root before it writes any: ```sh jason skills install --dry-run jason skills install ``` **From a working tree.** A build from source knows no published tag. Its version names the release it is on its way to, so the repair `jason status` prints for `role_skills` — `jason skills install --roles-only`, with no `--source` — asks for a tag that has not been published yet, and refuses, saying so. Add `--source `, the path of your checkout of this repository, to each of the lines above. It refuses a deployment the runtime would later refuse to launch, rather than writing one — a role whose directory and skill name disagree, or a tree over the runtime's live size cap, stops the whole deployment before a byte is written. A file you have since edited is reported and kept, not overwritten, and everything else is written around it: the run names each file it kept and succeeds. The skill holding it is written file by file where it stands, and is a blend of two hands, yours and the release's, which is yours to reconcile. `--force` overwrites it, and overwrites every edited file in every root of the plan, so read what it says first. Later, to move an existing deployment to a newer set: ```sh jason skills update ``` It updates only where a deployment was made, and each root from the source its own record names: an installation taught with `--roles-only` stays that way, and a harness installed from one source is not updated from another. A deployment made at the tag of the build that installed it moves to the tag this build carries. One made with `--ref` stays at its ref, a directory is read where it stands, and a development build keeps the ref the record names, because the tag its own version names is not published yet. From 0.20.0, Jason's own installation on 0.18.x or earlier updates through 0.19.0: `jason update apply --version 0.19.0`, then `jason update apply`. Its own `jason update check` names 0.19.0 as `install_first` and its apply as `upgrade_command`, and a plain `jason update apply` refuses with `update_not_directly_applicable`, naming 0.19.0. A package manager's upgrade goes straight to the newest release. `jason update apply` ends by running `jason skills update` at the new release's tag, and then places the release's UI as `jason ui install` does; an update applied by a build before 0.12.0 needs one `jason skills update` after it, and one applied by a build older than the UI step places no UI, so `jason ui install` follows it. A package manager's upgrade does not run `jason update apply`, so `jason skills update` and `jason ui install` follow it. Either way, `jason status` is the check: role skills a default install took at another release's tag fail `role_skills`, and the repair it prints moves them to the runtime's own tag. That repair is `jason skills install --roles-only`, with the `--source` they came from when it was not this repository. A deployment made with `--ref` stays where it is and passes, in the runtime's own root and in an agent's, and so does one an older Jason's `jason skills update` touched, which recorded it as though it had been made with `--ref`. The check's fact names both tags and the line that moves it: `jason skills install --roles-only` for the role skills, and `jason skills install --pack ` for a pack in an agent's root, each with the `--source` it came from when that was not this repository. The line for `jason-runtime-skills` moves its role half as well. [`skills/README.md`](../skills/README.md) is the contract both verbs keep, including the record each root carries — which is what §7 removes by. --- ## 5. Ask whether it can work ```sh jason status jason status --human ``` One question — "can this installation start work?" — answered check by check. It is one of eleven names in this CLI with no API operation behind it — `status`, `uninstall`, `logs`, `doctor`, `export` and `import`, the `skills` and `update` nouns, `ui install` and `plugin install`, which change this installation's files as those two do, and `session open`, which starts your own agent host in a terminal — and it cannot be otherwise: half of what it reports is not the runtime's to know. | Required — a failure exits 1 | Optional — absent never fails | |---|---| | the runtime answers, and no update stopped part-way from its swap on — its repair then is `jason update apply`, never `jason runtime start` | no update is waiting to be resumed | | the running runtime is the build this CLI is | a provider plugin is installed | | migrations are applied | each plugin package this release publishes is the one installed | | the plugin registry is alive (zero plugins is alive) | every plugin installed is available | | role skills are present for every role Jason ships — a role of your own is reported, never failed — named after their directories and within the runtime's live cap | a plugin is granted a journal kind | | `jason` resolves on PATH — in this shell, or in every shell started from now on — and which file answers | every plugin is granted something of each capability it asks for | | | a route is configured | | | a binding names an account | | | a provider CLI **you name** answers | | | the skill packs are deployed to an agent harness, and the files their record names are there | | | every enabled profile names an agent host detected on this machine | | | autostart is registered | | | notifications reach you | | | a UI is installed, and the default one is this release's | | | the harness root can take the first project or campaign | **It exits 0 or 1 and never 3.** Exit 3 means "I could not ask the runtime", and this is the verb whose whole job is to answer when the runtime cannot be asked. The JSON body carries `ready` and a state per check, so **an agent branches on the body, never on the exit code**. A check reports a fact and, where there is one, the command that repairs it. Most repairs are `jason` commands. One is not: putting an executable on a PATH is the shell's own act, so the `path` check prints the line your platform needs — a PowerShell line on Windows, an `sh` line elsewhere, the same line this product's own installer writes — which you type rather than hand back to `jason`. **Ask first.** That line writes a login profile — for `bash` and `zsh`, `~/.bashrc` or `~/.zshrc` beside it — or this account's `Path` on Windows. Typed twice, it changes nothing the second time. Read §2's note about login shells before you type it. A shell that started before the installer put Jason on this account's PATH does not see it — and an agent's commands usually run in exactly such a shell, because each one inherits the environment the agent itself started with. That is an old shell, not a broken installation: when this account's PATH carries the directory — its Path value on Windows, the one profile a login shell reads elsewhere — `path` is `ok`, says that this shell predates it, and names the full path to type in the meantime. A shell started from now on finds `jason` by name. **But everything the old shell started is as old as it is**: an agent host started before the install, and every command it runs, keeps failing a bare `jason` while `ready` is true — type the full path the check names, or restart the host. A fresh installation that has done §2 through §4 but has not yet started the runtime is expected to report `runtime`, `runtime_version`, `migrations`, `plugin_registry` and `role_skills` as failed-or-unknown with `jason runtime start` as the repair. That is §6. `runtime_version` compares the version the running runtime reports with this CLI's own. It fails when a runtime was left running across an upgrade that replaced the executable — a package manager's, or a file copied over by hand — because that runtime is still the old build and starts its plugin hosts from the old image. Its repair is `jason runtime restart`. `plugin_package` compares each plugin package the release you run publishes — today the Reply plugin's, the journal forwarder's, ntfy's, Slack's and Telegram's — with the package of that id installed, by content digest, offline: the runtime carries its release's package and asks no network. An earlier release's package fails it: a package manager's upgrade replaces the executable and leaves `~/.jason/plugins/reply` as it was, and so does an update whose `plugins:` line says the package was not replaced. Its fact names the installed version, the version this release published, and the command that places it, `jason plugin install reply --replace`, which swaps the old package for the release's and asks the runtime to load it. A package with the same version or a later one passes, and the fact says it is a later release's package or one built or edited on this machine; no package of that id is absent. A development build compares with its own tree, and the fact names the build it compared with. `plugin_availability` names each plugin `jason plugin list` reports `unavailable`, with its problem codes and never their text — `reply is unavailable; its problems: executable_missing.` Such a problem is about this machine rather than the package, most often a program the plugin runs that is not on the PATH the runtime started with. Work routed to such a plugin fails at the claim, and a notification plugin delivers nothing; nothing else stops, so the check never decides `ready`. `jason plugin list` says what each problem is, and once it is repaired `jason plugin reload` reads the plugins again. `plugin_subscriptions` names each plugin the settings grant journal kinds to, with those kinds — `forwarder handles workitem_failed, campaign_created.` — and is absent when no plugin is granted one. It quotes a plugin's id and its kinds and nothing else, and it never decides `ready`: a kind no plugin handles is an ordinary installation. `jason plugin list` says which kinds each plugin declares and which it is granted. `plugin_grants` names each plugin, an unavailable one included, that asks for a capability and is granted nothing of it, with the keys under `Plugins:Grants:` that would grant it — `reply is granted nothing it asks for under Exec.` It quotes a plugin's id and those keys and never what the manifest asks for, and it never decides `ready`: such a plugin runs without what it is not granted, and nothing else stops. `jason plugin list --human` says what each asks for, the key that grants it and the settings file, and `jason plugin reload` reads the grant. To check a provider's own CLI as well, name it — this build knows no vendor's command by heart: ```sh jason status --provider-cli my-provider-cli ``` The check looks the name up on the PATH of the process that runs `jason status`, and its answer says so whenever it read a PATH: *It read the CLI's PATH; the runtime's PATH may differ, see the install page.* The runtime has a PATH of its own, fixed when it started, and a runtime started at logon or from another shell may not see a program your terminal does. That is the case `plugin_availability` above names for a plugin's program; this check does not ask the runtime to look. A name given as a path is looked up in its own directory and reads no PATH, so the answer says nothing of one, with one exception: an npm shim given as a path takes its `node.exe` from the PATH when none stands beside it, and then the answer says whose PATH that was. Under Jason Desktop's chat the check is held tighter: the chat runs `jason` with `JASON_CONFINED` set, so the program is named by name and found on the search path, and a name with a directory in it is neither looked up nor started. Run a path from a terminal. **When something does not work**, run `jason doctor --dry-run`, then `jason doctor`, and open an [issue](https://github.com/reply-team/jason-ai/issues/new?template=problem.yml) with the file it wrote attached: the address it prints fills in the version and the platform. Help with your own data, or a file made with `--include-journal`, goes to the support address the README gives under Getting help, never to an issue; a vulnerability goes the way [SECURITY.md](../SECURITY.md) says. --- ## 6. Start it, and keep it started ```sh jason runtime start jason runtime status jason runtime stop ``` `start` launches the runtime in the background and prints the instance it ended up talking to; `stop` asks that instance to shut down and returns only once it has really gone. Migrations apply automatically on start, after a backup. Nothing is registered until you ask. **Ask first.** To have the runtime start when you log on: ```sh jason runtime autostart enable jason runtime autostart status ``` The registration carries the data directory it was made under, and nothing supervises it afterwards: a runtime that stops stays stopped until somebody starts it. It needs no administrator rights anywhere, and it is this account's alone: on a machine several people sign in to, each registers their own. On Windows the runtime then runs in your own session when you sign in, shows no window on Windows 11 24H2 and later, and ends when you sign out. On Windows that is a logon task named for this account; on macOS a LaunchAgent, `ai.jason.runtime`; on Linux a `systemd --user` unit, `jason.service`. `jason runtime autostart status` says what is registered. That is the installation. What comes next is yours to choose, and an agent that installed Jason asks you once: [the wiring check](golden-path.md) — a page of its own, a synthetic walk to meet the system, your provider connected and proven with your own address, and not the real work — or the real work at once. Skip the walk and it is not offered again. The real work, at once or after the walk, begins with you telling your agent about your first campaign in your own words — typed, a link, a file or a voice note, or an example to start from — and becomes a campaign planned with the business skills, [`campaign-planning`](../skills/business/campaign-planning/SKILL.md) first, and worked by Jason's roles. --- ## 7. Take it off again ```sh jason uninstall --human --dry-run ``` Look first: it prints exactly what it would remove and changes nothing. ```sh jason uninstall ``` **Skills go only by receipt.** Every root a deployment wrote into carries a record listing each path written there, and this verb removes those skills and nothing else. A skill you copied into a harness by hand has no receipt, so it is removed by nobody — including this. The rest of the installation goes by rule, in a fixed order: this account's logon registration first — on Windows including the task `\Jason` an earlier version registered for it — so a logon part-way through cannot start what is going; then the runtime, and if it will not stop — or is running and does not answer — nothing after that is removed; then, on Windows, the notification registration — the AppUserModelID key the toast was shown under, the two entries Windows made for it at the first toast, and the `jason:` link where its command names this executable — after the runtime, so its next toast cannot write them back; then the recorded skills; then the PATH entry, only where the installer wrote it; then the executable, its two notice files, its install directory, and the native libraries a release unpacks the first time it runs — under the temporary directory on Windows, under `~/.net` on macOS and Linux. On Windows what every other build of Jason unpacked beside them goes too: the versions this installation was before an update, and any other installation of this account, which nothing there tells apart. A build unpacks again on its next start, and a copy running now holds its own, which stays and is named. On macOS and Linux a running copy holds nothing, so what the other builds unpacked stays: the plan and the report count those directories, name the directory they are in, and leave them for you to remove once nothing runs from them. With `DOTNET_BUNDLE_EXTRACT_BASE_DIR` set they are not looked for at all. The notice files go by name: on macOS and Linux it removes those two files by name from a directory other tools share, and a `LICENSE` there that is not one of them is another tool's and stays. "Only where the installer wrote it" is one rule on both platforms: the entry goes only where the installer wrote it **and** its directory holds nothing but what the installer puts there, because other programs are on the PATH through the same entry. On macOS and Linux the entry is the block the installer appends to a login profile, and to `~/.bashrc` or `~/.zshrc` beside it — a marker line and the `export` line under it; a line nobody marked is yours and stays, and so does the block where the directory holds more than `jason` and its two notice files: `~/.local/bin`, the installer's default, is where other tools install too. On Windows the Path carries no marker, so the entry goes only where its directory holds nothing but the executable, its two notice files (`jason-LICENSE`, `jason-THIRD-PARTY-NOTICES`) and the `jason.previous.exe` an upgrade can leave beside it. An entry that stays is named in the report, with the reason. On Windows the executable is the file the uninstall is running from, and Windows does not delete the image of a running process. So it is moved out of the install directory, to a directory on the same volume — which then goes, before the verb returns — and a cleanup it starts removes the moved copy as soon as the verb has exited. The report names both, and the line that removes the copy by hand should it still be there; where no cleanup could be started, that copy is a problem and the verb exits 1. Where Homebrew or winget installed Jason, the executable, its directory and the PATH entry that reaches it are the package manager's: the dry run and the report list them as left to it, with the command that takes them off — `brew uninstall jason`, or `winget uninstall Reply.Jason` — and `jason uninstall` removes the rest as above, the runtime stopped first. **Three things are this account's rather than this installation's**: the logon registration, the notification registration on Windows, and the agent harnesses. An uninstall of a second installation on the same account — a build from source beside a release, a copy — takes the registrations and the harness skills the first one made as well. The `jason:` link goes only where its command names this executable. Look at the dry run first. The notifications already in the notification center stay: they are yours to dismiss. A recorded file whose bytes have changed since is reported and kept, because the record says what Jason wrote and a mismatch says somebody else wrote it afterwards. `--force` removes it anyway: ```sh jason uninstall --force ``` **The data directory is kept.** It holds the database, the settings, the plugins, the logs and the work directories — the record of what you did — and the copies an update keeps — the executable it replaced and the copy of the program kept for finishing an interrupted update, under `update/` — so a copy of the program stays there after an uninstall until `--purge-data` removes it; and the verb says in one line that it kept it and where. To take it to another machine instead, `jason export` writes it and the harness root into one archive (§8). To remove that as well you have to say so: `--human` prints what will be deleted and asks before anything at all is removed — and a no removes nothing at all — and when nobody is there to be asked the word is said in advance: ```sh jason uninstall --purge-data --yes ``` It removes what Jason keeps in the data directory, and the directory itself once nothing else is in it: a file of yours in there stays, and is named. And a data directory that is not one — a file system's root, a directory holding your profile, the temporary directory or the installation, or a folder of the harness root, one inside it, or one holding such a folder directly in it or anywhere in a folder the purge would delete, known by its `.jason/marker.json`, or holding a folder there that cannot be looked into, which a stray `JASON_DATA_DIR` can name — is refused before anything is removed. Nothing else is touched: no skill without a receipt, no other skill in an agent harness, no provider CLI, no model credential, no PATH entry the installer did not write, no other account's logon registration, and none of the notifications already in the notification center. Nor is anything under the harness root (§2) — your memory files and every project's and campaign's folder — whatever `--purge-data` says. A link in the data directory, a symbolic link or a junction, is removed as itself, and what it points to is never touched. It exits 0 when everything it set out to remove is gone, and 1 when it did not get there — it refused (a runtime that would not stop, a purge you did not confirm), something it set out to remove is still there (a record it could not read, a file it could not remove, a moved copy nothing will remove), or it stopped part-way. Every step that did happen is listed either way: in the report on stdout, or on stderr where the report itself could not be written. ### Jason Desktop The desktop is taken off its own way, because it places things `jason uninstall` has no receipt for. On Windows, remove Jason from Installed apps in Settings. On macOS and Linux, choose Remove What Jason Placed… in the Jason menu first, then remove the application: move Jason.app to the Trash, `sudo apt remove jason-desktop` for the deb, or delete the AppImage file. [desktop.md](desktop.md) says what each step takes off, what stays (the data directory, the harness root and the updater's cache) and what to do by hand when Jason will not start. ## 8. Moving the installation to another machine Install Jason on the new machine first (§2), the same version or a newer one: an archive a newer Jason wrote is refused, naming the version to install. Then stop the runtime on the old machine and write the archive: ```sh jason runtime stop jason export ``` `jason export` writes `jason-export-.zip` in the folder you run it in, or the file you name, and never over a file that is already there. `--stop` stops a running runtime for you and starts it again once the archive is written; without it the verb refuses while the runtime runs. A link at the top of a carried place, `ui/custom/` as a junction to a build of your own say, or a harness root that is one, is followed and carried as what it leads to, unless that is inside the data directory or the harness root, or holds either; a link inside a carried place, a name another system cannot hold, and two names apart only by the case of their letters are refused by their path. The archive is written to `.partial` first and moved into place once whole; a `.partial` an export left behind is refused, as yours to remove. Copy the archive across, then on the new machine: ```sh jason import jason-export-20261109T100005Z.zip jason skills install jason runtime autostart enable jason status ``` **What travels:** the database, the settings file, the plugins, the role skills with their record, a custom UI under `ui/custom/`, the logs, and the harness root's tree — your memory files and every project's and campaign's folder, each whole, a `.git` included — with `export.json` listing every file's size and SHA-256. Whether the runtime started at logon travels as a fact: the import registers it again on a machine that can, and on one that cannot says "No logon registration, and this machine has no way to register one." **What does not:** the backups under `state/backups/`, the run and work directories, staged skills, the shipped UI under `ui/default/`, the copies an update keeps, anything an earlier import moved aside, the skills deployed into agent hosts (`jason skills install` deploys them again), and anything outside the data directory and the harness root. **The archive carries the settings file with everything in it, a token under `Plugins:Config` included: keep the archive as you keep that file.** **Before anything is written**, the import refuses an archive it cannot read, a name in it that would land outside the data directory or the harness root, a file whose size or SHA-256 is not the one `export.json` lists, an archive a newer Jason wrote, and an installation already here — a database, or a harness root with a folder marker in it, which a Jason that has run once on the new machine has. The refusal names what is there. Give `--replace` to move it aside and place the archive instead: the data directory's parts go into `/replaced-/` — `state/` whole, the database's `-wal` and `-shm` files and its backups with it — and the harness root to `.replaced-`, nothing is deleted, and the answer names both as yours to remove. On a machine with no installation the import still writes over nothing: the same parts that stand there, a `jason.db-wal` or `jason.db-shm` beside no database among them, go aside the same way and are named, since SQLite would read such a file as the placed database's. The harness root is `--root` when given, else the one this machine's runtime would read (`JASON_Harness__Root`, else `Harness:Root` in this machine's settings file, else `~/Jason`); a `--root` the variable contradicts is refused, naming the variable, and the root is held to the runtime's own rule for one — an absolute path, not the home directory, a folder holding it or the top of a drive, nor the data directory, a folder inside it or one holding it — before anything is placed. **The settings file is made this machine's.** Every absolute path under the old machine's home directory, data directory or harness root is rewritten to the same place here, `Harness:Root` first, and each rewrite is said; a path elsewhere that is not on this machine is said and left as written, for you to correct. Every other value, the secrets among them, is placed as it was. A role skills pack the record says came from a folder that is not here is named, with `jason skills install` to deploy it again. **Then the runtime starts on it**, and the import asks it to record each project folder where it now stands, as `jason project link` does; a link the runtime refuses is named with its code, the folder stays, and the answer's `next` carries `jason project link --path `. An import on the same machine, into a second data directory, needs the source harness root moved aside first: the records name its folders, and the runtime refuses to link a folder that is present elsewhere (`harness_folder_present`). The import exits 0 when everything was placed and the runtime answered, 1 when it refused (nothing written) or the runtime did not start (the files are in place; start it with `jason runtime start`), and 2 on a usage error. Three things are left to you, in this order: `jason skills install`, `jason runtime autostart enable` if the runtime should start at logon here and the import did not register it, and `jason status`.