A local workflow engine that takes you from idea to merged PR, unattended. Two pipelines: a design flow (requirements → scaffolded repo + Linear project + design doc) and a build flow (Linear issue → code → review → PR).
- What It Does
- Why
- Prerequisites
- Quick Start (npm)
- Install from Source
- Configuration
- Usage
- MCP Server (optional)
- Development
- Testing
- Architecture
- Contributing
- Security
- License
Loomforge runs two complementary pipelines, both unattended:
Design flow. Write a one-page requirements doc and run
loomforge design new <slug>. Loomforge scaffolds a Git repo (locally and on
GitHub), drafts a structured design doc, has a reviewer agent critique it,
revises once, then publishes the doc as a Linear project plus a design
document. You review the design and break it into Linear issues — that human
checkpoint is deliberate.
Build flow. Point Loomforge at a Linear project. It fetches actionable
issues, spins up a builder agent (Codex or Claude) to write the code, runs a
reviewer agent to check it, applies one round of fixes if needed, pushes to a
dev branch, and opens a pull request describing what shipped. You review and
merge — Loomforge handles everything before that.
Designed for: solo developers and small teams who want overnight or batch-mode design + build cycles, without running a heavyweight platform.
I've been running an overnight build pipeline since the early days of OpenClaw. After brainstorming designs with OpenClaw and Claude during the day, a nightly cron job would pick up the Linear issues, use Claude to build and Codex to review, and move issues to Done by morning. It worked - until it didn't. Breaking changes in Claude's tool use, instability in OpenClaw's ACP protocol, and fragile skill wiring meant the workflow would silently break every few weeks. I looked at Paperclip, but it carries too much weight - multi-tenant, Postgres, plugin marketplace — for what is fundamentally a single-developer overnight build loop. Loomforge is the lighter, purpose-built replacement: same pipeline, fewer moving parts, easy to fix when something changes.
The design half was the natural sibling. The same brainstorming with OpenClaw that produced the issues also needed a repo and a published design doc — work I was doing by hand at 11pm. Loomforge's design flow runs the same agents over a one-page requirements doc and produces the scaffolding, the Linear project, and the design doc. I still create the issues by hand — that review point stays — and then the build flow takes over.
- Node 22+
- Codex CLI and/or Claude Code CLI — builder and reviewer runners (configurable per project)
- Linear API key — issue fetching and status sync
npm install -g @tezra-io/loomforgeThe installer scaffolds ~/.loomforge/ with default config files and attempts
to register the daemon (launchd on macOS, systemd on Linux).
Then run the interactive setup:
loomforge setupThis validates your config, installs the agent skill (prompts you to choose target agents), and prints next steps.
After setup, configure your Linear API key and add a project (see Configuration).
For contributors or users who prefer to build from source.
git clone git@github.com:tezra-io/loomforge.git
cd loomforge
pnpm install
pnpm run buildLink the CLI globally and run setup:
pnpm link --global
node scripts/postinstall.js # scaffold ~/.loomforge/ and register daemon
loomforge setup # install agent skill, validate configAfter setup, configure your Linear API key and add a project (see Configuration).
Edit ~/.loomforge/config.yaml:
linear:
apiKey: lin_api_YOUR_KEY_HEREOr set an environment variable instead:
export LINEAR_API_KEY=lin_api_YOUR_KEY_HEREAppend to the projects: list in ~/.loomforge/loom.yaml:
projects:
- slug: my-project
repoRoot: /path/to/repo
defaultBranch: main
linearTeamKey: TEZ # required for project-level submission
linearProjectName: My Project # Linear project name — filters issues
builder: codex # "codex" or "claude" (default: claude)
reviewer: claude # "codex" or "claude" (default: claude)
verification:
commands:
- name: test
command: pnpm test
- name: lint
command: pnpm run lintverification.commands are passed to the builder as required self-checks before
handoff. Loomforge does not run a separate verification phase between build and
review.
The design flow scaffolds a new project, drafts a design doc with the builder, reviews it, applies a revision if needed, and publishes to Linear.
Easiest: run loomforge setup. After the agent-skill prompt it asks for a
design repoRoot (default ~/projects — created if missing), a
linearTeamKey (default TEZ), and an optional GitHub org (blank = personal
account), then appends the design: block to ~/.loomforge/config.yaml.
Branches are fixed at main / dev. Skipped if the block is already
present.
Manual: add the block yourself:
design:
repoRoot: /path/to/workspaces # parent dir where new project repos are scaffolded
defaultBranch: main # branch to open the design-doc PR against
devBranch: dev # long-lived branch the design doc is pushed to (default: dev)
linearTeamKey: TEZ # Linear team key that owns new design projects
githubOrg: tezra-io # optional — create new repos under this org instead of your userdevBranch must differ from defaultBranch. githubOrg, when set, is used
as the repo owner in gh repo create <org>/<slug>; omit it (or leave blank)
to create repos under your authenticated GitHub user. Omit the whole block
if you only use the issue-build flow.
If the daemon was registered via postinstall, it starts on login automatically. To start manually:
loomforge start # uses ~/.loomforge/loom.yaml
loomforge start --config /other/path.yaml # custom configloomforge status # daemon health check
loomforge submit my-project # enqueue all actionable issues
loomforge submit my-project TEZ-1 # submit a single Linear issue
loomforge queue # list queued/active runs
loomforge get <runId> # get run state and findings
loomforge cancel <runId> # cancel a queued run
loomforge retry <runId> # retry a failed/blocked runWhen you have a small, well-scoped task and don't want to hand-author a Linear
issue, fire it off as an ad-hoc run. Loomforge creates a loomforge-adhoc-labeled
Linear issue from your prompt, then runs the normal build pipeline against it.
The Linear ticket is the system of record — it transitions through "in progress"
/ "done" exactly like a human-authored issue.
loomforge adhoc "Fix the typo in README" --project loom
loomforge adhoc "Update CHANGELOG for 0.3.0" --project /absolute/path/to/repo--project is required and accepts either a registered slug or an absolute
repo-root path. There is no current-directory fallback. The command prints the
run ID, Linear identifier, and queue position; track it with
loomforge get <runId>.
The project must have linearTeamKey and linearProjectName configured. See
skills/loomforge/SKILL.md for the full ad-hoc flow
including MCP usage and error handling.
# Scaffold a new project, draft & review a design doc, publish to Linear.
loomforge design new my-project \
--requirement-path /abs/path/requirement.md
# Or pass the requirement inline:
loomforge design new my-project --requirement-text "Build a …"
# Draft a feature-extension design doc for an existing project:
loomforge design extend my-project --feature billing \
--requirement-path /abs/path/billing.md
loomforge design get <designRunId> # fetch a design run by id
loomforge design cancel <designRunId> # cancel an active design run
loomforge design retry <designRunId> # retry a failed/blocked design run
loomforge design status my-project # latest design run for a slugRequirement files must be absolute paths, end in .md or .txt, live outside
hidden directories, and stay under 256 KiB. Use --redraft on new / extend
to force a fresh draft when re-running.
The daemon parses ~/.loomforge/loom.yaml once at startup. The design flow
already triggers a reload after register so a freshly scaffolded project is
immediately available to the build flow without restarting. If you hand-edit
loom.yaml, ask the daemon to re-read it:
loomforge config reloadReturns the new project count and slug list. No effect on in-flight runs.
For agents that support MCP tool discovery (OpenClaw, Cursor, etc.), you can optionally register the MCP server:
npx add-mcp loomforge -- loomforge mcp-serveOr target specific agents:
npx add-mcp loomforge -- loomforge mcp-serve -a claude-code -a codexMCP tools:
- Issue build:
loom_health,loom_submit_run,loom_submit_project,loom_get_run,loom_get_queue,loom_get_project_status,loom_cancel_run,loom_retry_run,loom_cleanup_workspace. - Design flow:
loom_design_new_project,loom_design_extend_project,loom_get_design_run,loom_cancel_design_run,loom_retry_design_run,loom_get_design_run_status_for_project.
pnpm run build # compile TypeScript
pnpm run test # run tests (vitest)
pnpm run lint # eslint
pnpm run format # prettier check
pnpm run typecheck # tsc --noEmitRun locally without a global link:
pnpm run dev start --config ./loom.yaml
pnpm run dev status
pnpm run dev submit my-project TEZ-1
pnpm run dev queue
pnpm run dev design new my-project --requirement-text "Build a …"
pnpm run dev design status my-project# Terminal 1: start daemon
loomforge start --config ./loom.yaml --port 3777
# Terminal 2: exercise the API
loomforge status
loomforge submit my-project TEZ-1
loomforge queue
loomforge get <runId>From source without a global link:
pnpm run dev start --config ./loom.yaml --port 3777
pnpm run dev statusPrerequisites: builder and reviewer CLIs authenticated, Linear API key
configured, a test repo with a dev branch.
loomforge start --config ./loom.yaml
loomforge submit my-project TEZ-1 # single issue
loomforge submit my-project # all actionable issues
loomforge queue
loomforge get <runId>
# When all issues complete, a PR from dev→main is created automaticallyPrerequisites: design: block configured (see
Configuration), builder and reviewer
CLIs authenticated, Linear API key configured, a requirement markdown file.
# Terminal 1: start daemon
loomforge start --config ./loom.yaml --port 3777
# Terminal 2: kick off a fresh design run
loomforge design new my-project \
--requirement-path /abs/path/requirement.md
# → returns { designRunId, state: "queued", ... }
loomforge design status my-project # poll overall project state
loomforge design get <designRunId> # inspect the specific run
# On success the design doc is pushed to `design.devBranch` and published
# to Linear as a project document with a review summary.Extend an existing project with a new feature doc:
loomforge design extend my-project --feature billing \
--requirement-path /abs/path/billing.mdSee SPEC.md for Loomforge's public behavior contract. This section maps that contract onto the current implementation.
| Module | Path | Responsibility |
|---|---|---|
| API | src/api/ |
Local HTTP endpoints |
| App | src/app/ |
Daemon bootstrap, lifecycle, service composition |
| CLI | src/cli/ |
Operator-facing wrapper over the API |
| Config | src/config/ |
Project registry, YAML loading, zod validation |
| DB | src/db/ |
SQLite schema, migrations, event log |
| Linear | src/linear/ |
Issue fetching and status sync |
| MCP | src/mcp/ |
MCP server adapter (optional) |
| Workflow | src/workflow/ |
Run state machine, queue drain, retry/recovery |
| Runners | src/runners/ |
Configurable builder + reviewer (Codex or Claude) |
| Worktrees | src/worktrees/ |
Dev branch worktree, rebase, cleanup |
| Artifacts | src/artifacts/ |
Prompt/log/result persistence |
TypeScript · Node 22+ · Fastify · Commander · MCP SDK · @linear/sdk · SQLite · zod · execa · pino
The Loomforge repo ships AGENTS.md (Codex) and CLAUDE.md (Claude Code) at
the repo root, automatically discovered when agents run inside this repo.
For projects that Loomforge builds against, the builder prompt instructs the
agent to read the target repo's own AGENTS.md / CLAUDE.md before making
changes.
Contributions are welcome. To get started:
- Fork the repo and create a feature branch
- Install dependencies:
pnpm install - Make your changes — follow the conventions in
CLAUDE.md - Run checks:
pnpm run build && pnpm run test && pnpm run lint - Open a pull request against
main
Please open an issue before starting large changes so we can align on approach.
Reporting bugs: Open an issue with steps to reproduce, expected vs. actual behavior, and your Node/OS version.
Loomforge assumes a trusted single-user local machine. It runs registered local repos through the Codex CLI and Claude Code CLI, and those tools own their own authentication. Loomforge does not store OpenAI or Anthropic API keys.
Loomforge only reads a Linear API key for Linear issue/project operations, either
from ~/.loomforge/config.yaml or LINEAR_API_KEY. Build runs execute in the
configured project workspace, push only the configured devBranch, and never
merge into the default branch automatically.
If you discover a security vulnerability, please report it privately via GitHub Security Advisories rather than opening a public issue. We will respond within 7 days.

