Overview
To use Ticket House with a project, you need two things:
- A project registered on your Ticket House server
- A
.ticket-house.jsonconfiguration file in your repository root
The configuration file tells the local Ticket House workstation where your remote server is and how to manage work items. This guide walks through setting up a new project from scratch.
Prerequisites
- Node.js 22+ installed on your machine
- Git — your project must be a Git repository with a remote
- A running Ticket House server with your project registered
Step 1: Register Your Project on the Server
Before configuring your local project, register it on your Ticket House server. Open the server's web UI and create a new project. You'll need to provide:
- Name — display name for the project
- Slug — a short identifier used in URLs (e.g.,
my-app) - Ticket prefix — a short prefix for ticket IDs (e.g.,
MAproduces tickets likeMA-1,MA-2) - Repository URL — the Git remote URL for the project
Once created, note the project URL. It will look like:
https://your-server.example.com/projects/my-app
Step 2: Create the Configuration File
In your repository root, create a .ticket-house.json file. The only required field is remote:
{
"remote": "https://your-server.example.com/projects/my-app"
}
The remote URL must point to your project on the Ticket House server. The CLI parses the project slug from the URL path.
Step 3: Update .gitignore
Add the following entries to your .gitignore to keep Ticket House runtime files out of version control:
.ticket-house/
.ticket-cache.json
The .ticket-house/ directory contains worktrees, audit logs, work items, and other runtime state managed by the workstation. The .ticket-cache.json file is a local cache of the active ticket's data.
Whether you commit .ticket-house.json itself is up to you. If all developers use the same server, committing it is convenient. If different developers use different servers, add it to .gitignore as well.
Step 4: Start the Workstation
Run the Ticket House CLI from your project root:
npx ticket-house
The CLI detects .ticket-house.json and starts in workstation mode:
- Creates a
.ticket-house/data directory for local state - Starts the HTTP server on port 3412
- Opens the remote server's dashboard with your workstation registered
You can now click "Work Locally" on any ticket in the web UI to start working on it. This creates a Git worktree in .ticket-house/worktrees/ with an isolated branch.
Optional Configuration
The minimal config above is all you need to get started. The sections below cover optional features you can enable as your project grows.
Container Pool
For projects that benefit from isolated container environments per work item, add a container block:
{
"remote": "https://your-server.example.com/projects/my-app",
"container": {
"image": "my-app-dev",
"containerfile": "Containerfile",
"seedCommand": "npm install",
"idlePool": 2,
"buffer": 1
}
}
| Field | Description |
|---|---|
image |
Name for the container image |
containerfile |
Path to the Containerfile or Dockerfile used to build the image |
seedCommand |
Command run after a container is provisioned (e.g., dependency install) |
idlePool |
Number of pre-warmed containers to keep ready |
buffer |
Build new containers when fresh count drops below this number |
You'll also need to create a Containerfile in your project root. This should install the toolchain your project needs and stay alive for agent use:
# Example for a Ruby/Jekyll project
FROM ruby:3.3-slim
RUN apt-get update && apt-get install -y git curl build-essential
RUN gem install bundler
WORKDIR /workspace
CMD ["sleep", "infinity"]
# Example for a Node.js project
FROM node:22-slim
RUN apt-get update && apt-get install -y git curl
WORKDIR /workspace
CMD ["sleep", "infinity"]
Worktree Hooks
Hooks let you run scripts when worktrees are created or removed. Common uses include installing dependencies, symlinking shared files, or running setup tasks.
{
"remote": "https://your-server.example.com/projects/my-app",
"hooks": {
"post-worktree-create": "scripts/hooks/post-worktree-create",
"pre-worktree-remove": "scripts/hooks/pre-worktree-remove"
}
}
| Hook | When | On Failure |
|---|---|---|
post-worktree-create |
After a worktree is created | Warning only (worktree is kept) |
pre-worktree-remove |
Before a worktree is removed | Non-zero exit aborts deletion |
Hook scripts receive three positional arguments: $1 (worktree path), $2 (ticket ID), $3 (branch name). The REPO_ROOT environment variable is also set.
Example: symlink a shared .env file into each new worktree:
#!/bin/bash
# scripts/hooks/post-worktree-create
WORKTREE_PATH="$1"
ln -sf "$REPO_ROOT/.env" "$WORKTREE_PATH/.env"
Make sure your hook scripts are executable: chmod +x scripts/hooks/*
Dev Watch
Dev Watch runs a single dev process (e.g., npm run dev) that watches symlinked source directories, letting you swap between work items without restarting the dev server.
{
"remote": "https://your-server.example.com/projects/my-app",
"devWatch": {
"links": {
"src": "src",
"tests": "tests"
},
"command": "npm run dev",
"autoStart": true
}
}
| Field | Description |
|---|---|
links |
Map of symlink name to worktree-relative path. These directories are symlinked into work/. |
command |
The dev process command to run |
autoStart |
Automatically start the dev process when a track is loaded (default: false) |
workDir |
Directory for symlinks, relative to repo root (default: "work") |
cwd |
Working directory for the command (default: ".") |
When using Dev Watch, update your build tool to read source files from the work/ directory instead of the repo root. Add work/ to your .gitignore.
Environments
Define environments to provide quick links to staging, production, or other deployed instances:
{
"remote": "https://your-server.example.com/projects/my-app",
"environments": [
{ "name": "staging", "url": "https://staging.example.com" },
{ "name": "production", "url": "https://prod.example.com" }
]
}
Reactions
Configure reaction types that can be added to tickets:
{
"remote": "https://your-server.example.com/projects/my-app",
"reactions": {
"types": [
{ "name": "seen", "emoji": "👀" },
{ "name": "upvote", "emoji": "👍" },
{ "name": "downvote", "emoji": "👎" }
],
"cooldownSeconds": 60
}
}
Worktrees
Control worktree storage limits, cleanup behavior, and shared file symlinking:
{
"remote": "https://your-server.example.com/projects/my-app",
"worktrees": {
"shared-files-symlink": [".env", ".env.local"],
"cleanupDelayMinutes": 120,
"warningLimitMB": 2000,
"maxLimitMB": 5000
}
}
| Field | Description | Default |
|---|---|---|
shared-files-symlink |
Array of file paths (relative to repo root) to symlink into each new worktree. Useful for .env files and other shared config. Files that don't exist are skipped. |
none |
cleanupDelayMinutes |
Minutes to wait before cleaning up merged or abandoned worktrees | 60 |
warningLimitMB |
Warn when total worktree storage exceeds this size (MB) | 2000 |
maxLimitMB |
Hard limit for total worktree storage (MB) | 5000 |
The shared-files-symlink option is a convenient alternative to writing a post-worktree-create hook just for symlinking environment files. Symlinks are created as relative paths so they work regardless of the absolute location of the repository.
Commands
Run scripts automatically as part of the workstation lifecycle:
{
"remote": "https://your-server.example.com/projects/my-app",
"commands": {
"autoStart": "scripts/workspace-start.sh"
}
}
| Field | Description |
|---|---|
autoStart |
A shell command or script path that runs automatically when the workstation starts. Useful for launching background services, running migrations, or any one-time setup. |
Log File
Write workstation logs to a file for debugging:
{
"remote": "https://your-server.example.com/projects/my-app",
"logFile": "ticket-house.log"
}
The logFile path is relative to the data directory (.ticket-house/). Logs rotate automatically at 10 MB, keeping the 5 most recent files. You can also set the log file from the command line with --log-file, which takes precedence over the config value.
Full Configuration Reference
Here is a complete .ticket-house.json showing all available fields:
{
"remote": "https://your-server.example.com/projects/my-app",
"environments": [
{ "name": "staging", "url": "https://staging.example.com" }
],
"hooks": {
"post-worktree-create": "scripts/hooks/post-worktree-create",
"pre-worktree-remove": "scripts/hooks/pre-worktree-remove",
"post-track-activate": "scripts/hooks/on-activate",
"pre-track-deactivate": "scripts/hooks/on-deactivate"
},
"devWatch": {
"workDir": "work",
"links": {
"src": "src"
},
"command": "npm run dev",
"cwd": ".",
"autoStart": false
},
"container": {
"image": "my-app-dev",
"containerfile": "Containerfile",
"seedCommand": "npm install",
"idlePool": 2,
"buffer": 1,
"portRange": [5000, 5500],
"maxSlots": 10
},
"reactions": {
"types": [
{ "name": "upvote", "emoji": "👍" }
],
"cooldownSeconds": 60
},
"worktrees": {
"shared-files-symlink": [".env"],
"warningLimitMB": 2000,
"maxLimitMB": 5000,
"cleanupDelayMinutes": 60
},
"commands": {
"autoStart": "scripts/workspace-start.sh"
},
"logFile": "ticket-house.log"
}
Build Tool Integration
If your project uses a build tool or framework, you may need to exclude Ticket House files from the build output. For example:
Jekyll
Add to _config.yml:
exclude:
- .ticket-house.json
Vite / Webpack
No extra configuration needed — these tools respect .gitignore by default.
Verifying Your Setup
After completing the steps above:
- Run
npx ticket-housefrom your project root - The web UI should open showing your project dashboard
- Create a ticket on the server and click "Work Locally"
- A worktree should appear at
.ticket-house/worktrees/with a new branch - Open a terminal in the web UI and start working
If the workstation starts but can't connect to the remote server, verify that your remote URL is correct and the server is reachable.