NTM - Named Tmux Manager
<div align="center">
<img src="https://raw.githubusercontent.com/Dicklesworthstone/ntm/HEAD/ntm_dashboard.webp" alt="NTM dashboard">
</div>
<div align="center">
Platform
Go Version
License
Release
</div>
NTM은 tmux를 다중 에이전트 소프트웨어 개발을 위한 로컬 제어 평면(local control plane)으로 변환합니다. 이 도구는 세션 오케스트레이션(session orchestration), 그래프 인식 작업 분류(graph-aware work triage), 안전 정책 및 승인(safety policy and approvals), Agent Mail 조정, 영속적인 상태 캡처(durable state capture), 기계가 읽을 수 있는 로봇 표면(machine-readable robot surfaces) 그리고 Go 바이너리 내의 로컬 REST/WebSocket API를 하나로 결합합니다.
<div align="center">
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/ntm/main/install.sh?$(date +%s)" | bash -s -- --easy-mode
</div>
요약 (TL;DR)
문제점 (The Problem)
여러 코딩 에이전트를 병렬로 실행하는 것은 시작하기는 쉽지만, 지속적으로 유지하기는 번거롭습니다. 일반적인 tmux는 패널(panes)을 제공하지만, 영속적인 조정(durable coordination), 작업 선택(work selection), 안전 정책, 승인, 기록, 재생 가능한 자동화 표면(replayable automation surfaces), 또는 인간과 에이전트 모두가 사용할 수 있는 공유 제어 모델은 제공하지 않습니다.
해결책 (The Solution)
NTM은 다음을 위한 단일 로컬 시스템을 제공합니다:
tmux 내에서 레이블이 지정된 다중 에이전트 세션 스폰(spawning)
- 패널 간에 작업, 중단(interrupts), 후속 조치 전송
br 및 bv를 사용하여 다음 작업을 분류(triage)하는 기능
- Agent Mail, 파일 예약, 할당을 통해 에이전트 조정
- 정책, 승인, 가드(guards)를 통한 위험한 작업 보호
--robot-*, REST, SSE, WebSocket, OpenAPI를 통해 전체 시스템 노출
- 체크포인트, 타임라인, 감사 추적(audit trails), 파이프라인 상태로 상태 캡처
NTM을 사용해야 하는 이유 (Why NTM)
| 영역 | NTM이 제공하는 것 | 일반적인 명령어 |
|---|
| 세션 오케스트레이션 | 스폰, 레이블 지정, 검사(inspect), 줌, 대시보드, 팔레트 | ntm spawn, ntm dashboard, ntm palette |
| ... | | |
빠른 시작 (Quick Start)
요구 사항 (Requirements)
NTM은 순수 Go 프로젝트이지만, 런타임 경험은 의도적으로 통합(integration)-중심적입니다.
- 필수:
tmux
- 에이전트 생성에 필요: 실행하려는 모든 CLI(예: Claude Code, Codex, Antigravity CLI, Oh My Pi (
omp), Grok Build)가 필요합니다. (Gemini CLI는 레거시로 지원됩니다)
- 선택적이지만 강력한 기능:
br, bv, Agent Mail, cass, dcg, pt
- 모든 것을 확인하려면
ntm deps -v를 사용하세요.
첫 세션 (First Session)
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/ntm/main/install.sh?$(date +%s)" | bash -s -- --easy-mode
...
핵심 워크플로우 (Core Workflows)
1. 다중 에이전트 세션 오케스트레이션 (Multi-Agent Session Orchestration)
NTM은 명명된 tmux 세션을 중심으로 구성되며, 여기에는 명시적인 에이전트 패널과 사용자 패널이 포함됩니다.
이는 세션 이름 지정, 패널 레이아웃, 에이전트 시작, 라벨링 및 검사 기능을 처리하여, 사용자가 터미널 더미(pile of terminals) 대신 관리 가능한 단위처럼 스웜(swarm)을 취급할 수 있게 합니다.
ntm quick payments --template=go
ntm spawn payments --cc=3 --cod=2 --agy=1
ntm add payments --cc=1
...
단순히 --cc=N만 사용하면 --model이 전달되지 않으므로, Claude Code는 자체 기본값 또는 저장된 모델 및 컨텍스트 설정을 사용하여 시작합니다. --cc=N:MODEL을 사용하여 하나를 고정하거나, ~/.config/ntm/config.toml 파일에서 [models] default_claude를 설정할 수 있습니다. default_claude = ""는 위임(delegate) 동작을 복원합니다.
Grok Build
NTM은 공식 xAI Grok Build CLI를 표준 grok 에이전트 유형으로 인식합니다. xAI의 최신 지침을 사용하여 설치한 후, NTM 설정에 자격 증명을 넣지 않고 인증하세요:
curl -fsSL https://x.ai/cli/install.sh | bash
grok login
grok login --device-auth
...
단순한 사양(bare spec)은 모델 선택을 Grok Build에 위임합니다. grok models를 사용하여 인증된 계정에 사용 가능한 모델을 검사하고, 오버라이드가 필요한 경우에만 정확한 모델 ID를 전달하세요.
tm spawn research --grok=1
tm spawn research --grok=1:MODEL_ID
tm spawn research --grok=1:MODEL_ID:EFFORT
...
NTM은 공식 --always-approve 자동화 플래그를 사용하여 Grok Build를 실행합니다. Phase 2 (GH#251)에서는 라이브 Grok Build에 대한 대화형 TUI(Text User Interface) 프로토콜을 구현하여 준비 상태 및 작동 상태 감지, composer-gated 및 submission-verified 프롬프트 전달(send, assign, --robot-spawn --spawn-wait 및 --spawn-assign-work), 인터럽트, 재시작, 복원 시간 재실행 기능을 처리합니다. 유일하게 의도된 거부는 페르소나 관련입니다: Grok Build CLI는 시스템 프롬프트 플래그나 환경 변수를 가지고 있지 않으므로, Grok 에이전트의 페르소나는 조용히 무시되는 대신 실행 자체가 실패합니다.
Oh My Pi (omp)
NTM은 내장된 omp 에이전트 유형으로 Oh My Pi를 운영합니다(패널 이름은 session__omp_N이며, oh-my-pi가 별칭으로 허용됩니다). 첫 번째 스폰 전에 omp의 자체 설정을 완료하지 않으면, 첫 프롬프트가 설정 마법사로 이동하게 됩니다:
omp setup
tm deps -v
tm spawn swarm --omp=8
...
실행 명령어는 omp --auto-approve이며, 요청 시 --model, --thinking, 그리고 --append-system-prompt <file> (페르소나)가 추가됩니다. 이를 [agents] omp = "..."로 재정의할 수 있습니다(템플릿; 노력 사양을 반영하려면 {{.ReasoningEffort}}를 유지하고, 그렇지 않으면 NTM이 무시하는 대신 거부합니다). 또한 [models] default_omp 또는 [models.omp] 별칭과 [prompts] omp_default를 설정할 수 있습니다. [spawn_pacing.agent_caps] omp_max_concurrent(기본값 8)는 호스트 전체 에이전트 예산 중 omp가 할당받는 부분으로, 로봇 스폰 승인 기능은 이를 강제합니다(실행 중인 에이전트와 요청된 에이전트의 합계가 모든 에이전트 캡을 초과할 수 없음). 실행은 유형별로 절대 직렬화되지 않으며, 기본적으로 전체 --spawn-omp=8 스웜을 기본 Claude/Codex/Gemini 예산과 함께 허용합니다.
NTM이 omp pane에 수행하는 모든 작업은 omp의 라이브 TUI(v18.2.3)에서 파생됩니다 (nerd, unicode 및 ascii 심볼 프리셋 전반에 걸쳐):
-
준비됨/작동 중/유휴 상태. omp는 pane 하단에 테두리가 있는 컴포저(composer)를 유지합니다. 진행 중인 작업은 스피너와 경과 시간 타이머가 컴포저의 상단 테두리(╭── ⠧ 1s)에 표시되며, 그 위에는 Esc-힌트 활동 라인(⎋ Working… 또는 의도 레이블)이 있고, 대기 중인 Steering · N 블록이나 실행 중인 subagents를 나열하는 Subagents 패널이 있습니다. TODO 트리만으로는 작업 중으로 간주되지 않습니다. 왜냐하면 계획(plan)은 자신의 턴보다 오래 지속될 수 있기 때문입니다. 아래에 아무것도 없는 조용한 컴포저는 유휴 상태입니다.
-
전달. Enter를 입력하면 제출됩니다. 바쁜 pane으로 전송되는 메시지는 omp에 의해 스티어링(steering)으로 대기열화되며, 페이로드(payload)가 컴포저를 벗어날 때 전달이 확인됩니다. 스테이지된 대용량 붙여넣기(#1 토큰)는 --robot-dialogs에 의해 붙여넣기 임보(paste limbo)로 보고되며 Ctrl+C로 지워집니다.
-
중단 및 종료. omp는 Escape 키에서 중단됩니다 (Ctrl+C만 초안을 지우고, 이중 Ctrl+C가 종료합니다). 따라서 ntm interrupt, --robot-interrupt, 재시작(restart), 그리고 REST 중단은 Escape를 omp pane으로 전송합니다. 정상적인 종료는 Escape, Ctrl+C, 그 다음 Ctrl+D입니다.
-
컨텍스트. --robot-context, --robot-snapshot, ntm status, 그리고 코디네이터의 컨텍스트 회전 트리거는 컴포저 테두리에서 omp 자체의 컨텍스트 게이지(7% … 262K)를 읽어와, 이를 source: "status_bar"로 보고합니다. 따라서 여러 omp pane이 하나의 디렉터리를 공유하더라도 읽기 값은 pane별로 유지됩니다. 압축(Compaction)은 네이티브 /compact를 사용하며 컨텍스트 게이지의 신선한 감소를 확인합니다.
-
세션. ntm sessions save는 각 pane을 해당 omp 세션에 바인딩합니다 (omp는 자신의 기록(transcript)을 ~/.omp/agent/sessions/ 아래에 열어 유지하므로, 바인딩은 pane별로 정확하며 프로필, XDG 및 PI_CODING_AGENT_* 저장소가 존중됩니다). 그리고 omp --auto-approve --resume <id>를 사용하여 재개 실행합니다.
-
오류(Errors). 실패한 턴은 컴포저 위에 직접 규칙으로 둘러싸인 제공자 오류 블록을 남깁니다 (server_error: ERROR, 401 Invalid API Key 등, 이후 다음 메시지를 보내면 해제됨(Dismissed when you send your next message.)). NTM은 이를 유휴 상태 후 완료가 아닌 오류로 보고합니다. --robot-is-working은 indicator_basis: "provider_error"와 함께 ERROR_STATE를 반환하며 재시도 힌트를 제공하고, 상태 관찰 및 코디네이터는 오류(401/403의 경우 auth, 그 외에는 일반적인 오류)를 보고하며, 할당된 작업은 해당 패널에 새로운 작업을 공급하지 않습니다. 블록과 입력 상자 사이에는 F5로 재시도(F5 to Retry) 힌트가 있을 수 있습니다. 실패한 턴을 다시 실행하려면 F5 (omp의 재시도 키)를 누르거나, 계속 프롬프트와 같은 메시지를 보내면 블록이 해제되고 재시도가 이루어집니다. Error: No model selected. 역시 오류입니다. 아직 omp 속도 제한 화면(rate-limit screen)이 캡처되지 않았기 때문에, omp 패널은 트랜스크립트 텍스트로부터 절대 속도 제한 상태로 표시되지 않으며, 제공자 429는 제공자 오류로 나타납니다.
-
할당량(Quota). omp에는 할당량이나 사용량 명령이 없습니다. ntm quota는 omp 패널을 "no quota API (provider-error classification)"으로 나열하고, ntm rotate all-limited는 해당 이유로 이들을 건너뛰며, --robot-quota-check --provider=omp는 동일한 폴백(fallback) 이름을 가진 NOT_IMPLEMENTED (종료 코드 2)를 반환합니다.
-
팔레트, 할당, 부팅 확인(Palette, assignment, boot checks). ntm palette에서 키 7은 omp 패널을 대상으로 하며 (6은 여전히 개별 에이전트를 선택합니다), --assign은 omp에 Claude와 Codex 역량 프로필의 작업별 중간 지점을 점수화하는데, 이는 omp의 강점이 실행하는 모델에 따르기 때문입니다. --verify-boot는 패널이 유휴 상태일 때 또는 스폰 프롬프트(복구 컨텍스트, CASS 컨텍스트 또는 사용자 프롬프트)를 받고 작업 중일 때 부팅된 것으로 간주합니다.
OpenCode (oc)
OpenCode 패널은 session__oc_N으로 이름이 지정됩니다. 모델은 OpenCode의 provider/model 형태를 따르며, 모델이 없으면 OpenCode 자체 기본값을 사용합니다.
실행 명령어는 opencode --model <모델>입니다. 노력(effort) 조절 노브가 없는데, TUI에는 --variant 플래그가 없습니다(오직 opencode run에서만 사용). 따라서 스펙에 명시된 노력은 무시됩니다. 명령어를 [agents] oc = "..."로 덮어쓸 수 있습니다 (템플릿입니다. 모델 스펙을 존중하려면 {{if .Model}} --model {{shellQuote .Model}}{{end}}를 유지하세요). 또한, [models] default_opencode 또는 [models.opencode] 별칭(alias)을 설정할 수 있습니다. 프롬프트는 대괄호 붙여넣기(bracketed paste)로 전달되며 컴포저(composer)와 검증됩니다: TUI가 드롭하는 프롬프트는 성공으로 보고되는 대신 전송에 실패합니다.
자동화된 패널 및 권한. OpenCode는 작업 전에 자체의 권한 설정(permission config)이 ask로 표시하는 경우 사용자에게 요청을 합니다 (기본적으로 프로젝트 외부 경로인 external_directory를 포함합니다). 해당 패널에 아무도 없을 경우, 요청은 자동으로 거부되고 턴(turn)이 중단됩니다. 사전 승인할 수 있는 두 가지 방법이 있습니다:
-
--auto로 실행하기 (OpenCode 1.18.0+): 이 옵션은 명시적으로 거부되지 않은 모든 요청을 해당 패널에 한해서 자동으로 승인합니다:
[agents]
oc = "opencode --auto{{if .Model}} --model {{shellQuote .Model}}{{end}}"
deny 규칙은 여전히 적용되므로, 패널이 절대 수행해서는 안 되는 모든 작업에 대해 --auto와 거부 규칙을 결합할 수 있습니다.
-
OpenCode 자체의 "permission" 설정을 지정합니다. 이 설정은 읽어들이는 모든 OpenCode 세션에 전역적이며, 개별 패널마다 적용되는 것이 아닙니다: ~/.config/opencode/opencode.json, 프로젝트의 opencode.json, 또는 환경 변수 OPENCODE_CONFIG / OPENCODE_CONFIG_CONTENT를 사용합니다. 각 키는 allow, ask, 또는 deny 값을 가지며, `
경로 패턴은 *, ?, 그리고 선행하는 ~를 지원합니다. 디렉터리 트리를 포함하려면 **를 사용하십시오: OpenCode는 실제로 접촉하는 정확한 경로 대신 부모 디렉터리의 glob을 확인할 수 있으므로, 하나의 리프 디렉터리에 대한 패턴이라도 거부될 수 있습니다.
공유 프로젝트 디렉터리를 유지하면서 동일한 프로젝트에서 여러 개의 조정된 스웜(swarms)을 사용하려면 레이블을 사용하십시오:
tm quick payments --template=go
tm spawn payments --label backend --cc=2 --cod=1
tm spawn payments --label frontend --cc=2
...
단계적 프롬프트 (thundering-herd prevention)
여러 에이전트가 동시에 부팅되고 모두 한 번에 bv/br에서 작업을 가져가려고 할 때, 이들은 같은 비즈(bead)를 두고 경쟁합니다. 다음 에이전트가 찾기 시작하기 전에 각 에이전트가 무언가를 확보하도록 초기 프롬프트를 단계적으로 조정하십시오: