This guide installs gsd-pi 1.20.1, the Open GSD terminal agent, and hooks it up to a local model served by llama.cpp. Then it hands the agent a real task in a throwaway Git repository. It also covers what gsd-core is, the commands you look up on day one and the seven traps I hit along the way. Everything was tested on 30 September 2026 on arm64 Linux with Docker. Version 1.21.0 came out on 2 October; I checked its code and the 15 s headless timer is unchanged, as it is in 1.21.1, released on 7 October.

Key takeaways

  • gsd-pi is the terminal agent (the gsd command) and gsd-core is a pack of commands and skills that installs inside Claude Code, OpenCode, Codex or Cursor.
  • Install it with npx @opengsd/gsd-pi@latest; the unscoped gsd-pi package (version 3.0.0) is flagged as unsupported on npm and is the wrong one.
  • It works without an API key: with a models.json pointing at llama.cpp, a 4B Qwen3.5 finished a task with 12 passing tests and a commit.
  • Every request starts with about 29,400 tokens of instructions, so the model needs a 64k context window.
  • Headless gsd quick ends the session after 15 s without events; with a slow CPU model, use the interactive interface.

What gsd-pi and gsd-core are, and which one to install

Open GSD ships two packages that get mixed up because they share the "Git. Ship. Done." motto: one is a complete agent and the other is a set of instructions for the agent you already use.

Our article on what Open GSD is covers the whole catalogue as of 9 October 2026, including gsd-graph, gsd-loop and gsd-path.

Package What it is Version tested Where it runs
@opengsd/gsd-pi Terminal agent with memory in .gsd/, worktrees and an autonomous mode 1.20.1 Its own TUI (gsd) or headless
@opengsd/gsd-core /gsd-* commands, skills and hooks for the discuss, plan, execute, verify and ship loop 1.15.0 Inside Claude Code, OpenCode, Codex, Cursor and others
gsd-pi (unscoped) Previous build of the agent, flagged as unsupported on npm 3.0.0 Do not install it

The rule of thumb: if you already work in Claude Code or OpenCode and want the method, install gsd-core. If you want a standalone agent you can point at any provider, a local model included, install gsd-pi. The "Pi" in the name has a concrete origin: the package.json of its internal packages says the agent core and TUI are "vendored from earendil-works/pi", the Pi agent harness[1].

The project README defines it this way:

"GSD Pi is a local-first coding agent for planning, implementing, verifying, and tracking project work from the command line." (open-gsd/gsd-pi README)

What you need before installing gsd-pi

gsd-pi requires Node.js 22.18.0 or later, Git 2.20 or later and a model provider. I used a node:24-bookworm-slim container (Node 24.21.0, npm 11.19.0, Git 2.39.5) to keep my machine clean, because the installer writes to npm’s global directory and to ~/.gsd.

If you have no API key, the provider can be a local server with an OpenAI-compatible API. The provider docs cover Ollama, LM Studio, vLLM and SGLang; llama.cpp comes in through the same door. If you do not have it yet, follow the guide to install llama.cpp on Linux, macOS and Docker first.

How to install gsd pi step by step

The guided installer runs through npx and, with --yes, asks nothing. My user was not root, so I first pointed npm’s global prefix at my home folder:

export NPM_CONFIG_PREFIX="$HOME/.npm-global"
npx -y @opengsd/gsd-pi@1.20.1 --yes
export PATH="$HOME/.npm-global/bin:$PATH"
gsd --version

The installer put the package in the global directory and linked 14 workspace packages. Then it downloaded a Playwright Chromium for browser automation and tried to install RTK, a third-party tool that condenses shell output. On arm64 it printed RTK: binary validation failed, a harmless warning: the rest carried on and finished with Verified gsd v1.20.1.

The disk footprint surprises you the first time: 771 MB in npm’s global directory and 662 MB of Chromium in ~/.cache/ms-playwright. The package leaves four executables: gsd, gsd-cli, gsd-pi and gsd-mcp-server. On first launch it also downloads ripgrep to ~/.gsd/agent/bin/rg if the system has none.

How to connect gsd-pi to a local model with llama.cpp

gsd-pi reads local providers from ~/.gsd/agent/models.json and reloads the file every time you open /model. I started llama-server (build b11206) in Docker with the model’s chat template (--jinja), a 64k context and reasoning switched off:

