Sessions
Runbooks keeps a session for every runbook you open. A session is what the runbook’s blocks build up as you run them:
- A directory of its own. Scripts start there, <GitClone> blocks clone into it, and generated files are written to it.
- The environment variables that scripts exported and auth blocks set.
- The directory the last script left off in.
- The repositories its <GitClone> blocks cloned or opened.
- Its history: what you did in its blocks. The values you typed into forms, every script run with its status, logs and outputs, the repositories you cloned or selected, the pull requests you opened, and the accounts you signed in to.
Runbooks saves the session after every change, so quitting the app keeps it.
Session names
Section titled “Session names”Every session has a name made of an adjective and a noun, such as elegant-elephant. The title bar shows it after the runbook’s name, labelled Session, along with how far through the runbook you are. The window title starts with the session’s name too.
A runbook’s name is the name of the folder its runbook.mdx is in. A remote runbook at the root of its repository is named after the repository. The button before the runbook’s name copies the full path of its file, or for a remote runbook the URL you opened it from.
The copy button before the session’s name copies it. The folder button after the name copies the path of the session’s directory. It is the session’s directory for every runbook, including a remote one, whose temporary clone it does not point to.
Paths on screen are shortened: a path in the session’s directory starts with session/, as in session/generated, and any other path in your home directory starts with ~/. Hover over one to see it in full. Copy buttons copy the full path, and scripts and other blocks get the full path too.
Runbooks picks the name when it creates the session, and the session keeps it until you rename it. No two sessions share a name. If a random pick is already taken, Runbooks picks again, and after ten tries it adds a number, as in elegant-elephant-2.
Renaming a session
Section titled “Renaming a session”Click the name in the title bar, or choose File > Rename Session… or Rename Session in the app’s menu. Type the new name and press Enter. Press Esc or click elsewhere to keep the name as it was.
A name follows these rules:
- It is 1 to 63 characters long.
- It uses lowercase letters (
atoz), digits and hyphens. Uppercase letters are lowercased as you type. - It starts and ends with a letter or digit, and has no two hyphens in a row.
- No other session has it.
prod-deploy and release-2026-10-02 are allowed. Prod Deploy, prod_deploy and -prod are not. When a name is refused, the title bar says why and the session keeps its name.
Renaming changes only what the session is called. Its directory, files and environment stay as they are.
Resuming a session
Section titled “Resuming a session”Opening a runbook resumes its most recent session, unless you finished the runbook in it. Scripts run with the environment variables and working directory the earlier run left, and the session’s files are where they were. That holds for a runbook you close and open again without quitting the app, too.
A notice at the top of the runbook names the session it resumed and says when you last used it. Click Start new session in it to reset the session instead. A session with nothing in its history gets no notice: there is nothing of it to come back.
The blocks come back as you left them, and so does the runbook’s progress. Each block shows what the session’s history has for it at once. A block whose state depends on something outside the app then checks it in the background, and starts over, saying why, if it no longer holds:
| Block | What comes back | What is checked |
|---|---|---|
| <Inputs> | The values you typed, and the values you entered in place of a linked value’s chips. A form you had submitted is still submitted. | |
| <Command> and <Check> | The last run: its status, logs and outputs. A block that reads another block’s output runs without that block running again. The outputs you entered by hand. | |
| <Finish> | Whether you finished the runbook, with the last run of its final check if it has one. It doesn’t celebrate again. | |
| <Prerequisites> | The last check: what it found for each tool, its logs and its outputs. It doesn’t check again. | |
| <Template> | The values you typed, the values you entered in place of a linked value’s chips, and whether you had generated its files. | |
| <GitClone> | The repository you cloned or selected, with its outputs. | That it is still a git repository on disk. |
| <DirPicker> | The path, with a dropdown selection for each of its directories that is still there. | |
| <GitPullRequest>, <GitHubPullRequest> and <GitLabMergeRequest> | The pull or merge request you opened, with its outputs, and the form fields you edited. | |
| <Iframe> | Not the outputs its page set. Blocks that read them wait until the page sets them again. | |
| <AwsAuth> | The account you signed in to. | That its credentials still work. Temporary ones expire. |
| <GitAuth>, <GitHubAuth> and <GitLabAuth> | The account you signed in to. The session’s token is still sent only to the host you signed in to. | That the token still works for that host, and still belongs to that account. |
| <GoogleAuth> | The account you signed in to, when the sign-in can be done again. | That the credential still signs in as that account. Runbooks then signs in again the same way. |
A check that can’t reach AWS, GitHub or GitLab, because you are offline for example, leaves the sign-in as it is.
Credentials that work now can still expire later in the session. When the provider says when, the history saves it with the sign-in, and the block turns red and asks you to sign in again from five minutes before then. That works the same in a resumed session as in a new one. Each auth block’s page lists which credentials have an expiry: <AwsAuth>, <GitAuth> and <GoogleAuth>.
A resumed <GitClone> also checks which branch the repository is on. If it is no longer on the branch the session cloned or found it on, the block turns red and names both branches, and Runbooks leaves the repository as it is. Check out the session’s branch in the repository, or clone again.
A resumed <Template> or <TemplateInline> writes its files only when they would come out differently than it last wrote them. A change made to a generated file since stays until something the template uses changes.
A script that was still running when Runbooks quit shows as not run, with a notice that its last run did not finish.
<GoogleAuth> can sign in again from a gcloud configuration, from credentials it detected in the environment or in gcloud’s application default credentials, from a key file you chose, or from another block’s outputs. It can’t from a key you pasted or from Sign in with Google: Runbooks deletes the credential files it writes for those when it quits. A block signed in that way says so and asks you to sign in again.
A <GoogleAuth> credential that now signs in as another account is not used: the block asks you to sign in again, and later resumes start over. When signing in again fails for any other reason, such as a key file that was moved or no network, the block asks you to sign in, and the next resume tries again.
See The session’s history for what is saved and when.
Which session opens depends on how you launch Runbooks:
| Launch | What opens |
|---|---|
runbooks open SOURCE |
SOURCE, in its most recent session. A runbook you have not opened before gets a new one. |
runbooks with no arguments, in a terminal |
The session last launched from the terminal’s current directory. If there is none, the welcome screen. |
| The dock, the Start menu, or a desktop shortcut | The most recent session. If there is none, the welcome screen. |
A session you finished the runbook in is never what opens: its runbook opens in another session, as Finishing a session describes.
Runbooks records the directory you ran runbooks open SOURCE from, which is how runbooks alone finds the session later. Your home directory counts as no directory: runbooks run there opens the most recent session.
A remote runbook is cloned again every time it opens, and resumes the session of the source you opened it with.
If a resumed session’s working directory or one of its cloned repositories has been deleted, the session starts in its own directory and drops the missing repository.
Resetting a session
Section titled “Resetting a session”Choose File > Reset Session, or Reset Session in the app’s menu, to start the open runbook over. Its blocks go back to their initial state, and scripts run in an empty directory with the environment Runbooks was launched with.
A reset replaces the session with a new one, so the name in the title bar changes. The runbook resumes the new session from then on.
Nothing is deleted. The session that was replaced keeps its directory, files and history on disk. Switch to it to pick it up again, or delete it.
Finishing a session
Section titled “Finishing a session”A runbook can end with a <Finish> block. When you click Finish, and its final check passes if it has one, you have finished the runbook, and Runbooks marks the session finished. In instruction mode, ticking Mark as done on the <Finish> block does the same. A session is marked finished once: finishing the runbook again in it, or a later failed final check, changes nothing.
Runbooks doesn’t resume a finished session on its own. The next time you open its runbook, in the running app or after a restart, the runbook opens in a new session. A notice at the top of the runbook names the finished session, with a Switch session… button to go back to it or to another session.
A finished session keeps its directory, files and history, and Switch Session… lists it with a Finished label. Switching to it opens it as you left it, the <Finish> block finished too, and the notice that it was resumed says when you finished it. A watch mode reload keeps it open.
Switching to a finished session doesn’t make it the one the runbook opens in: it stays finished. If you started another session of the runbook after you last finished it, opening the runbook again resumes the most recent of those that isn’t finished. Otherwise it starts a new session.
Switching sessions
Section titled “Switching sessions”Choose File > Switch Session…, or Switch Session… in the app’s menu, to see the saved sessions. They are grouped by runbook, the open runbook first, and each shows when it was last used and how many scripts it ran. A session you finished the runbook in has a Finished label. Type in the filter box to narrow the list by session name or runbook.
Click a session to open its runbook in it. Its blocks, environment and working directory come back as Resuming a session describes. A remote runbook is cloned again first. A session whose local runbook file has been deleted is listed but can’t be opened.
If a script is running, Runbooks asks before switching, since the switch stops every running script.
The session you switch to counts as launched again. Launching Runbooks from the dock resumes it next, and so does runbooks run in the directory it was last launched from, unless it is a finished session.
The session’s history
Section titled “The session’s history”Runbooks adds an entry to the session’s history each time you act on a block:
- You change a value in a form, submit the form, or generate its files. The entry has the form’s values. Changes to one form that follow each other are one entry, so the history has the form as you left it and not every keystroke. The same goes for a <DirPicker> path and the fields of a <GitPullRequest> form.
- A <Command> or <Check> script, the final check of a <Finish> block, or the check of a <Prerequisites> block, starts, and it ends. The entry for the end has the status, the exit code, the outputs, and the newest 500 lines of the log, up to 64 KiB of text, and the path of the full log. Outputs larger than 512 KiB in total are left out. The resumed block says so, and the blocks that read them wait until it runs again.
- You click Finish on a <Finish> block without a final check. The entry is a run that succeeded, with no log.
- A <Template> or <TemplateInline> writes its files. The entry has a hash of what it wrote, not the files.
- A <GitClone> block gets a repository, or you start it over.
- A <GitPullRequest> block opens a pull or merge request, or you set it aside to open another.
- An auth block signs in, or you sign it out.
- The generated files left to review change, because a file changed or you reviewed one, and then stay the same for a second. The entry lists them, with what each modified file was when you last reviewed it, up to 512 KiB in total. Past that, a file is kept as modified without what it was, so a resumed session highlights it but not its lines.
The history keeps every entry in order. The app reads only the latest entry of each block, which is what a resumed session shows.
A block also resumes from its latest entry when the runbook is reloaded in watch mode, or closed and opened again without quitting the app.
A resumed session’s Generated panel lists the files its blocks wrote, and highlights the ones you had yet to review. Runbooks doesn’t offer to delete them when the runbook opens: they are the session’s own.
Where sessions are stored
Section titled “Where sessions are stored”Sessions live in the v0/sessions folder of the app’s data directory:
| OS | Path |
|---|---|
| macOS | ~/Library/Application Support/Runbooks/v0/sessions |
| Linux | ~/.config/Runbooks/v0/sessions |
| Windows | %APPDATA%\Runbooks\v0\sessions |
Directorysessions/
Directorydb/
- sessions.db A SQLite database of the sessions and their histories
Directorydirs/
Directory0199a5c2-7e3b-7c4d-9a1f-3b2c4d5e6f70/ One directory per session
Directory.runbooks/
Directorylogs/
Directorydeploy/ One directory per block
- 2026-10-02T14-03-11-482Z-k3x9qa.log The full log of each script run
Directorygenerated/
- …
Directorymy-cloned-repo/
- …
Every <Command> and <Check> run, and every final check of a <Finish> block, writes its full log to .runbooks/logs in the session’s directory, in a directory named after the block’s id. Copy log file path on a block copies the path of its last run’s log, in a resumed session too. Runbooks keeps the logs as long as the session.
The database records each session’s name, its runbook, its directory, its working directory, its cloned repositories, the directory it was last launched from, the host each of its git tokens belongs to, when you finished its runbook, its environment, and its history. A session’s directory is named after its id, a UUID that never changes, not after its name. To get the directory of the open session, click the folder button next to its name in the title bar. For any other session, look its name up:
sqlite3 sessions/db/sessions.db "SELECT dir FROM sessions WHERE name = 'elegant-elephant'"What is encrypted
Section titled “What is encrypted”The environment can hold credentials: cloud keys an auth block exported, or a token a script set. So can the history: a password typed into a form, a script’s sensitive output, a secret a script printed to its log, or the keys and token an auth block signed in with. Runbooks encrypts the environment and the content of every history entry with the operating system’s credential store before writing them to the database: Keychain on macOS, DPAPI on Windows, and a secret service such as GNOME Keyring or KWallet on Linux.
On Linux without a secret service, Runbooks saves neither. A resumed session there starts from the environment Runbooks was launched with and with its blocks as new, and keeps its directory and files.
The rest of the database is not encrypted, including which block each history entry belongs to and when it was added. Neither are the files in a session’s directory. Those include the full log of every script run, with anything the script printed.
Deleting sessions
Section titled “Deleting sessions”Runbooks keeps every session until you delete it. Their cloned repositories add up, and so do their histories and their logs: every script run adds a history entry and a log file.
To delete a session, open Switch Session…, click the trash icon next to it, and click the red trash icon to confirm. Its history is deleted. Its directory, with the files its blocks generated, the repositories they cloned and the logs of its script runs, goes to the Trash (the Recycle Bin on Windows), named after the session’s id. Restore it from there if you deleted the session by mistake; the files come back, but the session doesn’t. If the directory can’t be moved to the Trash, Runbooks says why and keeps the session. The open session can’t be deleted: switch to another one first.
To remove every session, quit Runbooks and delete the sessions folder.