CLI Reference
A command-line interface for managing Stash from your terminal — push session events and manage all resources.
--json for machine-readable output.Install
uv tool install stashaiFirst-time setup
Run the interactive setup wizard. It configures the API endpoint, authenticates you through the browser, and sets up your Stash — all in one shot. No manual config editing required.
stash connectThe wizard saves everything to ~/.stash/config.json. Once complete, commands like stash sessions push work without extra flags.
Virtual filesystem
Use stash vfs when an agent needs to browse Stash through one filesystem-shaped interface without mounting anything into the OS. Your Stash exposes files, sessions, skills, tables, and sources — the last surfacing every connected integration (Gmail, GitHub, Slack, Jira, …) as read-only documents you can ls, cat, and grep.
stash vfs ls /
stash vfs "find /me -maxdepth 3 -type f"
stash vfs "rg 'database migration' /me"
stash vfs --cwd "/me/sources" "rg 'incident' ."stash vfs[--cwd PATH] "command"Run bash-shaped read and write commands against the virtual Stash tree.
--cwdstringVirtual working directory. Defaults to /.
commandstringBash-shaped command such as ls, find, rg, cat, sed, tee, or redirection.
Authentication
stash signin[--api <base_url>] [--api-key <key>] [--non-interactive]Authenticate this machine. With no flags it runs the browser flow: on first run it also picks the endpoint (managed or self-host) and offers to install streaming hooks for your coding agents. On SSH/headless it prints a URL to open instead of launching a browser. Pass --api-key to store a pre-minted key directly (no browser) on an unattended, browser-less machine — typically a self-hosted CI runner; get the key from your self-hosted instance's API-key page.
--apistringBase URL of the Stash server. Override for self-hosted deployments.
--api-keystringA pre-minted key to store directly, skipping the browser. For unattended, browser-less machines.
--non-interactiveflagSkip the setup wizard; just authenticate. Implied when stdin isn't a terminal.
STASH_API_KEY / STASH_URL in the environment authenticates CLI commands for CI and scripts — but it does not reach the streaming hooks, which read ~/.stash/config.json. To make an unattended machine stream, use stash signin --api-key. Change the endpoint or streaming agents later from stash settings.stash whoamiDisplay the currently authenticated user.
stash disconnectSign out and clear all stored credentials so the next stash connect re-onboards.
stash settings[--json]Interactive settings page — change the endpoint, toggle which agents stream, and view config. Pass --json for a read-only snapshot.
--jsonflagPrint a read-only snapshot instead of the interactive page.
stash connect, your defaults are stored. Change the endpoint any time from stash settings, or set STASH_API_KEY / STASH_URL as environment variables for CI and scripts.Files
stash files pagesList pages in your Stash.
stash files treeShow the folder and page tree for your Stash.
stash files create-folder<name> [--parent FOLDER_ID]Create a folder in the files.
<name>stringREQUIREDFolder name.
--parentstringParent folder ID.
stash files add-page<name> [--folder FOLDER_ID] [--content '...']Add a new page to the files.
<name>stringREQUIREDPage title.
--folderstringFolder ID.
--contentstringInitial page content.
stash files read-page<page_id>Read a page.
<page_id>stringREQUIREDID of the page.
stash files edit-page<page_id> --content '...'Update a page. Reads from stdin if --content is not given.
<page_id>stringREQUIREDID of the page.
--contentstringNew page content. Reads from stdin if omitted.
Sessions
stash sessions push<content> [--agent cli] [--type message] [--session ID] [--attach FILE]Push a new event to your session stream.
<content>stringREQUIREDEvent content to push.
--agentstringAgent identifier. Defaults to "cli".
--typestringEvent type. Defaults to "message".
--sessionstringSession ID to group events under.
--toolstringTool identifier.
--attachpathLocal file path to upload and attach. Repeatable.
--attach-idstringPre-uploaded file ID to attach. Repeatable.
stash sessions query[--agent X] [--type Y] [-n 50]Query recent session events with optional filters.
--agentstringFilter by agent identifier.
--typestringFilter by event type.
-n, --limitnumberMaximum number of results. Defaults to 50.
stash search with --source sessions (see Sources & search below). It replaces the old per-resource search commands.stash sessions foldersList session folders — shareable groupings of sessions.
stash sessions new-folder<name>Create a session folder.
<name>stringREQUIREDFolder name.
stash sessions agentsList distinct agent names that have logged events in your Stash.
stash sessions transcript<session_id> [--save PATH]Fetch a full session transcript and print or save it. Transcripts are stored gzipped on the server and decompressed automatically.
<session_id>stringREQUIREDID of the session.
--savepathSave the transcript to a file instead of printing.
Sources & search
A source is anything the agent can read, exposed as a virtual file system: the two native sources — files and sessions — plus your connected sources (GitHub, Google Drive, Gmail, Notion, Slack, Granola). Pick a source like a drive, browse it by path, read a document, or search one source — or everything at once.
stash sources lsList every source you can read here: the native files and sessions sources plus your connected sources. Each row prints a source handle to use with the other commands.
stash sources add<source_type> [--ref REF] [--name NAME]Connect a source. Slack and Granola resolve their reference from your connected token; Gmail uses the mailbox email as --ref; the others need a --ref (e.g. a repo 'owner/name').
<source_type>stringREQUIREDgithub_repo | google_drive | gmail | notion | slack | granola.
--refstringExternal reference, e.g. a repo 'owner/name' or Gmail address.
--namestringDisplay name for the source.
stash sources browse<source> [path]List a source's entries like a file system.
<source>stringREQUIREDA source handle from stash sources ls.
pathstringPath prefix (connected sources only).
stash sources read<source> <ref>Read one document from a source.
<source>stringREQUIREDA source handle from stash sources ls.
<ref>stringREQUIREDPage id (files), session id (sessions), or document path (connected sources).
stash sources sync<source_id>Trigger an immediate re-index of a connected source you own.
<source_id>stringREQUIREDID of the connected source.
stash sources rm<source_id>Disconnect a source you own. Its indexed documents are removed.
<source_id>stringREQUIREDID of the connected source.
stash search<query> [--source HANDLE] [-n 20]Search across everything you can see — files, sessions, and connected sources. Pass --source to scope to one; omit it to search everything.
<query>stringREQUIREDSearch query.
--sourcestringScope to one source handle (from stash sources ls). Omit to search everything.
-n, --limitnumberMaximum number of results. Defaults to 20.
Tables
stash tables listList tables in your Stash.
stash tables create<name> [--columns JSON]Create a new table with optional column definitions.
<name>stringREQUIREDName for the table.
--columnsJSONColumn definitions as a JSON array of {name, type, options?}.
stash tables update<table_id> [--name TEXT] [--description TEXT]Update a table's name or description.
<table_id>stringREQUIREDID of the table.
--namestringNew table name.
--descriptionstringNew table description.
stash tables schema<table_id>Show a table's column schema.
<table_id>stringREQUIREDID of the table.
stash tables rows<table_id> [--sort COL] [--filter COL]Fetch rows from a table. Sort and filter accept column names, which are auto-resolved.
<table_id>stringREQUIREDID of the table.
--sortstringColumn name to sort by.
--filterstringColumn name to filter on.
stash tables insert<table_id> <data_json>Insert a new row. Data is a JSON object with column names as keys.
<table_id>stringREQUIREDID of the table.
<data_json>JSONREQUIREDRow data as a JSON object.
stash tables import<table_id> <file> [--format csv|json]Bulk import rows from a file. Auto-chunks into batches of 5000. CSV uses the first row as column headers. Supports piping: cat data.csv | stash tables import <id> --format csv.
<table_id>stringREQUIREDID of the table.
<file>pathREQUIREDPath to the import file.
--formatstringFile format: "csv" or "json". Auto-detected if omitted.
stash tables update-row<table_id> <row_id> <data_json>Update an existing row with a partial merge. Data is a JSON object with column names as keys.
<table_id>stringREQUIREDID of the table.
<row_id>stringREQUIREDID of the row to update.
<data_json>JSONREQUIREDUpdated row data as a JSON object.
stash tables delete-row<table_id> <row_id>Delete a row from a table.
<table_id>stringREQUIREDID of the table.
<row_id>stringREQUIREDID of the row to delete.
stash tables add-column<table_id> <name> [--type text] [--options TEXT]Add a column to a table.
<table_id>stringREQUIREDID of the table.
<name>stringREQUIREDColumn name.
--typestringColumn type. Defaults to "text".
--optionsstringComma-separated options for select/multiselect columns.
stash tables delete-column<table_id> <column_id>Delete a column from a table.
<table_id>stringREQUIREDID of the table.
<column_id>stringREQUIREDColumn ID (col_xxx) or column name.
stash tables count<table_id>Count rows in a table, optionally with filters.
<table_id>stringREQUIREDID of the table.
stash tables export<table_id>Export all rows from a table as CSV.
<table_id>stringREQUIREDID of the table.
stash tables delete<table_id> [-y]Delete a table and all its data.
<table_id>stringREQUIREDID of the table.
-y, --yesflagSkip confirmation prompt.
Uploaded Files
stash upload<path> [--skill TITLE]Upload a single file (Markdown/HTML become pages, everything else a binary file) or a folder into your Stash. Pass --skill to also bundle it into a shareable Skill.
<path>pathREQUIREDFile or directory to upload.
--skillstringAlso publish the upload as a Skill with this title.
stash files listList your files.
stash files text<file_id>Print extracted text for a file (PDF, image OCR, or plain text).
<file_id>stringREQUIREDID of the file.
Object operations
One set of verbs across every object type. Pass items as type:id tokens (e.g. page:abc, file:def, session:ghi); each verb accepts several at once.
stash rm<type:id>... [--permanent]Move pages, files, or sessions to trash. Pass --permanent to skip the trash window and delete immediately.
<type:id>stringREQUIREDItems to delete, e.g. page:<id> session:<id>.
--permanentflagDelete immediately instead of trashing.
stash restore<type:id>...Restore pages, files, or sessions from trash.
<type:id>stringREQUIREDItems to restore, e.g. page:<id> file:<id>.
stash mv<type:id>... (--to-folder ID | --to-root)Move pages, files, folders, tables, or sessions into a folder, or to the root.
<type:id>stringREQUIREDItems to move.
--to-folderstringTarget folder id.
--to-rootflagMove to the root.
stash cp<type:id>... [--to-folder ID]Duplicate pages, files, or folders as 'Copy of <name>'.
<type:id>stringREQUIREDItems to copy.
--to-folderstringTarget folder id for the copies.
Skills
A Skill is a special folder — one containing a SKILL.md — of pages, files, and tables. Publishing a skill makes it publicly readable at its link (optionally listed in Discover); to share privately with a specific person, share its folder like any other folder. (The stash CLI name is unchanged.)
stash skills listList Skills in your Stash.
stash skills create<name> [--public] [--discover]Create a skill: a folder with a SKILL.md template. Pass --public to publish immediately.
<name>stringREQUIREDSkill name (becomes the folder name).
--publicflagPublish immediately and mint a shareable link.
--discoverflagList the public Skill in the Discover catalog (requires --public).
stash skills publish<folder_id> [--discover]Publish an existing skill folder: mint its share record and print the public URL.
<folder_id>stringREQUIREDThe skill folder to publish.
--discoverflagList the public Skill in Discover.
stash skills snapshot-source<skill_id> --source ID --path PATHCopy a point-in-time snapshot of one connected-source document into the Skill as a page, so the skill stays self-contained.
<skill_id>stringREQUIREDID of the Skill.
--sourcestringREQUIREDConnected-source id (from stash sources ls).
--pathstringREQUIREDDocument path within the source.
stash skills fork<slug>Fork a public Skill: deep-copy its folder into your Stash.
<slug>stringREQUIREDPublic Skill slug.
stash skills unpublish<skill_id>Stop sharing a Skill: delete its publish record. The folder stays.
<skill_id>stringREQUIREDID of the published Skill.
Shares
Share a single object — a folder, page, file, session, or table — with a specific person by email. If they don't have an account yet the share is recorded as pending and converts when they sign up. (To share a whole folder of related work, convert it to a Skill.)
stash shares ls<object_type> <object_id>List who an object is shared with.
<object_type>stringREQUIREDfolder | page | file | session | table.
<object_id>stringREQUIREDID of the object.
stash shares add<object_type> <object_id> <email> [--permission read]Share an object with a person by email.
<object_type>stringREQUIREDfolder | page | file | session | table.
<object_id>stringREQUIREDID of the object.
<email>stringREQUIREDRecipient email (pending until they sign up).
--permissionstringread | write | admin. Defaults to read.
stash shares rm<object_type> <object_id> <principal_id> [--principal-type user]Revoke a person's access to an object.
<object_type>stringREQUIREDfolder | page | file | session | table.
<object_id>stringREQUIREDID of the object.
<principal_id>stringREQUIREDThe user id to revoke (from stash shares ls).
--principal-typestringPrincipal kind. Defaults to "user".
Keys
stash keys listList your active API keys (one per device / login).
stash keys revoke<key_id>Revoke an API key by ID. Any device using it will receive a 401 on the next call.
<key_id>stringREQUIREDID of the key to revoke.
Streaming & hooks
Install Stash hooks for all supported coding agents on your $PATH, then enable or disable streaming per repo.
stash installInstall hook plugins for all supported coding agents on your PATH.
stash enableRe-enable activity streaming for the current repository.
stash disableStop streaming for this repo without touching the committed manifest.
stash settings[--json]Open the interactive settings page.
--jsonflagPrint a read-only snapshot of settings instead of opening the interactive page.