services:
  llama:
    image: ghcr.io/ggml-org/llama.cpp:server-b11206
    volumes:
      - ./models:/models:ro
    command: >
      -m /models/Qwen_Qwen3.5-4B-Q4_K_M.gguf
      --alias qwen3.5-4b --host 0.0.0.0 --port 8080
      -c 65536 --jinja -t 6 --parallel 1 --reasoning off

The models.json declares the server as one more provider. The apiKey field is mandatory even though llama.cpp never checks it, and the two compat settings stop gsd-pi from sending the developer role and the reasoning_effort parameter, which local servers do not understand:

{
  "providers": {
    "llamacpp": {
      "baseUrl": "http://llama:8080/v1",
      "api": "openai-completions",
      "apiKey": "not-needed",
      "compat": {
        "supportsDeveloperRole": false,
        "supportsReasoningEffort": false
      },
      "models": [
        { "id": "qwen3.5-4b", "name": "Qwen3.5 4B (llama.cpp)",
          "contextWindow": 65536, "maxTokens": 8192 }
      ]
    }
  }
}

Check that gsd-pi sees it before you open a session. The id must match the alias the server publishes on /v1/models:

$ gsd --list-models llamacpp
provider  model       name                    context  max-out  thinking  images
llamacpp  qwen3.5-4b  Qwen3.5 4B (llama.cpp)  65.5K    8.2K     no        no

The window size is not a detail. The quick task’s first request took 29,425 tokens between instructions, tool definitions and my prompt, and the session ended up using 37k of the 66k available. A 32k-context model cannot even hold the opening request.

A real task end to end with gsd quick

To test it I created a repository with a slugify() function that only swapped spaces for hyphens, plus one test. The task: strip accents and collapse runs of spaces and punctuation into a single hyphen. Open gsd in the repository first, because that first launch creates .gsd/, then launch the task from inside the session:

cd demo
gsd --model llamacpp/qwen3.5-4b
# inside the session, on a single line:
/gsd quick Make slugify() in slug.py strip accents (Mundo Ñandú
  becomes mundo-nandu) and collapse runs of spaces and punctuation
  into one hyphen. Add tests to test_slug.py and run python3 -m unittest.

gsd-pi turned the prompt into quick task number 1, created .gsd/quick/1-make-slugify-in-slug-py-strip-accents-mu/ and gave the model fixed instructions: read the code, write tests, verify, make atomic commits with conventional messages and leave a 1-SUMMARY.md. Over 20 model requests the agent read the files and failed one edit, so it rewrote the whole file. Then it tried a regular expression with \p{}, which Python’s re module does not support, replaced it and left 12 tests passing.

These are the checks I ran myself afterwards, outside gsd-pi:

$ git log --oneline
ba7a16a feat: enhance slugify() to strip accents and collapse
        punctuation into hyphens
50e1729 initial
$ python3 -m unittest 2>&1 | tail -1
OK
$ python3 -c 'import slug; print(slug.slugify("Canción del año, 2026"))'
cancion-del-ano-2026

The commit touched two files, 116 lines added and 2 removed, straight on main: quick tasks open no worktree and no branch. Reviewing the diff is still your job. The docstring the model wrote documents "mundonandu" and "helloworld" as outputs, the opposite of what the code does, and "straße" comes out untransliterated. The tests pass because they test the code, not the comment.

Before settling on the 4B model I tried Nex-N2.5-mini, a 34.66-billion-parameter MoE that takes 22 GB in Q4_K_M. With other processes on the same 47 GB machine, the server started swapping and generation became unusable. For gsd-pi on CPU, pick a model that fits comfortably in free RAM.

The gsd commands and flags you will use most

gsd-pi has two surfaces: executable flags in the shell and /gsd commands inside the session. These are the ones I used or the docs recommend to start with:

Command What it does
gsd Opens the TUI in the current directory and creates .gsd/ the first time
gsd --model provider/model Pins the session model, for example llamacpp/qwen3.5-4b
gsd --list-models [filter] Lists the models gsd-pi can see and exits
/gsd quick [--full] task Small task with a commit and a summary; --full adds discussion, research and validation
/gsd auto Autonomous mode: plans, implements, verifies and advances milestone by milestone
/gsd status and /gsd doctor Project status and diagnostics with auto-fix
gsd headless query JSON snapshot of the state without calling the model
gsd headless quick Quick task without the TUI, with exit codes for CI
gsd upgrade Updates gsd-pi (alias gsd update)
gsd --web Web interface instead of the TUI

