Tungsten

Run many AI coding agents at once, without losing track of them.

Download for macOS

Tabs hide things. A canvas doesn't. Tungsten gives every coding agent a real terminal on an infinite canvas, and its own git worktree if you want one, with your .env files copied over and dependencies installed before it starts.

Zoom out and the whole fleet is in front of you. You see the branch each agent is on, what it has changed, its pull request and whether its tests pass. Zoom in and it's just a shell. The diff, the commit history and a live preview of the dev server open beside the terminal that made them, and a terminal glows when its agent is waiting on you.

Works with , and , launched from the dock with your Claude and Codex plan limits in view. Anything else runs in a plain terminal.

~/.tungsten/worktrees/acme-web/steady-ridgeworksteady-ridge
✳ Fix checks detail link
▐▛███▜▌ Claude Code v2.1.173
▝▜█████▛▘ Opus 5.5 · Claude Max
▘▘ ▝▝ ~/.tungsten/worktrees/acme-web/steady-ridge
> the checks link on the PR panel 404s. fix it and add a regression test
⏺ I'll trace where the checks URL is built and compare it with what
GitHub actually serves.
⏺ Search(pattern: "details_url|buildChecks", path: "src")
⎿ Found 3 files
⏺ Read(src/integrations/github/checks.ts)
⎿ Read 112 lines
⏺ Found it. The builder links /check-runs/{id}, which only exists in
the API; the web UI serves /runs/{id}.
⏺ Update(src/integrations/github/checks.ts)
⎿ Updated src/integrations/github/checks.ts with 1 addition and 1 removal
86 export function buildChecksDetailUrl(run: CheckRun): string {
87 - return `${run.repoUrl}/check-runs/${run.id}`
87 + return `${run.repoUrl}/runs/${run.id}`
88 }
⏺ Write(src/integrations/github/checks.test.ts)
⎿ Wrote 19 lines to src/integrations/github/checks.test.ts
⏺ Bash(pnpm test checks)
⎿ ✓ src/integrations/github/checks.test.ts (2 tests) 41ms
Test Files 1 passed (1)
Tests 2 passed (2)
⏺ Bash(pnpm lint)
⎿ (No content)
⏺ Bash(pnpm typecheck)
⎿ (No content)
⏺ Fixed. Check rows now link /runs/{id}, and checks.test.ts pins the
URL shape so the API path can't come back. Tests, lint and typecheck
pass.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
? for shortcuts
2 files +20-1
Diff
8484
8585/** GitHub's own page for one check run. */
8686export function buildChecksDetailUrl(run: CheckRun): string {
87 return `${run.repoUrl}/check-runs/${run.id}`
87 return `${run.repoUrl}/runs/${run.id}`
8888}
1import { describe, expect, it } from 'vitest'
2import { buildChecksDetailUrl, type CheckRun } from './checks'
3
4const run = {
5 id: 1842,
6 repoUrl: 'https://github.com/acme/acme-web',
7} as CheckRun
8
9describe('buildChecksDetailUrl', () => {
10 it('links the run page, not the API path', () => {
11 expect(buildChecksDetailUrl(run)).toBe(
12 'https://github.com/acme/acme-web/runs/1842',
13 )
14 })
15
16 it('never builds a /check-runs/ link', () => {
17 expect(buildChecksDetailUrl(run)).not.toContain('/check-runs/')
18 })
19})
fix/checks-detail-link9
History
4 checks
Checks
~/.tungsten/worktrees/acme-web/quiet-meadowquiet-meadow
zsh
~/work/acme-web
pnpm dev
➜ acme-web git:(main) pnpm dev
> acme-web@0.1.0 dev /Users/you/work/acme-web
> next dev
▲ Next.js 16.3.5
- Local: http://localhost:3000
- Network: http://192.168.1.24:3000
✓ Starting...
✓ Ready in 812ms
○ Compiling / ...
✓ Compiled / in 1.2s (612 modules)
GET / 200 in 1388ms
http://localhost:3000/
localhost:3000
Cart (2)

Your cart

Field jacketOlive · M$148.00
Merino crewOat · M$86.00
~/.tungsten/worktrees/acme-web/calm-harborworkcalm-harbor
✳ Claude Code
▐▛███▜▌ Claude Code v2.1.173
▝▜█████▛▘ Opus 5.5 · Claude Team
▘▘ ▝▝ ~/.tungsten/worktrees/acme-web/calm-harbor
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
? for shortcuts
~/work/acme-internal
zsh
➜ acme-internal git:(main) git pull
Already up to date.
➜ acme-internal git:(main)
Claude usage5-hour 58% · resets in 2h 14mWeekly 41% · resets ThuDefault profile
Codex usage5-hour 52% · resets in 3h 2mWeekly 37% · resets Sat

Every session is a real terminal on one plane. Drag panes by their header, pinch or ⌘-scroll to zoom, ⌘F to fit everything.

Tungsten's canvas with several coding agents, a diff, CI checks and a browser pane
Open this page on a bigger screen to try the demo.

Forged by Vinayak