Overview

To use Ticket House with a project, you need two things:

  1. A project registered on your Ticket House server
  2. A .ticket-house.json configuration 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., MA produces tickets like MA-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:

  1. Creates a .ticket-house/ data directory for local state
  2. Starts the HTTP server on port 3412
  3. 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:

  1. Run npx ticket-house from your project root
  2. The web UI should open showing your project dashboard
  3. Create a ticket on the server and click "Work Locally"
  4. A worktree should appear at .ticket-house/worktrees/ with a new branch
  5. 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.