Headless exit codes are 0 (complete), 1 (error or timeout), 10 (blocked) and 11 (cancelled). With --output-format json the final result includes the branch, the commits and the artifacts it created.

How to install gsd-core in your coding agent

gsd-core is not an agent: it copies commands, subagents, skills and hooks into the config folder of the tool you already use. I installed it for OpenCode in local mode, inside an empty repository:

npx -y @opengsd/gsd-core@1.15.0 --opencode --local

The result was 899 files under .opencode/: 72 commands, 64 agents, 72 skills and 30 hooks, plus the gsd-core/bin engine. The installer warned that the 72 skills "shadow" the 72 commands of the same name, which is the expected behaviour. For Claude Code the equivalent is --claude --global, and you start with /gsd-new-project or /gsd-onboard. If you run OpenCode with a local model, the guide to OpenCode with llama.cpp and Ollama covers the other half.

Traps I hit installing and using gsd-pi

None of these traps breaks the install, but each one costs time if you do not know it:

  1. The wrong package. npm install -g gsd-pi pulls version 3.0.0, flagged as unsupported. The right one is @opengsd/gsd-pi and its numbering restarted at 1.0.0. If you have the old one, uninstall it and delete ~/.gsd/.update-check and ~/.gsd/agent/managed-resources.json.
  2. gsd is not found. npm’s global bin directory is not on your PATH. In oh-my-zsh, the gitfast plugin defines a gsd alias for git svn dcommit; check it with alias gsd.
  3. Headless mode needs .gsd/. In a fresh repository, gsd headless quick fails with No .gsd/ directory found in current directory. Open gsd once first.
  4. The 15 s headless timer. After the first tool call, gsd headless quick treats the session as finished if 15 s pass without events, even with --timeout 0. With Nex-N2.5-mini on CPU it ended with status: timeout, 3 tool calls and 0 commits. The IDLE_TIMEOUT_MS = 15_000 constant lives in dist/headless-events.js; auto mode does not apply it.
  5. State files are not ignored automatically in a quick task. After the task, git status still showed .gsd/ and .bg-shell/ as untracked. Add them to .gitignore or check the git add before each of your own commits.
  6. gsd-core touches the global config. Even with --local, the installer wrote ~/.gsd/defaults.json, the same directory gsd-pi uses. An rm -rf ~/.gsd to uninstall one takes the other’s config with it.
  7. Reasoning multiplies the output. Qwen3.5 thinks by default: to a plain "Say pong" it returned a whole reasoning_content block before "Pong". With --reasoning off in llama-server it answers directly.

Frequently asked questions

Does gsd-pi work without an API key?

Yes. Local providers (Ollama, LM Studio, vLLM, SGLang or any OpenAI-compatible server such as llama.cpp) only need an entry in ~/.gsd/agent/models.json with a dummy apiKey. What you cannot expect is Claude or GPT quality from a 4B model: it finished the task, but with mistakes you have to review.

What is the difference between gsd pi and gsd core?

gsd-pi is a complete agent with its own interface, project database and model selection. gsd-core is an instruction pack that installs inside another agent (Claude Code, OpenCode, Codex, Cursor and others) and adds /gsd-* commands. You can use both, but they share ~/.gsd.

What does Git Ship Done mean?

It is the Open GSD motto and the name shown in the gsd help banner ("GSD v1.20.1, Git Ship Done"). The original GSD was created by Lex Christopherson, known as TÂCHES, and his npm package get-shit-done-cc is still published; the Open GSD site credits that origin on its origin page.

Conclusion

gsd-pi installs with one command and works with a local model if you give it a 64k context and a well-formed models.json. For a first test, open gsd, run /gsd quick on a clean repository and review the diff the way you would review a new colleague’s. If you plan to automate it in CI with a slow model, keep the 15 s headless timer in mind. The background on what problem Open GSD solves is in what Open GSD is, and this guide is also available in Spanish.

Sources: [1] gsd-pi README on GitHub[2], [2] @opengsd/gsd-pi on npm[3], [3] gsd-core README[4], [4] Open GSD origin page[5], [5] Pi agent harness[1], [6] llama.cpp[6].

Sources

  1. Pi agent harness
  2. gsd-pi README on GitHub
  3. @opengsd/gsd-pi on npm
  4. gsd-core README
  5. Open GSD origin page
  6. llama.cpp