How it works
A team is one private git repository, and everything the team shares is a file in it. The CLI runs on your machine, reads and writes that repository, and talks to no server of ours.
A team is one git repository
Everything the team shares lives in one private repository, and nothing lives anywhere else.
| Thing | In the repository |
|---|---|
| A skill | A folder named for the skill, holding a SKILL.md and whatever you put beside it |
| A published version | An immutable folder, skills/<name>/v<N>/. Publishing appends one; nothing rewrites one. |
| Eval assets | skills/<name>/evals/, beside the versions, so editing a case does not mint a version |
| A person | people/<handle>.json: handle, name, email, GitHub login, installs, endorsements |
| A receipt | evals/<skill-uuid>/v<N>/<runId>.json: one eval run, written once, never edited |
| Team settings | team.json: name, categories, projects, archived handles, and the license publish stamps into each SKILL.md |
No server, no account
Membership is repository access. You are an active member when people/<handle>.json exists and your handle is not in team.json’s archived list. Both are required: a departure archives the handle rather than deleting the file.
There is no Terum server and no Terum account. The team’s data sits on your git host, and the rest happens here:
| Where | What happens there |
|---|---|
| Your machine | The CLI, the desktop app, every eval run, the team clone at ~/.terum/skills/teams/<team>, and your placed skills |
| Your git host | One git clone when you join, then fetches and pushes. Any git remote works: GitHub, GitLab, Bitbucket, bare SSH. |
| Anthropic, through your Claude Code login | Eval runs, the judge, generated eval assets and the publish category suggestion, through claude -p. The CLI never handles a token; the cost goes to whoever is logged in. |
GitHub’s API, through gh | Invitations, access-revoking team remove, and a few lookups. GitHub-only; on another host these refuse. |
| The terum-skills release repository | A release probe at most once a day, only when a team has a GitHub remote, and desktop app downloads. |
Privacy and network lists every request and how to avoid it.
The CLI and the app
The desktop app is a window onto the CLI, and every verb works from a terminal without it. The app runs the CLI as a child process with --frames, which speaks JSON, one object per line. Every question a verb would ask in a terminal becomes an ask frame that waits for the app’s answer.
So the app shows what the CLI returns. It has no HTTP client; its webview opens only https://github.com/* and https://discord.gg/* links. The protocol is in the frame protocol.
How a write reaches the team repo
Every write goes through one function that re-applies your change instead of rebasing it:
- Fetch, and hard-reset the clone to
origin/main. - Apply the verb’s change to that fresh tree.
- Run the write guard on the result.
- Stage exactly the paths the change touched, and check the staged diff matches them.
- Commit and push to
main. - If someone else pushed first, discard the commit and start over, with backoff, until a 30-second deadline.
One writer holds a per-clone lock for the whole loop, so two terminals on one machine queue instead of racing. Publish takes this same path: it pushes to main, and no branch or pull request is created.
The guard is the authorization model, and it is per verb. publish may add files to a version folder that does not exist yet, and may not touch one that does. unpublish is the only verb that may remove a version folder. Every other verb may write your own people file, and team.json only in the shape that verb needs. A write that touches one path it does not own is refused whole.
The same guard runs as a pre-push hook in your clone, so a hand-written git push is checked too. It catches accidents, not abuse: a bypass is possible, and is attributed to whoever pushed.
What sync does, and does not
npx -y terum-skills@latest syncsync runs git fetch and git reset --hard origin/main on each team clone, under that clone’s lock. Read verbs (ls, search, status) never fetch, so a teammate’s publish reaches you only when something does. The app runs sync in the background at launch and on window focus, at most once a minute.
sync does not place, copy, move or delete skill folders, push, edit a skill you are authoring, or repair a missing or broken clone. One exception: when a GitHub team’s repository answers “not found”, sync looks for where it went and, at a terminal, offers to move you there. Accepting runs team move, which does remove and re-place your placed skills.
The session hook
Setup offers a Claude Code session-start hook, defaulting to No. With it, every session start runs sync --hook, which fetches your team clones in the background, at most once an hour. It places nothing and edits none of your skill folders, but it does refresh Terum’s own files (the bundled skills, the edit-hook script, its settings entry) when they are outdated.
The hook runs the copy of the CLI that installed it, pinned to that release, never @latest. A newer release reaches it when you re-run setup. Details are in Claude Code integration.
Why it is built this way
- No server. A server would mean a Terum account, a Terum-held copy of your skills, and an operator to trust. A private repository already does distribution, history, access control and offline reads.
- No container. A skill is a folder Claude Code reads, with no runtime to isolate. Running Claude Code in a container breaks host authentication, host MCP servers, editor and browser extensions, and your global skills and hooks.
- Any git remote. Storage and sync work anywhere git works. Only membership administration needs a collaborator API, so
inviteand access-revokingteam removeare GitHub-only. - Git-host access is the permission model. Who may read and write the skills is who may read and write the repository.
- Evals run on your machine and budget. No CI job holds an API key, and a receipt records a run someone on the team paid for.
Full reference on GitHub
- How it worksdocs/concepts/how-it-works.md
- terum-skillsREADME.md
- Claude Code integrationdocs/guides/claude-code-integration.md
- Privacy and networkdocs/concepts/privacy-and-network.md