CLI Reference
Complete reference for all sfs commands.
Global Options
Section titled “Global Options”sfs [OPTIONS] COMMAND [ARGS]...| Option | Description |
|---|---|
--help |
Show help and exit |
--version, -V |
Show the installed version (sessionfs X.Y.Z (python …, platform arch)) and exit. Also available as sfs version. |
sfs list
Section titled “sfs list”List captured sessions.
sfs list [OPTIONS]| Option | Type | Default | Description |
|---|---|---|---|
--tool |
string | — | Filter by source tool (e.g., claude-code) |
--since |
string | — | Show sessions since time (7d, 24h, or ISO date) |
--tag |
string | — | Filter by tag |
--sort |
string | recent |
Sort order: recent, oldest, messages, tokens |
--json |
flag | false |
Output as JSON |
--quiet, -q |
flag | false |
Only print session IDs |
Example:
$ sfs list --since 7d --sort tokens
Sessions (5)┌──────────────┬─────────────┬────────┬──────────┬───────────┐│ ID │ Tool │ Model │ Messages │ Title │├──────────────┼─────────────┼────────┼──────────┼───────────┤│ a1b2c3d4e5f6 │ claude-code │ opus-4 │ 23 │ Debug ... │└──────────────┴─────────────┴────────┴──────────┴───────────┘sfs show
Section titled “sfs show”Show session details.
sfs show SESSION_ID [OPTIONS]| Argument | Required | Description |
|---|---|---|
SESSION_ID |
yes | Session ID or prefix (min 4 chars) |
| Option | Type | Default | Description |
|---|---|---|---|
--messages, -m |
flag | false |
Show conversation messages |
--cost, -c |
flag | false |
Show cost estimate |
--page-size |
int | 20 |
Messages per page (with --messages) |
Example:
$ sfs show a1b2 --cost
╭──────────── Session Details ────────────╮│ Session ID: a1b2c3d4-e5f6-... ││ Title: Debug auth flow ││ Tool: claude-code 1.0.23 ││ Model: claude-opus-4 (anthropic) ││ Messages: 23 ││ Input tokens: 34,200 ││ Output tokens: 12,800 │╰─────────────────────────────────────────╯╭──────────── Cost Estimate ──────────────╮│ Input cost: $0.5130 ││ Output cost: $0.9600 ││ Total: $1.4730 │╰─────────────────────────────────────────╯sfs resume
Section titled “sfs resume”Resume a captured session in any supported AI tool.
sfs resume SESSION_ID [OPTIONS]| Argument | Required | Description |
|---|---|---|
SESSION_ID |
yes | Session ID or prefix |
| Option | Type | Default | Description |
|---|---|---|---|
--project |
path | — | Target project path (overrides workspace) |
--in |
string | claude-code |
Target tool: claude-code, codex, copilot, or gemini |
--model, -m |
string | — | Model to use in target tool (e.g. gpt-4.1, claude-sonnet-4, gemini-2.5-pro) |
--no-rules-sync |
flag | false |
Skip preflight of the target tool’s project rules file. Per-invocation only. |
--force-rules |
flag | false |
Overwrite an unmanaged target-tool rules file with SessionFS-managed content. One-time permission — the file becomes SessionFS-managed afterward and subsequent resumes refresh it normally. |
Converts the session to the target tool’s native format and injects it into that tool’s session storage. Cursor, Cline, Roo Code, Kilo Code, Antigravity, and Amp are capture-only — --in cursor (and the others) is rejected with an error. Use --in with one of the four supported resume targets instead.
Before launching the target tool, sfs resume preflights the tool’s project rules file from the current canonical SessionFS rules. Missing files are written; SessionFS-managed files are refreshed; unmanaged files are left alone with a warning on stderr unless --force-rules is passed. Preflight failures are non-fatal — resume still exits 0. See Resume-Time Rules Sync for the full policy.
--model support per tool:
- Claude Code: passed as
--modelto theclaudebinary - Codex: used in session injection and
codex resume --model - Gemini: passed as
--modelto thegeminibinary - Copilot: not supported (warns, uses Copilot’s default)
If omitted, each tool uses its own default model.
Examples:
$ sfs resume ses_abc123 --in codex
Source session used rules v3 (sessionfs).Current project rules are v5.Synced codex.md from SessionFS rules v5.Launching codex resume ...
Session resumed successfully. CC Session ID: abc123-def456 JSONL: /Users/me/.claude/projects/.../abc123-def456.jsonl Messages: 23Skip preflight for a one-off resume:
$ sfs resume ses_abc123 --in codex --no-rules-syncTake ownership of a hand-written codex.md:
$ sfs resume ses_abc123 --in codex --force-rulessfs checkpoint
Section titled “sfs checkpoint”Create a named checkpoint of a session’s current state.
sfs checkpoint SESSION_ID --name NAME| Argument | Required | Description |
|---|---|---|
SESSION_ID |
yes | Session ID or prefix |
| Option | Type | Default | Description |
|---|---|---|---|
--name |
string | required | Checkpoint name |
Example:
$ sfs checkpoint a1b2 --name "before-refactor"
Checkpoint 'before-refactor' created for session a1b2c3d4e5f6.sfs fork
Section titled “sfs fork”Fork a session into a new independent session.
sfs fork SESSION_ID --name NAME [OPTIONS]| Argument | Required | Description |
|---|---|---|
SESSION_ID |
yes | Session ID or prefix |
| Option | Type | Default | Description |
|---|---|---|---|
--name |
string | required | Title for the forked session |
--from-checkpoint |
string | — | Fork from a named checkpoint instead of current state |
Example:
$ sfs fork a1b2 --name "Try different approach"
Forked session created: f6e5d4c3b2a1 Title: Try different approach Parent: a1b2c3d4e5f6sfs export
Section titled “sfs export”Export a session to a file.
sfs export SESSION_ID [OPTIONS]| Argument | Required | Description |
|---|---|---|
SESSION_ID |
yes | Session ID or prefix |
| Option | Type | Default | Description |
|---|---|---|---|
--format |
string | sfs |
Export format: sfs, markdown, claude-code |
--output, -o |
path | . |
Output directory |
Example:
$ sfs export a1b2 --format markdown -o ~/exports
Exported to /Users/me/exports/a1b2c3d4-e5f6-....mdsfs import
Section titled “sfs import”Import sessions from external sources.
sfs import [FILE] [OPTIONS]| Argument | Required | Description |
|---|---|---|
FILE |
no | File to import (for file-based import) |
| Option | Type | Default | Description |
|---|---|---|---|
--from |
string | — | Import source: claude-code |
--format |
string | — | Input format (for file import) |
Example:
# Import all Claude Code sessions$ sfs import --from claude-code
Found 47 Claude Code session(s).Imported 47 new session(s).sfs daemon start
Section titled “sfs daemon start”Start the SessionFS daemon in the background.
sfs daemon start [OPTIONS]| Option | Type | Default | Description |
|---|---|---|---|
--config |
path | — | Path to config.toml |
--log-level |
string | INFO |
Log level: DEBUG, INFO, WARNING, ERROR |
Example:
$ sfs daemon start
Daemon started (PID 12345).Logs: /Users/me/.sessionfs/daemon.logsfs daemon stop
Section titled “sfs daemon stop”Stop the running daemon.
sfs daemon stopExample:
$ sfs daemon stop
Sent SIGTERM to daemon (PID 12345).sfs daemon status
Section titled “sfs daemon status”Show daemon status and watcher health.
sfs daemon statusExample:
$ sfs daemon status
SessionFS Daemon Status┌──────────────────┬────────────────────────┐│ Field │ Value │├──────────────────┼────────────────────────┤│ PID │ 12345 ││ Running │ Yes ││ Sessions │ 47 ││ Watcher: cc │ healthy (47 sessions) │└──────────────────┴────────────────────────┘If pushes for a session keep failing (server errors, rate limits, network), the daemon backs off instead of retrying every cycle: after 1 minute, 5 minutes, 15 minutes, then hourly. After a long failing streak (12 attempts over at least six hours) it pauses that session until the session changes, the daemon restarts, or you run sfs daemon retry-sync. sfs daemon status lists these sessions with their failure count and last error, and sfs doctor reports them under “Sync retries”.
sfs daemon retry-sync
Section titled “sfs daemon retry-sync”Retry sessions whose sync is backing off or paused after failed pushes, on the daemon’s next sync cycle.
sfs daemon retry-sync [SESSION_ID]| Argument / Option | Description |
|---|---|
SESSION_ID |
Retry just this session (a unique prefix of its ID also works). Omit to retry every session that is backing off or paused. |
--config PATH |
The config file the daemon was started with, if you started it with sfs daemon start --config. |
Example:
$ sfs daemon retry-sync ses_abc12345sfs daemon logs
Section titled “sfs daemon logs”Show daemon log output.
sfs daemon logs [OPTIONS]| Option | Type | Default | Description |
|---|---|---|---|
--lines, -n |
int | 50 |
Number of lines to show |
--follow, -f |
flag | false |
Follow log output (like tail -f) |
Example:
$ sfs daemon logs -n 10
2026-03-20 14:30:00 sfsd INFO sfsd starting with 1 watcher(s)2026-03-20 14:30:01 sfsd INFO sfsd running (PID 12345)sfs config show
Section titled “sfs config show”Show the current configuration.
sfs config showExample:
$ sfs config show
Config: /Users/me/.sessionfs/config.toml
log_level = "INFO"scan_interval_s = 5.0
[claude_code]enabled = truesfs config set
Section titled “sfs config set”Set a configuration value.
sfs config set KEY VALUE| Argument | Required | Description |
|---|---|---|
KEY |
yes | Config key (dotted path, e.g., claude_code.enabled) |
VALUE |
yes | Value to set |
Example:
$ sfs config set scan_interval_s 10
Set scan_interval_s = 10sfs config default-org
Section titled “sfs config default-org”Set or clear the server-canonical default organization used when capturing sessions and creating projects. Available starting v0.10.0.
sfs config default-org [ORG_ID | --clear]| Argument | Required | Description |
|---|---|---|
ORG_ID |
no | Org ID to use as default. Pass --clear to drop the preference. |
The value is persisted on the server (users.default_org_id) and returned in GET /auth/me. Membership is validated — non-members cannot set an org as default.
Example:
$ sfs config default-org acme_eng
Default organization set to acme_eng.sfs alias
Section titled “sfs alias”Set or clear a session alias for easy reference.
sfs alias SESSION_ID [ALIAS]| Argument | Required | Description |
|---|---|---|
SESSION_ID |
yes | Session ID or prefix |
ALIAS |
no | Alias name (omit to clear) |
Example:
$ sfs alias ses_a1b2 auth-debugAlias set: auth-debug -> ses_a1b2c3d4e5f6
$ sfs show auth-debug # Now works with aliassfs search
Section titled “sfs search”Full-text search across all local sessions.
sfs search QUERY [OPTIONS]| Argument | Required | Description |
|---|---|---|
QUERY |
yes | Search text |
| Option | Type | Default | Description |
|---|---|---|---|
--tool |
string | — | Filter by source tool |
--cloud |
flag | false |
Search cloud sessions instead of local |
--json |
flag | false |
Output as JSON |
Example:
$ sfs search "rate limiting middleware"
2 results: ses_a1b2 claude-code "...added rate limiting middleware to..." ses_c3d4 codex "...the rate limiter should handle..."sfs summary
Section titled “sfs summary”Show a session summary — files changed, tests run, commands executed.
sfs summary SESSION_ID [OPTIONS]| Argument | Required | Description |
|---|---|---|
SESSION_ID |
yes | Session ID or prefix |
| Option | Type | Default | Description |
|---|---|---|---|
--format |
string | — | Export format: md for markdown |
Example:
$ sfs summary ses_a1b2
Debug auth middleware2.3h | 327 msgs | 28 tool calls | Claude CodeBranch: feature/auth-fix @ a1b2c3d
Files modified (3): src/auth/middleware.py src/auth/tokens.py tests/test_auth.py
Commands: 34Tests: 6 runs (5 passed, 1 failed)Packages: pyjwt, redissfs audit
Section titled “sfs audit”Audit a session for hallucinations using LLM-as-a-Judge.
sfs audit SESSION_ID [OPTIONS]| Argument | Required | Description |
|---|---|---|
SESSION_ID |
yes | Session ID or prefix |
| Option | Type | Default | Description |
|---|---|---|---|
--model |
string | claude-sonnet-4 |
Judge LLM model |
--api-key |
string | — | LLM API key (or use config/env) |
--provider |
string | auto-detect | Provider: anthropic, openai, google, openrouter |
--base-url |
string | — | Custom OpenAI-compatible endpoint (LiteLLM, vLLM, Ollama) |
--consensus |
flag | false |
Run 3 passes, report where 2+ agree (3x cost) |
--report |
flag | false |
Show existing report only |
--json |
flag | false |
Output as JSON |
--format |
string | — | Export: json, markdown, csv |
Example:
$ sfs audit ses_a1b2 --model gpt-4o --base-url https://litellm.internal/v1
Trust Score: 74%3 contradictions | 9 unverified | 42 verified
CRITICAL test_result msg #34 "Test passes" -> exit code 1HIGH file_existence msg #12 "Created validator.py" -> No Write callsfs delete
Section titled “sfs delete”Delete a session from the cloud, the local device, or both. Requires an explicit scope flag – there is no default.
sfs delete SESSION_ID [OPTIONS]| Argument | Required | Description |
|---|---|---|
SESSION_ID |
yes | Session ID or prefix |
| Option | Type | Default | Description |
|---|---|---|---|
--cloud |
flag | – | Delete from server, keep local copy |
--local |
flag | – | Remove local copy, keep cloud copy |
--everywhere |
flag | – | Delete from both server and local |
--force |
flag | false |
Skip confirmation prompt |
If no scope flag is provided, the command prints an error and exits.
Examples:
# Remove from cloud only (local copy stays)$ sfs delete ses_abc123 --cloudDelete ses_abc123 from cloud? Local copy will be kept. [y/N] yDeleted from cloud. Recoverable for 30 days.
# Remove from this device only$ sfs delete ses_abc123 --localDelete ses_abc123 from this device? Cloud copy is unaffected. [y/N] yRemoved local copy.
# Delete everywhere (recoverable for 30 days)$ sfs delete ses_abc123 --everywhere --forceDeleted from cloud and local device. Recoverable for 30 days.See Delete Lifecycle for full details on retention, recovery, and sync behavior.
sfs trash
Section titled “sfs trash”List soft-deleted sessions in the retention window.
sfs trashExample:
$ sfs trash
Trash (3 sessions -- purge after 30 days)
ID Deleted Scope Purge afterses_abc123 2 days ago cloud 2026-05-14ses_def456 5 days ago everywhere 2026-05-11ses_ghi789 12 days ago everywhere 2026-04-28sfs restore
Section titled “sfs restore”Undo a soft-delete. Clears the server-side deletion flag and removes the session from the local exclusion list.
sfs restore SESSION_ID| Argument | Required | Description |
|---|---|---|
SESSION_ID |
yes | Session ID or prefix |
If the local copy was also removed (scope was everywhere), run sfs pull <id> afterward to re-download it.
Example:
$ sfs restore ses_abc123Session restored. Run 'sfs pull ses_abc123' to re-download locally.sfs push
Section titled “sfs push”Push a session to the cloud.
sfs push SESSION_ID [--yes] [--timeout SECONDS]| Option | Description |
|---|---|
--yes, -y |
Skip interactive confirmations (DLP findings, cloud-undelete). Findings are still shown. |
--timeout SECONDS |
How long to wait for the server to accept the upload (1–3600). Defaults to SFS_UPLOAD_TIMEOUT, then upload_timeout under [sync] in config.toml, then 300. Raise it for very large sessions on servers that run DLP scans. |
If the server doesn’t answer in time, the push stops with a message saying so and how to raise the limit, instead of retrying the same upload.
sfs pull
Section titled “sfs pull”Pull a session from the cloud.
sfs pull SESSION_IDSince v0.24.0 the local copy is replaced to match the server: files the server version no longer has are removed, while local-only reports such as the audit report and checkpoints are kept.
sfs pull-handoff
Section titled “sfs pull-handoff”Pull a session from a handoff link.
sfs pull-handoff HANDOFF_IDExample:
$ sfs pull-handoff hnd_x7k9
Session pulled. 47 messages.Run: sfs resume ses_abc --in claude-codesfs list-remote
Section titled “sfs list-remote”List sessions stored on the cloud server.
sfs list-remote [OPTIONS]| Option | Type | Default | Description |
|---|---|---|---|
--page |
int | 1 |
Page number |
--page-size |
int | 20 |
Results per page |
sfs handoff
Section titled “sfs handoff”Hand off a session to a teammate with email notification.
sfs handoff SESSION_ID --to EMAIL [OPTIONS]| Option | Type | Default | Description |
|---|---|---|---|
--to |
string | required | Recipient email |
--message |
string | — | Message to include in the email |
sfs sync
Section titled “sfs sync”Bidirectional sync and autosync management.
sfs sync (default)
Section titled “sfs sync (default)”Run bidirectional sync — push local changes, pull remote-only sessions.
sfs syncsfs sync auto
Section titled “sfs sync auto”Set autosync mode.
sfs sync auto --mode MODE| Mode | Behavior |
|---|---|
off |
No autosync (default). Manual sfs push only. |
all |
Every new or updated session auto-pushes to cloud. |
selective |
Only sessions in the watchlist auto-push. |
sfs sync watch
Section titled “sfs sync watch”Add sessions to the autosync watchlist (selective mode).
sfs sync watch SESSION_ID [SESSION_ID...]sfs sync unwatch
Section titled “sfs sync unwatch”Remove sessions from the autosync watchlist.
sfs sync unwatch SESSION_ID [SESSION_ID...]sfs sync watchlist
Section titled “sfs sync watchlist”Show all sessions in the autosync watchlist.
sfs sync watchlistsfs sync status
Section titled “sfs sync status”Show current autosync mode, counts, and storage usage.
sfs sync statussfs project
Section titled “sfs project”Manage shared project context — a single document shared across the team via MCP.
sfs project init
Section titled “sfs project init”Create a project context for the current repo (matched by git remote).
sfs project init [--org ORG_ID | --personal]| Option | Type | Default | Description |
|---|---|---|---|
--org |
string | — | Create the project scoped to the given organization (caller must be a member) |
--personal |
flag | default | Create the project under the caller’s personal scope |
When --org is supplied, the project inherits the org’s knowledge base creation defaults at create time. If neither flag is supplied, the project is personal-scope (pre-v0.10.0 behavior).
sfs project show
Section titled “sfs project show”Display the current project context with metadata.
sfs project showsfs project edit
Section titled “sfs project edit”Open the context document in $EDITOR. Changes upload on save.
sfs project editsfs project set-context
Section titled “sfs project set-context”Set project context from a file.
sfs project set-context FILEsfs project get-context
Section titled “sfs project get-context”Output raw project context markdown to stdout.
sfs project get-contextsfs project compile
Section titled “sfs project compile”Compile pending knowledge entries into the project context document.
sfs project compileExample:
$ sfs project compile
Compiling pending entries...Project context updated. 12 entries compiled.sfs project rebuild
Section titled “sfs project rebuild”Force a full re-compile of the project context. Resets compiled_at=NULL on all active claims and clears context_document, so the next compile pass pulls every active claim from scratch. Useful on settled projects where normal compile would be a no-op.
sfs project rebuildExample:
$ sfs project rebuild
Project context reset. Run `sfs project compile` to regenerate.sfs project entries
Section titled “sfs project entries”List knowledge entries for this project.
sfs project entries [OPTIONS]| Option | Type | Default | Description |
|---|---|---|---|
--pending |
flag | false |
Show only pending (uncompiled) entries |
--type |
string | — | Filter by type: decision, pattern, discovery, convention, bug, dependency |
--limit |
int | 20 |
Max entries to show |
Example:
$ sfs project entries --type decision --limit 5
┌────┬──────────┬────────────────────────────────────────┬──────────┬──────────────────┬──────────┐│ ID │ Type │ Content │ Age │ Session │ Status │├────┼──────────┼────────────────────────────────────────┼──────────┼──────────────────┼──────────┤│ 42 │ decision │ HTTP + ETags only, no WebSockets │ 3d ago │ ses_a1b2c3d4e5.. │ compiled ││ 38 │ decision │ Sessions are append-only │ 5d ago │ ses_f6e5d4c3b2.. │ pending │└────┴──────────┴────────────────────────────────────────┴──────────┴──────────────────┴──────────┘Showing 2 of 2 entriessfs project ask
Section titled “sfs project ask”Ask a question about the project using the knowledge base.
sfs project ask QUESTION| Argument | Required | Description |
|---|---|---|
QUESTION |
yes | Question about the project |
Searches knowledge entries and project context for relevant answers. Optionally saves the Q&A back to the knowledge base.
Example:
$ sfs project ask "How does session conflict resolution work?"
╭─ Question: How does session conflict resolution work? ─╮╰────────────────────────────────────────────────────────╯
Matching Knowledge Entries (2): [decision] Sessions are append-only — conflict resolution appends both sides Session: ses_a1b2 | 2026-03-15 | confidence: 95% [pattern] Merge strategy: append both sides rather than 3-way merge Session: ses_c3d4 | 2026-03-10 | confidence: 90%
Related Sessions: sfs show ses_a1b2 sfs show ses_c3d4
Save this Q&A to the knowledge base? [y/N]:sfs project pages
Section titled “sfs project pages”List wiki pages for this project.
sfs project pagesExample:
$ sfs project pages
┌──────────────────┬──────────────────────────┬──────────┬───────┬─────────┬──────┐│ Slug │ Title │ Type │ Words │ Entries │ Auto │├──────────────────┼──────────────────────────┼──────────┼───────┼─────────┼──────┤│ session-format │ Session Format (.sfs) │ concept │ 420 │ 8 │ yes ││ conflict-resolve │ Conflict Resolution │ concept │ 310 │ 5 │ yes ││ daemon-arch │ Daemon Architecture │ manual │ 850 │ 0 │ no │└──────────────────┴──────────────────────────┴──────────┴───────┴─────────┴──────┘3 pagessfs project page
Section titled “sfs project page”View a wiki page by slug.
sfs project page SLUG| Argument | Required | Description |
|---|---|---|
SLUG |
yes | Page slug |
Example:
$ sfs project page session-format
╭──────────── Session Format (.sfs) ────────────╮│ A .sfs session is a directory containing: ││ manifest.json, messages.jsonl, workspace.json, ││ tools.json. All file paths within are relative ││ to workspace root. ││ ... │╰──────────── session-format (auto-generated) ──╯
Backlinks: entry:42 (references) entry:38 (defines)sfs project health
Section titled “sfs project health”Run health checks on the project knowledge base.
sfs project healthReports entry counts, compilation status, staleness, and a health score.
Example:
$ sfs project health
Project Health: sessionfs
✓ Context document exists (2400 words, 8 sections) ✓ 45 knowledge entries (38 compiled, 2 dismissed) ⚠ 5 entries pending compilation ✓ Last compiled: 2026-03-28 ✓ Context appears up to date
Health Score: 90%sfs project regenerate
Section titled “sfs project regenerate”Regenerate an auto-generated concept article from the latest knowledge entries.
sfs project regenerate SLUG| Argument | Required | Description |
|---|---|---|
SLUG |
yes | Page slug to regenerate |
Example:
$ sfs project regenerate session-format
Regenerating page 'session-format'...Article regenerated (420 words from 8 entries).sfs project set
Section titled “sfs project set”Update project settings.
sfs project set [OPTIONS]| Option | Type | Description |
|---|---|---|
--name |
string | Rename the project (project-admin only). Available starting v0.12.1. |
--auto-narrative / --no-auto-narrative |
flag | Enable or disable auto-narrative generation on sync |
Example:
$ sfs project set --auto-narrative
auto_narrative = True$ sfs project set --name "Acme Platform"
name = Acme Platformsfs project dismiss
Section titled “sfs project dismiss”Dismiss an irrelevant knowledge entry so it is excluded from future compilations.
sfs project dismiss ENTRY_ID| Argument | Required | Description |
|---|---|---|
ENTRY_ID |
yes | Numeric entry ID |
Example:
$ sfs project dismiss 38
Entry 38 dismissed.sfs project transfer
Section titled “sfs project transfer”Initiate, accept, reject, or cancel a project transfer between scopes (personal ↔ org, or org ↔ org). Available starting v0.10.0.
sfs project transfer (--to TARGET | --accept ID | --reject ID | --cancel ID) [--force]| Option | Type | Description |
|---|---|---|
--to |
string | Initiate a transfer to the given target. Use personal for personal scope, or an org ID for an org you belong to. |
--accept |
string | Accept an incoming pending transfer by ID. |
--reject |
string | Reject an incoming pending transfer by ID. |
--cancel |
string | Cancel an outgoing pending transfer you initiated. |
--force |
flag | With --to (auto-accepted) or --accept: transfer even if open tickets rely on org personas the destination lacks. |
The transfer is auto-accepted when the initiator and target are the same user/org (e.g. moving a personal project into your own org). Standing is re-validated on accept/reject, so a member demoted between initiate and accept loses the right to act on the transfer.
Org personas and transfers (GH #70): moving a project into a different org or out of one is refused (409 personas_stranded) when open tickets are assigned to org personas that will not exist in the destination; the error lists each persona and its ticket ids. Project personas move with the project, so a same-named project persona avoids the refusal. Nothing is copied automatically: reassign the tickets, create the personas in the destination, or pass --force (on --to when the transfer auto-accepts, or on --accept).
Example:
$ sfs project transfer --to acme_engTransfer initiated. Awaiting target acceptance: xfer_a1b2c3sfs project transfers
Section titled “sfs project transfers”List project transfers involving the caller.
sfs project transfers [--direction incoming|outgoing] [--state pending|accepted|rejected|cancelled|expired]| Option | Type | Default | Description |
|---|---|---|---|
--direction |
string | both | Filter by incoming or outgoing transfers |
--state |
string | all | Filter by transfer state |
A transfer proposed by an org admin (v0.23.0) appears in the project owner’s incoming list labelled Proposed by <admin> for <org>: <reason> with its expiry, and in the proposer’s outgoing list the same way. Accept or decline it with sfs project transfer --accept / --reject.
sfs project compile-schedule
Section titled “sfs project compile-schedule”Set the scheduled knowledge-base compile for the current project (v0.23.0). sfs project show displays the current schedule.
sfs project compile-schedule nightlysfs project compile-schedule weekly --after-claims 20sfs project compile-schedule offsfs project compile-schedule weekly --no-after-claims| Argument / option | Type | Description |
|---|---|---|
schedule |
off | nightly | weekly |
How often the scheduled compile rebuilds the context document |
--after-claims |
int | Also compile once this many claims are waiting, whatever the schedule (1+) |
--no-after-claims |
flag | Clear the waiting-claims threshold so the project compiles only on schedule |
nightly makes the project eligible every 24 hours, weekly every 7 days. off turns off the time-based schedule, but an --after-claims threshold still applies. Scheduled compiles use the deterministic compiler, never an LLM. On self-hosted servers the schedule takes effect only when something calls the compile sweep (see Self-Hosted).
sfs project group (Team+)
Section titled “sfs project group (Team+)”Group an org’s projects and grant people access to the whole group (v0.26.0). Every command addresses a group by its slug and takes --org (default: your default org); most take --json. sfs project list --group SLUG lists only that group’s projects. See Project Groups.
| Command | Description |
|---|---|
sfs project group list |
The org’s groups |
sfs project group create NAME [--slug S] [--description D] |
Create a group (org admin or owner) |
sfs project group show GROUP |
A group’s members and projects |
sfs project group set GROUP [--name N] [--slug S] [--description D] [--compile|--no-compile] |
Rename or describe a group, or turn its overview compile on or off (group admin) |
sfs project group delete GROUP |
Delete a group (org admin or owner) |
sfs project group add GROUP PROJECT_ID... |
Add projects (group admin who can edit each project) |
sfs project group remove GROUP PROJECT_ID |
Remove a project (group admin) |
sfs project group members GROUP |
Members and their roles |
sfs project group grant GROUP USER --role reader|editor|admin |
Grant or change a member’s role; USER is an org member’s email or user id (group admin) |
sfs project group grant GROUP --file FILE [--role R] |
Grant up to 100 members at once; one email or user id per line, optionally email,role (--role is the default). All or nothing |
sfs project group revoke GROUP USER |
Revoke a member’s grant (group admin) |
sfs project group access |
Every group you have access to, across your orgs |
sfs project group search GROUP [QUERY] [--entry-type T] [--limit N] |
Search knowledge claims across the group’s projects you can read (QUERY 3–200 characters; omit it to list top claims) |
sfs project group context GROUP |
The group’s compiled overview |
sfs project group compile GROUP |
Compile the overview (group editor or admin; the group must have compile turned on) |
sfs project confluence publish (Enterprise)
Section titled “sfs project confluence publish (Enterprise)”Publish a wiki page, or with --context the project context document, to the Confluence space mapped to this project (v0.26.0). See Confluence Cloud.
sfs project confluence publish architecture --previewsfs project confluence publish --context --yes| Argument / option | Description |
|---|---|
slug |
Wiki page slug to publish |
--context |
Publish the project context document instead of a wiki page |
--preview |
Show the draft, with its citations and anything dropped, without publishing |
--yes, -y |
Skip the confirmation prompt |
sfs rules
Section titled “sfs rules”Manage canonical project rules and compile them into the tool-specific files each AI agent reads (CLAUDE.md, codex.md, .cursorrules, .github/copilot-instructions.md, GEMINI.md). See Rules Portability for the full reference.
sfs rules init
Section titled “sfs rules init”Seed canonical rules for the current project. Detects the git remote, preselects enabled tools from existing rule files + recent tool usage, and optionally imports a single unmanaged rule file as the canonical seed.
sfs rules init [--local-only]| Option | Type | Default | Description |
|---|---|---|---|
--local-only |
flag | false |
Gitignore the compiled rule files instead of committing them |
Only the five v0.9.9-supported tools are preselected: claude-code, codex, cursor, copilot, gemini. The picker shows the reason for each preselection (file present, recent usage, or manual pick).
Example:
$ sfs rules init
Detected rule files: CLAUDE.md (reason: file present) .cursorrules (reason: file present)
Recent tool usage (last 90 days): codex (reason: recent usage)
Enable these tools? [Y/n]Seeded canonical rules for myorg/my-project.Run 'sfs rules edit' to edit preferences, then 'sfs rules compile'.sfs rules edit
Section titled “sfs rules edit”Open the canonical static_rules document in $EDITOR.
sfs rules editsfs rules show
Section titled “sfs rules show”Show current canonical version, enabled tools, knowledge/context injection config, and whether compiled outputs are in sync.
sfs rules showExample:
$ sfs rules show
Project: myorg/my-projectCanonical version: 4Enabled tools: claude-code, codex, cursor, gemini
Knowledge injection: on Types: convention, decision Budget: 2000 tokens
Context injection: on Sections: overview, architecture Budget: 2000 tokens
Compiled outputs: in sync (last compile: 2026-04-12)sfs rules compile
Section titled “sfs rules compile”Compile canonical rules into tool-specific files. Deterministic — no new version is created unless a compiled output changes by hash.
sfs rules compile [--tool TOOL] [--dry-run] [--force]| Option | Type | Default | Description |
|---|---|---|---|
--tool |
string | — | Compile for a single tool only |
--dry-run |
flag | false |
Show what would be written without touching disk |
--force |
flag | false |
Overwrite files not managed by SessionFS |
Example:
$ sfs rules compile
Compiling canonical rules v4... CLAUDE.md written (sha256:9a1c…) codex.md written (sha256:4e2f…) .cursorrules written (sha256:b7d1…) .github/copilot-instructions.md written (sha256:c3a8…) GEMINI.md written (sha256:5f90…)
New rules version: 5SessionFS refuses to overwrite a rule file that is not managed (no SessionFS marker and not created by sfs rules init). Use sfs rules init to import it, or pass --force.
sfs rules push
Section titled “sfs rules push”Push the canonical record and latest compiled version to the SessionFS API. Uses optimistic concurrency — a stale write returns 409 Conflict.
sfs rules pushsfs rules pull
Section titled “sfs rules pull”Pull canonical rules from the SessionFS API. Run sfs rules compile afterwards to regenerate tool files.
sfs rules pullsfs rules emit
Section titled “sfs rules emit”Print the latest compiled rules for a tool to stdout. Reads from the local rule cache populated by sfs rules compile and sfs rules pull — never hits the network.
sfs rules emit --tool TOOL [--format hook|file]| Option | Type | Default | Description |
|---|---|---|---|
--tool |
string | required | Target tool (claude-code, codex, cursor, copilot, gemini) |
--format |
string | hook |
hook for Claude Code’s hook JSON spec, file for the plain compiled body |
--format hook is the format the SessionStart hook installed by sfs hooks install consumes. --format file is useful for piping the compiled body into another tool or inspecting it from the shell. If the local cache is empty, the command prints an empty payload and exits 0 — it never breaks Claude Code startup.
Example:
$ sfs rules emit --tool claude-code --format hook{ "hookSpecificOutput": { "hookEventName": "SessionStart", "additionalContext": "..." }}sfs hooks
Section titled “sfs hooks”Manage SessionFS hooks for tools with native hook support. v0.10.1 supports Claude Code only. See Hook-based injection for the full reference.
sfs hooks install
Section titled “sfs hooks install”Wire the SessionFS SessionStart hook into the target tool’s settings. The hook calls sfs rules emit on every session start and pipes the compiled rules into the system prompt. Idempotent — running twice does not duplicate the entry.
sfs hooks install --for TOOL [--user|--project] [--force]| Option | Type | Default | Description |
|---|---|---|---|
--for |
string | required | Target tool (claude-code only in v0.10.1) |
--user |
flag | default | Install at user scope (~/.claude/settings.json) |
--project |
flag | false |
Install at project scope (.claude/settings.json in repo root) |
--force |
flag | false |
Skip the conflict warning when a managed CLAUDE.md already exists |
Example:
$ sfs hooks install --for claude-codeHook installed: ~/.claude/settings.json (SessionStart)SessionFS will inject project rules at every Claude Code startup.sfs hooks uninstall
Section titled “sfs hooks uninstall”Remove the SessionFS-managed hook entry from the target tool’s settings. Idempotent — no-op if not installed.
sfs hooks uninstall --for TOOL [--user|--project] [--force]| Option | Type | Default | Description |
|---|---|---|---|
--for |
string | required | Target tool (claude-code only in v0.10.1) |
--user |
flag | default | Uninstall from user scope |
--project |
flag | false |
Uninstall from project scope |
--force |
flag | false |
Skip the confirmation prompt |
sfs hooks status
Section titled “sfs hooks status”Show which SessionFS hooks are installed across supported tools and scopes. Tools without native hook support appear as N/A.
sfs hooks statusExample:
$ sfs hooks status
SessionFS Hooks───────────────claude-code (user): INSTALLED at ~/.claude/settings.json (SessionStart)claude-code (project): not installedcodex: N/A (no native hook system)gemini: N/Acursor: N/Asfs storage
Section titled “sfs storage”Manage local session storage.
sfs storage (default)
Section titled “sfs storage (default)”Show local disk usage, session counts, and retention policy.
sfs storagesfs storage prune
Section titled “sfs storage prune”Prune old sessions to free disk space.
sfs storage prune [OPTIONS]| Option | Type | Default | Description |
|---|---|---|---|
--dry-run |
flag | false |
Show what would be pruned without deleting |
--force |
flag | false |
Skip confirmation prompt |
sfs daemon restart
Section titled “sfs daemon restart”Restart the daemon (stop + start).
sfs daemon restartsfs watcher
Section titled “sfs watcher”Manage tool watchers.
sfs watcher list
Section titled “sfs watcher list”List all tool watchers and their status.
sfs watcher listsfs watcher enable
Section titled “sfs watcher enable”Enable a tool watcher.
sfs watcher enable TOOLsfs watcher disable
Section titled “sfs watcher disable”Disable a tool watcher.
sfs watcher disable TOOLsfs auth
Section titled “sfs auth”Manage cloud authentication.
sfs auth login
Section titled “sfs auth login”Authenticate with the cloud server.
sfs auth login [OPTIONS]| Option | Type | Default | Description |
|---|---|---|---|
--url |
string | https://api.sessionfs.dev |
Server URL |
--key |
string | — | API key |
sfs auth signup
Section titled “sfs auth signup”Create a new account.
sfs auth signup [OPTIONS]| Option | Type | Default | Description |
|---|---|---|---|
--url |
string | https://api.sessionfs.dev |
Server URL |
sfs auth status
Section titled “sfs auth status”Show current authentication status.
sfs auth statussfs mcp serve
Section titled “sfs mcp serve”Start the MCP server on stdio transport.
sfs mcp serveTools exposed: 130, covering sessions (including ask_session_helper), knowledge, rules, personas, tickets (including watch_ticket and get_ticket_updates), agent runs (including replay_agent_run, report_agent_run_usage and get_spend_summary), review-loop rollups (get_loop_report), merge readiness (check_merge_readiness), review loops (start_review_loop, get_loop_status and update_review_loop), workflow templates (list_workflow_templates, get_workflow_template, start_workflow and get_workflow_plan), the review checklist (get_loop_checklist and propose_checklist_item), agent feedback, handoffs, work queues, the skills marketplace, project groups, meetings and chat threads (upload_chat_thread), reminders, approvals (read only) and For You (get_my_attention). See MCP Server for the full catalogue.
sfs mcp install
Section titled “sfs mcp install”Auto-configure SessionFS as an MCP server for an AI tool. Also injects knowledge-contribution instructions into the tool’s project config file.
sfs mcp install --for TOOL [OPTIONS]| Option | Type | Description |
|---|---|---|
--for |
string | Target tool: claude-code, codex, gemini, cursor, copilot, amp, cline, roo-code, kilo-code, antigravity |
--skip-instructions |
flag | Skip injecting knowledge-contribution instructions into project config |
Example:
$ sfs mcp install --for claude-code
Added SessionFS MCP server in Claude Code. Config: /Users/me/.claude.json Restart Claude Code to activate.
Appended knowledge instructions to CLAUDE.md
Your AI agent can now search past sessions: "Has anyone on the team seen this error before?" "What was the fix for the auth middleware bug?"sfs mcp uninstall
Section titled “sfs mcp uninstall”Remove SessionFS MCP server registration and knowledge instructions from an AI tool.
sfs mcp uninstall --for TOOL| Option | Type | Description |
|---|---|---|
--for |
string | Target tool: claude-code, codex, gemini, cursor, copilot, amp, cline, roo-code, kilo-code, antigravity |
Example:
$ sfs mcp uninstall --for cursor
Removed SessionFS MCP server from Cursor. Restart Cursor to apply.Removed knowledge instructions from .cursorrulessfs mcp index
Section titled “sfs mcp index”Rebuild the full-text search index from all local sessions.
sfs mcp indexExample:
$ sfs mcp index
Search index rebuilt: 47 sessions indexed.sfs init
Section titled “sfs init”Interactive setup wizard for SessionFS. Detects installed AI coding tools, writes configuration, optionally sets up cloud sync, and starts the daemon.
sfs initDetects: Claude Code, Cursor, Codex, Gemini CLI, Copilot, Amp, Cline, Roo Code, Kilo Code, Antigravity.
Example:
$ sfs init
SessionFS Setup
Scanning for AI coding tools... ✓ Claude Code detected (~/.claude) ✓ Cursor detected (~/Library/Application Support/Cursor) ✓ Gemini CLI detected (~/.gemini) ✗ Codex not found
Found 3 tools. Track all? [Y/n]: y
Cloud sync lets you access sessions from any machine and share with teammates.
Set up cloud sync now? [y/N]: n
Start the SessionFS daemon now? [Y/n]: y
✓ Daemon started! Watching 3 tools. Sessions stored in: /Users/me/.sessionfs/sessions
Next steps: sfs list — View captured sessions sfs show <id> — Inspect a session sfs resume <id> — Resume in any tool sfs search "query" — Search past sessionssfs doctor
Section titled “sfs doctor”Run 9 health checks with auto-repair. Checks store directory, session count, index integrity, index freshness, daemon status, API reachability, authentication, config permissions, and capture health (detects when an AI tool’s format change has silently broken capture — an idle tool is never flagged). Automatically repairs corrupted indexes.
sfs doctorExample:
$ sfs doctor
SessionFS Health Check┌─────────────────────┬────────┬──────────────────────────┐│ Check │ Status │ Detail │├─────────────────────┼────────┼──────────────────────────┤│ Store directory │ ✓ │ /Users/me/.sessionfs ││ Sessions directory │ ✓ │ 47 session(s) on disk ││ Session index │ ✓ │ 47 indexed ││ Index freshness │ ✓ │ in sync ││ Daemon │ ✓ │ running (PID 12345) ││ API server │ ✓ │ reachable (https://...) ││ Authentication │ ✓ │ me@example.com (team) ││ Config permissions │ ✓ │ permissions OK (0o600) ││ Capture health │ ✓ │ all watched tools healthy │└─────────────────────┴────────┴──────────────────────────┘sfs dlp scan
Section titled “sfs dlp scan”Scan local sessions for secrets and PHI. SessionFS ships with 20 secret patterns (API keys, access tokens, private keys, database URLs) and 14 PHI patterns (SSN, phone, credit card, medical IDs).
sfs dlp scan [SESSION_ID ...] [--mode MODE] [--format FORMAT]| Option | Description |
|---|---|
--mode warn|redact|block |
Action on findings (default: warn) |
--format json|text |
Output format (default: text) |
--verbose |
Show matched substrings |
$ sfs dlp scan ses_abc1232 findings in ses_abc123: [HIGH] AWS access key in messages.jsonl:142 [MEDIUM] Email address in messages.jsonl:89sfs dlp policy
Section titled “sfs dlp policy”View or update the organization DLP policy. Applies server-side to all org members on sync.
sfs dlp policy [--get|--set-mode MODE|--enable|--disable]| Option | Description |
|---|---|
--get |
Show current policy |
--set-mode warn|redact|block |
Update the policy mode |
--enable |
Enable DLP scanning |
--disable |
Disable DLP scanning |
When set to block, uploads containing detected secrets/PHI are rejected. When set to redact, findings are automatically redacted before storage.
sfs security scan
Section titled “sfs security scan”Run local security checks: config file permissions, API key exposure in shell configs, dependency vulnerabilities (via pip-audit), and stale sessions.
sfs security scanExample:
$ sfs security scan
Security Scan Results────────────────────────────────────────✓ Config permissions: OK (0o600)✓ API key exposure: No keys found in shell configs✓ Dependencies: No vulnerabilities found✓ Stale sessions: No stale sessions
All checks passed.sfs security fix
Section titled “sfs security fix”Auto-fix security issues where safe to do so. Fixes config permissions, upgrades vulnerable packages (with confirmation), and warns about issues requiring manual action.
sfs security fix [OPTIONS]| Option | Type | Default | Description |
|---|---|---|---|
--yes, -y |
flag | false |
Skip confirmation prompts |
Example:
$ sfs security fix
Security Fix────────────────────────────────────────✓ Fixed config permissions: 0o644 -> 0o600
Vulnerable packages with available fixes: - cryptography>=44.0.0
Upgrade these packages? [y/N]: y✓ Upgraded 1 packages
Fixed 2 issue(s).sfs admin reindex
Section titled “sfs admin reindex”Re-extract metadata for all cloud sessions (admin only).
sfs admin reindexsfs admin registries poll
Section titled “sfs admin registries poll”Poll organization Git marketplace registries now (platform admin, or a skills_registry:poll service key in SESSIONFS_API_KEY). The API polls up to --limit due registries and publishes each new matching tag through the normal org publish checks; each registry is leased while it is polled, so concurrent runs never poll one twice. Use it from a self-hosted cron, or enable the Helm CronJob instead. Exits 2 when a registry failed. See Polling Git Registries.
sfs admin registries poll [--limit N] [--registry ID ...] [--until-idle] [--max-runs N]| Option | Default | Description |
|---|---|---|
--limit |
5 | Registries polled per request (1-20) |
--registry |
— | Poll this registry id now regardless of its schedule (repeatable) |
--until-idle |
off | Keep requesting batches while a full batch was polled |
--max-runs |
20 | Stop after this many requests |
sfs admin audit-log
Section titled “sfs admin audit-log”Show the platform admin audit log, newest first (platform admin only): action, target, admin, reason, and before/after state when captured. Entries with source operator_record were recorded by an operator and not verified by the server. See Auditing Operator Overrides.
sfs admin audit-log [--target-type TYPE] [--target-id ID] [--action NAME] [--source api|operator_record] [--admin-id USER_ID] [--limit N] [--page N] [--json]| Option | Default | Description |
|---|---|---|
--target-type / --target-id |
— | Only entries for this target |
--admin-id |
— | Only entries performed or recorded by this admin |
--action |
— | Only entries with this action |
--source |
— | api or operator_record |
--limit |
50 | Entries per page (1-200) |
--json |
off | Print the raw JSON, including the full before/after state |
sfs admin service-keys
Section titled “sfs admin service-keys”Org-scoped service keys for CI runners, agents and scheduled jobs (org owner or admin, Team or above). See API keys.
sfs admin service-keys list --org ORG_IDsfs admin service-keys create --org ORG_ID --name NAME --scope SCOPE [--scope SCOPE]... [--expires-days N] [--project PID]... [--output-key]sfs admin service-keys rotate KEY_ID --org ORG_ID [--output-key]sfs admin service-keys revoke KEY_ID --org ORG_ID --reason "..."sfs admin service-keys scopesThe raw key is printed once on create and rotate; --output-key prints only the key, for capturing in scripts. Platform scopes such as platform_sweeps:run (used by scheduled sweeps) can only be minted by a platform admin, and the key works only while the admin who minted or last rotated it and the user it runs as are both still platform admins. Since v0.28.0, create and rotate print a warning about this to stderr, scopes marks those scopes as tier-coupled, and list has a Coupling column that reads ok, or inactive: … with the reason once the key has stopped working. A request with such a key gets a 403 that names the cause and the fix.
sfs admin override
Section titled “sfs admin override”Audited operator overrides (platform admin only).
sfs admin override project-transfer PROJECT_ID --to-org ORG_ID --reason "..." [--new-owner USER_ID] [--expect-from ORG_ID|personal] [--force] [--yes]sfs admin override project-transfer --propose --project PROJECT_ID --org ORG_ID --reason "..."sfs admin override record --action NAME --target-type TYPE --target-id ID --reason "..." [--before-file F] [--after-file F]sfs admin override user-merge SOURCE_USER_ID TARGET_USER_ID --reason "..." [--apply] [--yes] [--json]sfs admin override project-merge SOURCE_PROJECT_ID TARGET_PROJECT_ID --reason "..." [--persona-policy rename|skip|merge_content] [--apply] [--yes] [--json]project-transfer moves a project into an organization without the owner’s consent. It keeps the normal transfer checks (merged projects and stranded org personas are refused unless --force), cancels any pending transfer, and commits the move together with an audit entry holding the reason and before/after state. The owner must be a member of the destination organization; otherwise pass --new-owner with an active member, who becomes the owner. --expect-from refuses the move unless the project is still in the given org (or personal), so a retried command cannot move it twice. With --propose (v0.23.0) nothing is forced: the command asks the owner of a personal project to move it into an org, and the project moves only when the owner accepts (POST /api/v1/orgs/{org_id}/projects/{project_id}/propose-transfer). The caller must be an owner or admin of the destination org, and the project owner must be an active member of it. One pending transfer per project (409 transfer_pending); the same project and org can’t be proposed again for 7 days after a decline or 24 hours after a cancel (409 proposal_cooldown); an org can hold at most 10 pending proposals (409 proposal_limit); proposals expire after 7 days. Use --project and --org in this mode. record logs an action performed outside the API, such as raw SQL; it is stored with source operator_record. Reasons are 1-500 characters; state files must hold a JSON object of at most 64 KiB.
sfs admin override user-merge
Section titled “sfs admin override user-merge”Fold a duplicate account (for example a signup with a typo in the email) into the account to keep. Calls POST /api/v1/admin/users/{source_id}/merge-into/{target_id}. Dry run by default: it writes nothing and prints, per table, how many rows would be reassigned, deduplicated, revoked or cancelled (--json includes the row ids). --apply performs the merge in one transaction, deactivates the source user, revokes its API keys and writes exactly one user_merge audit entry with the reason and the state before and after. Prompts for confirmation when applying unless --yes.
- Reassigned to the target: sessions, projects, share links, bookmarks, handoffs, knowledge entries, context compilations, tickets (creator, resolver, comments, edits), wiki revisions, personas (creator and represented member), work queues, rules, GitHub installation and the source’s plan records. Source storage usage is added to the target’s. A session alias the target already uses is cleared, and the sync watchlist keeps one row per session.
- Deduplicated: org memberships (the higher role wins, the target on ties), and team memberships, devices, GitLab settings and judge settings (the target’s row wins).
- Revoked, never moved: API keys (including service keys), trusted-reviewer bindings, SSO break-glass grants and SSO identities, and pending ownership or project transfers involving the source.
- Left alone: audit and history tables, so past actions keep the original actor.
The merge refuses, changing nothing, when source and target are the same (400); either user does not exist (404); the target is inactive (409 target_inactive); the source is a platform admin (409 source_is_platform_admin); the source has billing attached (409 source_has_billing); both users hold an active plan (409 entitlement_conflict — it never guesses which plan to keep); the source owns skill marketplace packages, publishers, listings or registries (409 marketplace_assets_owned); both have a GitHub installation (409 github_installation_conflict); or the source owns org projects in an org neither user belongs to (409 project_owner_not_member).
| Option | Default | Description |
|---|---|---|
--reason, -r |
required | Why the merge is needed (1-500 characters), stored in the audit log |
--apply |
off | Perform the merge. Without it the command is a dry run |
--yes, -y |
off | Skip the confirmation prompt when applying |
--json |
off | Print the raw JSON response, including the row ids |
sfs admin override project-merge
Section titled “sfs admin override project-merge”Merge a duplicate project into the one to keep, whoever owns them. Use it when the owners can’t run sfs project merge themselves, for example when the two projects belong to different users. Calls POST /api/v1/admin/projects/{target_id}/merge-from/{source_id}. It runs the same merge as sfs project merge: sessions, knowledge entries, wiki pages, tickets, personas, agent runs, handoffs and repos move to the target, and the source becomes a redirect to it. Dry run by default: prints the counts that would move. --apply merges in one transaction and writes one project_merge audit entry with the reason and the state before and after. Prompts for confirmation when applying unless --yes.
Both projects must be in the same org, or both personal (400 cross_scope otherwise: move one with sfs admin override project-transfer first). Owners don’t have to match: merging one user’s personal project into another user’s gives the target’s owner everything in the source, so check the dry run. It also refuses a project that is already merged or has a pending transfer.
| Option | Default | Description |
|---|---|---|
--reason, -r |
required | Why the merge is needed (1-500 characters), stored in the audit log |
--persona-policy |
rename |
What to do when both projects have a persona with the same name: rename, skip or merge_content |
--apply |
off | Perform the merge. Without it the command is a dry run |
--yes, -y |
off | Skip the confirmation prompt when applying |
--json |
off | Print the raw JSON response |
sfs admin trusted-reviewers
Section titled “sfs admin trusted-reviewers”Register, list, or revoke an organization’s trusted reviewers (org-admin only). A trusted reviewer is authorized to post review verdicts that the autonomous work queue’s stop oracle will trust — typically a dedicated automated reviewer key. Tightly gated and fully audited. Available starting v0.12.1.
sfs admin trusted-reviewers (list | add | revoke) [OPTIONS]sfs agent
Section titled “sfs agent”Run, complete, replay and measure agent runs against tickets. The run lifecycle (run, complete, status, list, replay, compare) and CI workflow are covered in CI integration; structured outcome records live under sfs agent feedback. This section documents usage reporting and the spend rollup.
Recording usage on a run
Section titled “Recording usage on a run”sfs agent run also takes --model, --provider, --role (implementer, ui-implementer, reviewer, design-reviewer, security-reviewer or release) and --branch, so runs can be sliced by model and role. sfs agent complete takes the run’s usage and outcome:
| Option | Type | Description |
|---|---|---|
--input-tokens / --output-tokens |
integer | Token usage (added to anything already reported) |
--cache-read-tokens / --cache-write-tokens |
integer | Cache token usage (additive) |
--cost-usd |
number | Cost in USD (additive) |
--cost-basis |
string | reported (the cost the tool or provider reported), estimated (your own estimate), plan (covered by a subscription, no per-token cost) or unknown |
--head-sha |
string | Head commit the run finished on (7–64 hex chars) |
--exit-reason |
string | finished, out_of_turns or crashed |
sfs agent usage
Section titled “sfs agent usage”Add token and cost usage to a queued or running run, for long runs and continuations that report more than once. Values are added to the run’s totals. Once the run is complete, the totals are fixed and further reports are refused.
sfs agent usage RUN_ID [--input-tokens N] [--output-tokens N] [--cache-read-tokens N] [--cache-write-tokens N] [--cost-usd X]At least one value is required.
sfs agent spend
Section titled “sfs agent spend”Summarize agent-run spend for a ticket or the current project. Dollar amounts only appear when the caller has admin standing on the project (org owners/admins, or the owner of a personal project); token totals are always shown. Service keys never see dollar figures.
sfs agent spend --ticket IDsfs agent spend --project [--group-by GROUP] [--from ISO] [--to ISO] [--format text|json]| Option | Type | Description |
|---|---|---|
--ticket |
string | Ticket id to summarize (totals, per-persona, per-model, review rounds) |
--project |
flag | Summarize the current project (defaults to the last 30 days) |
--group-by |
string | persona | model | ticket | role | day (project view only) |
--from |
string | Start of the created_at window (ISO datetime) |
--to |
string | End of the created_at window (ISO datetime) |
--format |
string | text (default) or json |
Only runs with a reported or estimated cost basis add dollars; plan and unknown runs (including runs that reported tokens but no cost) add tokens only, shown separately as tokens on plans.
sfs loop
Section titled “sfs loop”Start, watch and budget a worker review loop, run its workers and record its review rounds, read its reports, keep its checklist, check merge readiness and share a ticket’s story. Tier: Team+ (the checklist and sfs loop ready are on every plan). From v0.29.2.
| Command | Description |
|---|---|
sfs loop start <ticket-id-or-title> --reviewer-persona NAME [--ticket 'title::description' ...] [--criteria TEXT ...] [--token-budget N] [--cost-budget-usd N] [--max-review-rounds N] |
Start a loop on an existing issue, or create one from a title. Files one child task per --ticket and creates the reviewer’s queue. --cost-budget-usd needs org owner or admin standing; there is no default round cap |
sfs loop status [LOOP_ID] |
One loop’s children (status, branch, head, rounds, spend), or every loop when the id is omitted |
sfs loop update LOOP_ID [--token-budget N] [--cost-budget-usd N] [--max-review-rounds N] |
Raise a limit |
sfs loop close-item LOOP_ID TICKET_ID |
Close an item the loop handed back as needing a person. Users only; service keys are refused |
sfs loop run start TICKET_ID [--model M] [--provider P] [--branch B] [--step STEP_ID] [--output-id] |
Take the ticket’s lease and open a worker run; prints the run id and what is left of the budget (v0.29.3) |
sfs loop run finish RUN_ID --head-sha SHA [--exit-reason finished|out_of_turns|crashed] [--branch B] [--input-tokens N] [--output-tokens N] [--cache-read-tokens N] [--cache-write-tokens N] [--cost-usd N] [--cost-basis BASIS] [--summary TEXT] [--step STEP_ID] |
Record the commit, how the worker exited and its tokens. Repeating it never counts usage twice (v0.29.3) |
sfs loop review LOOP_ID --ticket TICKET_ID --round N --commit SHA --verdict VERIFIED-CLEAN|CHANGES-REQUESTED [--findings-file FILE] [--stage code|design] [--model M] [--provider P] [--input-tokens N] [--output-tokens N] [--cost-usd N] [--step STEP_ID] |
Record a review round for an exact commit. The findings file is a JSON list of {severity, class, harm, title, file?, line?, status?}. Pass the loop id as --ticket for a design round (v0.29.3) |
sfs loop report TICKET_ID |
Per-round findings by harm, known versus new classes and round cost |
sfs loop insights [--from DATE] [--to DATE] |
Findings caught, cost per accepted change and checklist learning |
sfs loop checklist list [--status proposed|active|retired] |
Show the project checklist |
sfs loop checklist seed |
Offer the generic starter items as proposals |
sfs loop checklist add TITLE [--check TEXT] [--slug SLUG] |
Propose an item |
sfs loop checklist accept SLUG / retire SLUG |
Activate or retire an item |
sfs loop ready TICKET_ID --sha HEAD_COMMIT |
Merge readiness (below) |
sfs loop share story TICKET_ID [--expires-days N] |
Mint a public, revocable link to a ticket’s story. The raw token is printed once and is never stored. Team+ to create; list and revoke keep working after a downgrade |
sfs loop share ship-report VERSION [--expires-days N] |
Mint a public, revocable link to a ship report |
sfs loop share list |
List the project’s share links (tokens are never shown) |
sfs loop share revoke LINK_ID |
Revoke a share link |
In a workflow loop, --step names the template step the report is for. The server checks that the step exists, its dependencies are done and its role matches, and refuses a mismatch with 422.
Dollar figures are shown only to org owners and admins, or the owner of a personal project.
sfs loop ready
Section titled “sfs loop ready”Check whether a ticket’s work is safe to merge at a given head commit. Pure read: a person still does the merge.
sfs loop ready TICKET_ID --sha HEAD_COMMIT| Option | Type | Description |
|---|---|---|
--sha |
string | Full head commit id (40 or 64 lowercase hex characters) |
Prints READY only when a trusted strict VERIFIED-CLEAN verdict is bound to exactly that commit, the reviewer’s identity differs from every implementer identity recorded for the ticket, and no open finding is harmful. Otherwise it prints NOT READY with the reasons and exits 1, so it can gate a script. MCP: check_merge_readiness.
sfs workflow
Section titled “sfs workflow”Record-only workflow templates: store a multi-agent plan, start a loop from it, and read which steps are ready with their agents and briefs. SessionFS never starts an agent; your orchestrator does, and reports each step with --step. Tier: Team+ to start a workflow. Commands use the project of the current repository; --org works on the org’s templates.
| Command | Description |
|---|---|
sfs workflow list [--org ORG] [--json] |
Active templates: the project’s own plus its org’s |
sfs workflow show TEMPLATE_ID [--org ORG] [--json] |
One template version with its steps and brief templates |
sfs workflow create FILE [--name NAME] [--org ORG] |
Create a template from a YAML or JSON file, validated locally before anything is sent |
sfs workflow update TEMPLATE_ID FILE [--name NAME] [--org ORG] |
Save a new version; the old one is deactivated and running loops keep their pinned version |
sfs workflow disable TEMPLATE_ID [--org ORG] |
Deactivate a version |
sfs workflow start TEMPLATE_ID --ticket TK | --title TEXT [--description TEXT] [--reviewer-persona NAME] [--token-budget N] [--cost-budget-usd N] [--max-review-rounds N] [--output-id] |
Start a workflow loop. --output-id prints only the loop id |
sfs workflow plan LOOP_ID [--json] |
Each step’s state, gate and reason, then the ready tickets with their agents and briefs |
Project editors write project templates and org admins write org templates. See Workflow templates for the file format.
sfs release
Section titled “sfs release”Record releases, their gates and their deployments, and read the Ship Report. Release events also arrive on their own from the GitHub App and the delivery webhooks. Tier: Team+. From v0.29.3.
| Command | Description |
|---|---|
sfs release record VERSION --tag-sha SHA [--previous SHA] [--pr N ...] [--gate kind=status ...] [--source SOURCE] |
Record a release at a commit, link the pull requests it shipped and record its gates (for example --gate ci=passed). Source is github_release, gitlab_release, helm_sync or manual (default) |
sfs release deploy VERSION --env ENV [--source argocd|helm|manual] |
Record a deployment of a release to an environment |
sfs release list |
Releases with their gates and deployments |
sfs release ship-report [VERSION] [--month YYYY-MM] [--markdown] |
The Ship Report for a release or a month: loops, review rounds, findings, harmful findings and whether all were fixed before merge, cost per accepted change, checklist classes learned, gates, deploys and pull requests. --markdown prints a snippet for release notes. Dollar figures follow the same visibility rule as the rest of the loop |
sfs persona
Section titled “sfs persona”Manage portable AI personas per project. Each persona has an ASCII name (^[A-Za-z0-9_-]{1,50}$) and a markdown body. Tier: every plan (from v0.29.10; Pro+ before). Available starting v0.10.1.
Commands
Section titled “Commands”| Command | Description |
|---|---|
sfs persona list [--no-org | --org ORG_ID] |
List personas usable in the current project (project + org, with a Scope column), or one org’s personas |
sfs persona show <name> [--raw] [--org ORG_ID] |
Show a persona’s full content (--raw skips markdown render) |
sfs persona create <name> [--content TEXT | --file PATH] [--org ORG_ID] [--represents EMAIL] |
Create a persona inline, from a file, or via $EDITOR; --org creates an org-level persona, and --represents names the org member who may edit it |
sfs persona represent <name> --org ORG_ID (--user EMAIL | --clear) |
Set or clear the org member an org persona represents (org admins). That member can edit its role, content and specializations |
sfs persona edit <name> [--org ORG_ID] |
Open the persona content in $EDITOR |
sfs persona delete <name> [--force] [--org ORG_ID] |
Delete a persona; refuses 409 if non-terminal tickets reference it (use --force to override) |
sfs persona pull [<name> | --all] [--no-org] |
Write personas to .agents/*.md; --all includes the org’s personas unless --no-org |
sfs persona assume <name> |
Tag subsequent captured sessions with this persona (persona-only bundle) |
sfs persona forget |
Clear the active persona bundle (refuses while a ticket bundle is in effect) |
Org-level personas (--org): define a persona once for an organization and use it from every project in that org. Writes need the org admin or owner role; members can read. Inside a project, names resolve to the project’s own persona first, then the org’s — a project persona with the same name overrides the org one. Ticket assignment, sfs ticket start, agent runs, and the MCP tools all follow this rule.
sfs ticket
Section titled “sfs ticket”Manage tickets with a server-enforced FSM (suggested → open → in_progress → blocked → review → done | cancelled), dependency graph, comments, and an active-ticket provenance bundle that tags every captured session with persona_name + ticket_id. Tier: every plan (from v0.29.10; Team+ before). Available starting v0.10.1.
Commands
Section titled “Commands”| Command | Description |
|---|---|
sfs ticket list [--status STATE] |
List tickets, optionally filtered by FSM state |
sfs ticket show <id> |
Show ticket detail + dependencies + recent comments, with the creator, due date and estimate |
sfs ticket history <id> [--limit N] |
The ticket’s change history, newest first: each status change, assignment and field edit with its before and after values and who made it (default 50, up to 200; v0.28.0) |
sfs ticket create --title T --description D [--accept "..." --depends-on tkt_…] [--assigned-to PERSONA | --user EMAIL] [--due YYYY-MM-DD] [--estimate DURATION] |
Open a ticket (agent source requires ≥1 acceptance criterion + ≥20-char description). --user/-u assigns it directly to a teammate (email or user id), who gets a “Your turn” notification; it can’t be combined with --assigned-to (v0.27.0). --due sets a due date and --estimate an estimate in Jira duration syntax such as 2d 4h (v0.28.0). --assign-contact ec_… assigns it to an external contact of the project’s org instead (no notification: a contact can’t log in) |
sfs ticket update <id> [--title T] [--description D] [--priority P] [--user EMAIL] [--due YYYY-MM-DD|none] [--estimate DURATION|none] |
Change a ticket’s editable fields; --user/-u reassigns it directly to a teammate (v0.27.0). --due and --estimate set the due date and estimate; none clears them (v0.28.0). --assign-contact ec_…|none assigns or unassigns an external contact |
sfs ticket start <id> [--tool T] [--force] [--no-print-context] |
Atomic claim; writes the active-ticket bundle and prints compiled persona + ticket context with tool-aware token budget |
sfs ticket complete <id> |
Move from in_progress to review; clears owned bundle |
sfs ticket comment <id> "body" [--as PERSONA] |
Slack-like comment (non-idempotent) |
sfs ticket status |
Render the active-ticket bundle (Rich panel) |
sfs ticket follow <id> [--mute] / sfs ticket unfollow <id> |
Follow a ticket to be notified when it changes state, changes hands or gets a comment; --mute follows silently (v0.24.0) |
sfs ticket inbox [--all] [--mark-read] |
Your ticket notifications, unread by default (v0.24.0) |
sfs ticket updates [--persona NAME] [--no-ack] |
Agent-side poll of what changed on followed tickets; each persona keeps its own cursor, --no-ack peeks without advancing it (v0.24.0) |
sfs ticket block <id> --reason "..." / sfs ticket unblock <id> |
Toggle blocked state |
sfs ticket reopen <id> |
Move a terminal ticket back to open |
sfs ticket approve <id> / sfs ticket dismiss <id> |
Decide on suggested tickets |
sfs ticket assign <id> --persona NAME |
Attach a persona to a ticket |
sfs ticket resolve <id> |
Move from review to done (atomic with rowcount guard) |
sfs ticket escalate <id> --reason "..." |
Raise priority + append audit comment |
sfs ticket review-state <id> |
Open and closed review findings, the last verdict, severity counts, and Strict VERIFIED-CLEAN: yes/no for the last verdict |
sfs ticket jira preview <id> [--out FILE] |
Draft a Jira story from the ticket without sending anything (Enterprise, v0.23.0) |
sfs ticket jira publish <id> --from FILE [--yes] [--overwrite-existing] |
Create the Jira issue from a saved preview, or update its summary and description. A ticket linked to an existing issue it never published needs --overwrite-existing to replace that issue’s summary and description (v0.27.0) |
sfs ticket jira pull <id> [--yes] |
Replace the ticket’s title and description with the linked Jira issue’s; empty Jira fields leave the ticket unchanged (v0.27.0) |
sfs ticket jira status <id> |
Linked issue key, URL and current Jira status |
sfs ticket jira unlink <id> --confirm |
Remove the link (project admin); the Jira issue is left alone |
The active-ticket bundle is stored locally and read by all 10 daemon watchers (claude_code, codex, copilot, cursor, gemini, amp, cline, roo_code, kilo_code, antigravity). Captured sessions carry the bundle in their manifest.json and the server populates sessions.persona_name + sessions.ticket_id on upload.
Following is also automatic: creating a ticket, being assigned, commenting or posting a review verdict follows it for you. Notifications are written by the server and never copy comment bodies. Choose an email digest (off, your_turn by default, or all) under Settings → Preferences in the dashboard.
sfs contact
Section titled “sfs contact”An org’s external contacts: people the org works with who are not SessionFS users. Every command takes --org (default: your default org).
| Command | Description |
|---|---|
sfs contact list [--q TEXT] [--status active|archived|all] [--tag TAG] |
Contacts, newest first |
sfs contact show <id> [--refs] |
One contact, and with --refs where it appears (sources you can read) |
sfs contact create NAME [--email E] [--role R] [--tag T] [--alias A] |
Create a contact (any member) |
sfs contact edit <id> [...] / alias add|rm <id> ALIAS / archive <id> [--undo] |
Edit a contact |
sfs contact merge <target> <source> [--yes] / delete <id> / export <id> / export-all |
Owners and admins |
sfs contact suggestions [--apply NAME --contact ID] [--dismiss NAME] |
Names in your meetings and chats that nobody confirmed yet |
sfs skill / sfs plugin
Section titled “sfs skill / sfs plugin”Import, inspect, and install portable Agent Skills and Agent Plugins locally. SessionFS preserves standards payloads, pins Git sources, computes deterministic target plans, discloses omissions, and records package provenance on captured sessions. sfs plugin is an alias of sfs skill.
| Command | Description |
|---|---|
sfs skill inspect SOURCE [--pin REF] [--subdir PATH] [--for TOOL] [--json] |
Validate and inspect a local path, Git source, hosted package, or named local marketplace package without installing, and print its install disclosure (see Skills Marketplace) |
sfs skill add SOURCE [--for TOOL] [--scope project|user] |
Plan and transactionally install across one or more tools |
sfs skill list / sfs skill show ID |
Inspect installed state, provenance, hashes, targets, and omissions |
sfs skill plan ID / sfs skill compile ID [--for TOOL] [--drop TOOL] [--yes] [--allow-hidden-unicode] |
Compute a side-effect-free plan or re-apply the pinned package. --for is additive (installed targets are always kept); only --drop TOOL removes a tool, after listing the managed files to be unlinked and confirming (--yes in non-interactive mode) |
sfs skill sync --locked [--approve-widening] [--allow-hidden-unicode] |
Reproduce exact project lockfile state without upgrading. Every installed version the lockfile replaces is classified like an update before anything changes; one refused transition refuses the whole sync |
sfs skill remove ID / sfs skill update ID [--approve-widening] [--allow-hidden-unicode] |
Remove or update a package while preserving unmanaged (dirty) files; update previews old → new hash, commit, plan, the update diff and its class, then applies the re-consent rules below |
sfs skill diff ID [--to VERSION] [--json] |
Show what an update would change without applying it: files added/removed/changed with bounded text diffs, capability changes, new scanner and hidden-character findings, and the update class (text, code, widening) |
sfs skill rollback ID --to HASH [--approve-widening] [--allow-hidden-unicode] |
Re-apply a cached immutable version; --to is required and must be an exact sha256:<64 hex> (or bare 64-hex) digest. The transition is classified and consented like an update |
sfs skill doctor |
Detect drift, missing files, unsafe paths, and state mismatches; also shows the size of the removal trash |
sfs skill marketplace add URL --name NAME --pin SHA |
Register one pinned local marketplace source |
sfs skill marketplace list|refresh|remove |
Manage multiple user/project registry aliases explicitly |
sfs skill search QUERY [--tool TOOL] [--limit N] [--local-only] [--json] |
Search registered local marketplaces and the hosted SessionFS Marketplace. Each row is labelled local:<scope> or hosted and shows the reference to install it with. Signed out or offline, the hosted part is skipped with a note. --tool filters hosted results by tool compatibility; --marketplace ALIAS and --local-only search local registries only. Hosted filters: --category, --publisher, --verified, --attested, --license, --max-severity, --capability, --works-in, --updated-within, --hide-deprecated, --sort relevance|recent (see Skills Marketplace) |
sfs skill categories [--json] |
List the hosted marketplace’s categories |
sfs skill works-in ID [--json] |
The per-tool “works in” matrix for a hosted package (spk_...) or version (skv_...): verified (with tool version and date), format-valid, regressed or expected (see Skills Marketplace) |
sfs skill usage --org ORG_ID [--days N] [--json] |
Your organization’s members’ hosted-marketplace usage by package and tool (org owners/admins, Team plan) |
sfs skill add sessionfs:NAMESPACE/NAME[@VERSION] |
Install a package from the hosted SessionFS Marketplace (requires sfs auth login). sessionfs:spk_<id> also works and is required when a namespace/name pair is ambiguous. Without @VERSION the package’s current version is used; --pin VERSION is equivalent to @VERSION |
sfs skill pull [--for TOOL] [--device-id ID] [--yes] [--allow-* ...] [--approve-widening] [--allow-hidden-unicode] [--json] |
Apply your org’s skill assignments and your approved install requests to this device (see Skills Marketplace) |
sfs skill validate SOURCE [--visibility personal|org|public] [--json] |
Validate a package directory or .tar.gz exactly as the server would. Prints each problem with its file and line (when known), why it fails, and how to fix it, then exits 1. On success it prints the content hash, risk flags, sizes, and the checks that only the server can make |
sfs skill publish SOURCE [--org ORG_ID] [--visibility personal|org|public] [--namespace NS] [--collection NAME] [--yes] [--json] |
Validate locally, show a summary (name, version, license, risk flags, size, target), confirm, then upload. Prints the listing, package, and version IDs and the package URL |
sfs skill publish SOURCE --trusted-publishing --namespace NS [--package NAME] [--visibility public] [--audience AUD] [--ci-provider github|gitlab] [--id-token-env VAR] |
Publish from a GitHub Actions or GitLab CI job without an API key: reads the server’s OIDC audience, gets the job’s OIDC token (GitLab: from $SFS_ID_TOKEN, declared with id_tokens:), exchanges it for a single-use publish token, and uploads. See Trusted publishing and GitLab CI |
sfs skill publisher claim NAMESPACE [--org ORG_ID] [--display-name NAME] [--json] |
Claim a namespace: 3-39 lowercase letters, digits or single hyphens. Personal publishers need Starter or above; org publishers need an org owner/admin and the team skill library. Names that imitate a reserved brand or a verified publisher are refused with 409 namespace_confusable: lookalike letters from any script (the full Unicode UTS #39 confusables table, so Cyrillic, Greek or Cherokee spellings), leetspeak digits (0 1 2 3 4 5 6 7 8 9), rn/m, one or two typos, and added -official, -team, -ai and similar. A namespace another owner already publishes packages in is refused with 409 namespace_in_use (ask SessionFS to review the claim). An owner can hold 5 publishers and claim 10 namespaces in total (retired ones count). Namespaces are never released, even after deletion |
sfs skill publisher list [--json] |
Publishers you manage, personal and org |
sfs skill publisher show PUBLISHER_ID [--json] |
Publisher details; managers also see verifications and trusted publishers |
sfs skill publisher verify PUBLISHER_ID --dns DOMAIN |
Start DNS verification. Prints a sessionfs-verification=... TXT record to add at the domain. If your organization already verified the domain for SSO, it is reused (and re-checked) immediately |
sfs skill publisher verify PUBLISHER_ID --github-org INSTALLATION_ID / --github-user INSTALLATION_ID |
Verify a GitHub organization or account through one of your own SessionFS GitHub App installations. The installation must be linked to your account through the verified GitHub sign-in flow; an installation linked only by its id is refused with 409 installation_claim_unverified. The badge is bound to GitHub’s numeric account id, so a renamed or re-registered login does not inherit it |
sfs skill publisher check PUBLISHER_ID VERIFICATION_ID |
Re-check a verification now |
sfs skill publisher trust PUBLISHER_ID --repo OWNER/REPO --workflow FILE [--environment ENV] [--ref-pattern REF] [--package NAME] [--reusable-workflow OWNER/REPO/.github/workflows/FILE] [--allow-workflow-run] |
Allow a GitHub Actions workflow to publish for this publisher (see Skills Marketplace) |
| `sfs skill publisher trust PUBLISHER_ID –gitlab-project ID [–gitlab-host ORIGIN] [–gitlab-project-path GROUP/PROJECT] [–gitlab-namespace ID | –no-namespace-pin] [–environment ENV [–require-protected-environment]] [–ref-pattern REF] [–package NAME]` |
sfs skill publisher untrust PUBLISHER_ID TRUSTED_ID |
Remove a trusted publisher. Publish tokens already issued under it stop working |
sfs skill publisher stats PUBLISHER_ID [--days 7|30|90] [--json] |
Publisher analytics: installs by tool, version and day, active installs, uninstall rate, translation failures, works-in regressions, scan findings and open reports. Counts under 10 show as <10 |
sfs skill publisher package PUBLISHER_ID PACKAGE_ID [--category SLUG ...] [--deprecate|--undeprecate] [--message TEXT] [--successor PACKAGE_ID] [--readme-path PATH] |
Set a package’s categories (up to 3), deprecation with a same-publisher successor, and README path |
Risky capabilities require explicit flags bound to the exact package hash: --allow-scripts for any non-inert skill asset (the policy is an inert allowlist, so .rb, .bat, .exe, Makefile, and suffix-less files all count), --allow-hooks for SKILL.md frontmatter hooks: / allowed-tools: grants, and --allow-executable-extensions for a hooks.json or hooks/ directory shipped inside a skill. --yes alone is refused for these and the error names the hook or tool grant. Local MCP activation remains reserved: SessionFS does not silently enable it.
Every update, rollback and sync --locked transition is classified as text (consent carries forward after one confirmation), code (the changed capability’s flag again) or widening (always stops until --approve-widening or an org admin approves that exact version). sfs skill pull and the daemon apply text updates and list the rest as held: <name> needs approval. Blocked packages are moved into ~/.sessionfs/skills/quarantine/; yanked ones are flagged by sfs skill list and sfs skill doctor. See Skills Marketplace for install disclosure, verified publishers and trusted publishing.
sfs catalog
Section titled “sfs catalog”Native plugin catalogs: read-only git repositories of approved packages that each tool’s own plugin command can add. See Skills Marketplace.
| Command | Description |
|---|---|
sfs catalog list [--json] |
The catalogs you can add (public, personal, organization), with plugin counts and clone URLs |
sfs catalog add --for TOOL [--org ORG | --personal] [--run] [--no-credential-helper] |
Print the tool’s own command to add a catalog (claude-code, copilot, codex, cursor, gemini, antigravity); --run runs it where supported. Configures git to authenticate to the SessionFS host only through sfs catalog credential, so your key never appears in a URL |
sfs catalog doctor |
Check that git sends your SessionFS key only through the SessionFS credential helper (run it inside a repository to check that repository’s config too) |
sfs catalog export --to REMOTE [--org ORG | --personal] [--branch main] [--dry-run] [--ssh-key-file PATH] [--known-hosts PATH] |
Copy a catalog to a git repository you own (for example, for a Cursor team marketplace). The destination branch is overwritten with the generated catalog commit, and nothing is pushed when it is already current. With --ssh-key-file only that deploy key is used, over SSH with strict host-key checking, so it can run unattended |
sfs meeting
Section titled “sfs meeting”Store meeting transcripts for a project or a project group, extract action items and decisions, and promote action items to tickets. Transcripts are DLP-redacted by the server before storage, and every access rule is enforced server-side. See Meetings. Without --project or --group a command uses the project of the current repository.
| Command | Description |
|---|---|
sfs meeting upload <file> | --stdin --title T [--project proj_… | --group pg_…] [--date ISO] [--duration MIN] [--extract] |
Upload a .txt, .md, .vtt or .srt transcript (cue timing in VTT/SRT is stripped server-side). --extract also runs extraction right away |
sfs meeting list [--project | --group] [-q TEXT] [-n N] [--before ID] |
Meetings, newest first; a printed cursor pages onwards |
sfs meeting search <q> [--project | --group] |
Search titles and transcript text |
sfs meeting show <id> [--no-transcript] |
The numbered transcript, participants and their resolution, and the action items and decisions with line ranges |
sfs meeting delete <id> [--yes] |
Delete a meeting |
sfs meeting extract <id> |
Extract participants, action items and decisions with your own LLM key (your key, else your org’s; never a SessionFS key) |
sfs meeting participants <id> |
Participants and how each was resolved |
sfs meeting resolve-participant <id> <participant_id> --user USER_ID | --persona NAME | --contact ID |
Resolve a participant manually |
sfs meeting resolve-participant <id> --file FILE |
Resolve up to 100 participants at once; each line is participant_id,user:<id>, participant_id,persona:<name> or participant_id,contact:<id>. All or nothing: if any line is refused, nothing changes and the failed lines are listed |
sfs meeting action-items <id> |
Action items and decisions |
sfs meeting promote <id> <item_id> [--title T] [--description D] [--assignee PERSONA | --user USER_ID] [--due DATE] [--priority P] [--target-project ID] [--jira] [--yes] |
Show the ticket draft and ask before creating it; --yes skips the prompt. A group meeting needs --target-project |
sfs meeting link <id> <item_id> [TICKET_ID] [--yes] / unlink <id> <item_id> |
Tie a pending item to an existing ticket (the item’s suggestion when no ticket is given); shows the ticket and the comment it will add, then asks. unlink puts a linked item back to pending (v0.29.11) |
sfs meeting dismiss <id> <item_id> / restore <id> <item_id> |
Dismiss a pending item, or bring a dismissed one back |
sfs chat
Section titled “sfs chat”Store chat threads (a Slack export, a DiscordChatExporter export, or a plain paste from any tool, including Teams) for a project or a project group. A thread is stored one message per line, so extracted items cite message ranges such as M12-15. The server refuses direct-message exports, redacts the text with your DLP policy before storage and enforces every access rule. The commands after upload are the sfs meeting commands run against chat threads.
| Command | Description |
|---|---|
sfs chat upload <file> --channel "#infra" [--project proj_… | --group pg_…] [--provider slack|discord|paste|teams_paste] [--users users.json] [--attest] [--title T] [--extract] |
Upload a thread (2 MiB max, refused before anything is sent). Without --provider the format is detected: Slack JSON, DiscordChatExporter JSON, otherwise a paste. A paste needs --attest to confirm it is from a channel, not a direct message. --users (Slack only) sends the export’s users.json so ids show as names |
sfs chat list [--project | --group] [-q TEXT] [-n N] [--before ID] |
Chat threads, newest first |
sfs chat search <q> [--project | --group] |
Search titles and message text |
sfs chat show <id> [--no-messages] |
Numbered messages (M1, M2, …), participants, action items and decisions |
sfs chat delete <id> [--yes] |
Delete a chat thread |
sfs chat extract <id> |
Extract participants, action items and decisions with your own LLM key |
sfs chat participants <id> / resolve-participant <id> <participant_id> --user USER_ID | --persona NAME |
Participants, and resolving one manually (--file FILE resolves many, as for meetings) |
sfs chat action-items <id> |
Action items and decisions |
sfs chat promote <id> <item_id> [same options as sfs meeting promote] |
Show the ticket draft and ask before creating it |
sfs chat link <id> <item_id> [TICKET_ID] [--yes] / unlink <id> <item_id> |
Tie an item to an existing ticket (the item’s suggestion when no ticket is given; asks first), or put a linked item back to pending (v0.29.11) |
sfs chat dismiss <id> <item_id> / restore <id> <item_id> |
Dismiss or restore a pending item |
sfs attention
Section titled “sfs attention”What needs you right now: your For You list across reminders, approvals, the tickets assigned to you or to a persona you represent, Review Loop items, meeting and chat action items you own, knowledge changes in projects you work in and the weekly proof card. The server applies each source’s own access rules on every call. Every plan; each section appears only when its source is in your plan.
| Command | Description |
|---|---|
sfs attention [--band now|your_turn|upcoming|lately] [--limit N] [--json] |
Print the feed grouped by band (Now, Your turn, Coming up, Lately), each item with why it is there and its dashboard link. Counts are the full totals; --limit (1–100, default 100) caps the items. A source that couldn’t load is named at the end. --json prints the raw response |
sfs remind
Section titled “sfs remind”Personal reminders, optionally tied to a meeting, a chat thread or a ticket. A reminder is private to the person reminded and the person who set it. When it falls due it shows in the notification bell and Inbox, and in the email digest if your notification settings allow it. Titles and notes are DLP-redacted by the server before storage. Reminders are on every plan.
| Command | Description |
|---|---|
sfs remind add "title" --at "2026-11-06 09:00" [--tz Europe/London] [--meeting MEETING_ID[:LINES] | --chat CHAT_ID[:M<a>-<b>] | --ticket TK] [--for EMAIL] |
Create a reminder. --chat ties it to a chat thread and, optionally, a message range (chat_…:M3-5). --at takes YYYY-MM-DD HH:MM (or a bare date, meaning 09:00), read in --tz or this machine’s timezone; a value with an offset (…Z, …+01:00) is used as given. It must fall between 1 hour ago and 2 years ahead. --for reminds a teammate who can read the meeting or ticket |
sfs remind list [--all | --done] [--due-before TIME] [--limit N] |
Your reminders, earliest due first (open by default); due ones are marked |
sfs remind show <id> |
A reminder with its source and notes |
sfs remind note <id> "text" |
Add a note (notes are append-only) |
sfs remind snooze <id> 1h|tomorrow|next-week / --until TIME [--tz ZONE] |
Push it later. tomorrow and next-week mean 09:00 in the reminder’s timezone (next week = Monday) |
sfs remind done <id> / dismiss <id> |
Close it as done, or dismiss it |
sfs approval (Enterprise)
Section titled “sfs approval (Enterprise)”Approval policies hold merges and knowledge-base promotion until the right people approve. Only people decide; implementers and authors (including through a service key they minted) can’t approve their own work. Creating and editing policies needs the Enterprise plan; reading, disabling and deciding keep working after a downgrade.
| Command | Description |
|---|---|
sfs approval policy list [--org ORG] [--all] |
The org’s active policies (--all: every version, admins) |
sfs approval policy create --name N --target merge|kb_promote --require role:admin:1 [--require users:ID[,ID]:COUNT ...] [--filter JSON | --filter-file PATH] [--advisory] [--description D] [--org ORG] |
Create a policy (owners and admins) |
sfs approval policy update <policy_id> [--name] [--description] [--require ...] [--filter ...] [--blocking | --advisory] [--org ORG] |
Edit a policy. This creates a new version; open requests stay on the old one |
sfs approval policy disable <policy_id> [--org ORG] |
Deactivate a policy |
sfs approval list |
Pending requests you could decide now |
sfs approval show <request_id> |
A request with its policy, target, state and decisions |
sfs approval approve <request_id> --reason "…" / reject <request_id> --reason "…" |
Decide. One reject rejects the whole request |
sfs helper (Enterprise)
Section titled “sfs helper (Enterprise)”Ask the session helper a question over the sessions and project knowledge you can read (v0.23.0). Answers cite the sessions and messages they used. The model call uses your own key (Settings → Data protection → Security review model) or your org’s helper key. See Session Helper.
| Command | Description |
|---|---|
sfs helper ask "QUESTION" [--project ID | --group ID_OR_SLUG | --session ID ...] [--conversation ID] [--no-stream] [--json] |
Ask a question. Streams the answer to the terminal and lists citations at the end. --project, --group (a project group id pg_… or its slug; v0.28.0) or --session scope the question, one at a time; --conversation continues a thread; --no-stream fetches the whole answer in one request; --json prints the raw JSON |
sfs helper conversations list |
Your helper threads, newest first |
sfs helper conversations show <id> |
One thread with its messages and citations |
sfs helper conversations rename <id> "TITLE" |
Rename a thread (up to 200 characters, DLP-redacted like your questions) |
sfs helper conversations delete <id> [--yes] |
Permanently delete a thread |
sfs helper status |
Whether the helper is available to you, and which key, provider and model it would use |
sfs org
Section titled “sfs org”Organization membership. See Organizations.
| Command | Description |
|---|---|
sfs org list |
Every organization you belong to; * marks your default org |
sfs org info / sfs org members |
Your default organization, its seats and members |
sfs org invite EMAIL [--role member|admin] |
Invite someone (admin only). When the server sends no email (no email provider configured), the command prints the link to share |
sfs org invite --file FILE [--org ORG_ID] |
Invite up to 100 people at once; one email per line, optionally email,role. All or nothing: if any line is refused, nobody is invited and the failed lines are listed |
sfs org invites |
Pending invites addressed to your email |
sfs org accept INVITE_ID |
Accept one of them. You can accept while you belong to other orgs; accepting never changes your default org |
sfs org set-role USER admin|member / sfs org remove USER |
Change a member’s role, or remove a member (admin only) |
sfs org delivery-webhook
Section titled “sfs org delivery-webhook”Manage the org’s inbound GitHub and GitLab webhooks for pull requests, releases and deployments (org owners and admins, v0.29.3). Every org has them; they are not feature-gated. See Delivery webhooks.
| Command | Description |
|---|---|
sfs org delivery-webhook rotate --provider github|gitlab |
Generate or rotate the provider’s secret. The secret and the inbound URL are printed once; the secret is stored encrypted and only its last four characters are shown again |
sfs org delivery-webhook status --provider github|gitlab |
Whether a secret exists, its last four characters and the inbound URL |
sfs org jira (Enterprise)
Section titled “sfs org jira (Enterprise)”Connect the org’s Jira Cloud site (org admins, v0.23.0). The API token is encrypted at rest and never printed back. See Jira Cloud.
| Command | Description |
|---|---|
sfs org jira connect --site-url https://NAME.atlassian.net --email EMAIL --template agile|compliance|sre|bug [--api-token TOKEN] |
Check the credentials against Jira and save the connection; the token is prompted for (hidden) when omitted |
sfs org jira mappings |
Project to Jira project mappings (key, issue type, template override, done status) |
sfs org jira health |
Unmapped projects, failed updates, and links not checked in 7+ days |
sfs org jira templates list |
Built-in and org-custom story templates (v0.26.0) |
sfs org jira templates show SLUG [--versions] |
One template and its sections; --versions lists a custom template’s version history (v0.26.0) |
sfs org confluence (Enterprise)
Section titled “sfs org confluence (Enterprise)”Connect the org’s Confluence Cloud site and map projects to spaces (org admins, v0.26.0). See Confluence Cloud.
| Command | Description |
|---|---|
sfs org confluence status |
The connection, project mappings and publishing health |
sfs org confluence connect --site-url https://NAME.atlassian.net --email EMAIL --template reference|architecture|runbook|onboarding|concept [--api-token TOKEN] [--batch-window MIN] |
Save the connection; the token is prompted for (hidden) when omitted |
sfs org confluence map PROJECT_ID --space-key KEY --parent-page-id ID [--template T] [--publish-context] [--auto-publish-pages] |
Map a project to a space and parent page; --auto-publish-pages opts it into the scheduled publish sweep |
sfs org confluence unmap PROJECT_ID |
Remove a project’s mapping |
sfs policy (Enterprise)
Section titled “sfs policy (Enterprise)”The org skills policy and what it becomes in each tool’s managed settings. See Skills Marketplace for how the policy is enforced and delivered.
| Command | Description |
|---|---|
sfs policy show [--org ORG] [--tool T] [--json] |
The policies that apply to you, with what each tool enforces, what only SessionFS checks, and what nothing checks |
sfs policy compile --tool T [--org ORG] [--json] |
Print a tool’s compiled managed settings for IT to deploy (Claude Code, GitHub Copilot, VS Code, Gemini CLI, Codex; a checklist for Cursor) |
sfs policy status [--json] |
Per tool on this device: system when the deployed managed settings match the current revision, otherwise advisory |
sfs policy set --org ORG --file policy.json [--acknowledge-warnings] |
Owners and admins: preview the per-tool changes and side effects, then publish a new revision |
sfs policy disable --org ORG [--yes] |
Owners and admins, any tier: publish a revision that restricts nothing (after leaving Enterprise the last policy stays enforced and can only be relaxed or disabled) |