
aitm 1.0: AI가 운전자가 아닌 참여자가 되는 터미널
요약
AI 보조 코딩 시 컨텍스트 스위칭을 최소화하기 위해 개발된 AI 터미널 'aitm 1.0'을 소개합니다. 사용자가 AI의 제안을 검토하고 실행을 승인하는 '참여자 중심' 설계와 Tauri 및 Rust를 활용한 경량화된 성능이 특징입니다.
핵심 포인트
- AI가 제안하고 사용자가 결정하는 제어 중심 설계
- 읽기 전용 도구 자동 호출 및 실행 명령 승인 루프 구현
- Tauri와 Rust를 사용하여 Electron 대비 압도적인 저사양/고성능 실현
- 컨텍스트 스위칭 없는 통합 개발 환경 제공
저는 터미널 세션 내에서 AI 보조 코딩 (AI-assisted coding)을 하고 있었습니다. AI는 계속해서 파일을 수정했지만, 저는 동일한 창에서 그 변경 사항을 확인할 방법이 없었습니다. 앱을 전환하고, 컨텍스트 (context)를 전환했다가 다시 돌아와야 했습니다. 이 사이클을 반복할 때마다 흐름이 끊겼습니다.
제가 원한 것은 간단했습니다. 컨텍스트 스위칭 (context-switching) 없이 터미널과 AI, 그리고 파일들이 모두 한곳에 있는 것이었습니다. 그래서 직접 만들었습니다.
그것이 aitm의 시작입니다. 버전 1.0이 바로 그 결과물이며, 출시되었습니다.
디자인 선택: 운전자가 아닌 참여자
대부분의 AI 터미널은 단일 모델을 중심으로 구축됩니다. 사용자가 의도를 설명하면 AI가 실행하는 방식입니다. 잘 작동할 때는 효율적이지만, 그렇지 않을 때는 최악의 오후를 보내게 됩니다.
aitm은 다른 선을 긋습니다. AI는 사용자의 환경을 보고, 파일을 읽고, 도구 (tools)를 호출할 수 있지만, 실행은 항상 사용자에 의해 제어됩니다. 불변의 원칙은 다음과 같습니다:
AI가 제안한다 → 사용자가 결정한다 → 실행된다.
실제로 AI는 list_files, read_file, get_terminal_history, search_history를 자동으로 호출합니다. 이것들은 읽기 전용 (read-only)입니다. 사용자는 결과가 들어오는 대로 대화창에서 확인할 수 있습니다. 하지만 상태를 변경하는 모든 것인 run_command는 루프를 멈추고 사용자의 승인을 기다립니다.
돌이켜보면 이 차이는 당연해 보입니다. 하지만 설계 당시에는 당연하지 않았습니다. 첫 번째 버전에는 저위험 명령을 자동 승인하는 "신뢰 모드 (trust mode)"가 있었습니다. 저는 그것을 제거했습니다. UX는 약간 더 매끄러워졌을지 모르지만, 통제권을 갖고 있다는 '느낌'을 포기할 가치는 없었습니다.
왜 Tauri와 Rust인가
Electron은 평가해 볼 만한 명백한 첫 번째 옵션이었습니다. 유휴 상태(idle)에서 RAM 사용량은 약 150 MB였고, 창을 띄우는 데 몇 초가 걸렸습니다. 프로토타입으로는 괜찮지만, 하루 종일 열어두어야 하는 도구로서는 받아들일 수 없는 수준이었습니다. 그래서 Electron은 초기에 제외되었습니다.
처음부터 Tauri 2와 Rust를 선택했습니다. 사용 가능한 수준에 도달하기까지 2개월이 걸렸습니다. 수치는 다음과 같습니다:
- 5.3 MB 바이너리 (binary) (vs 150+ MB Electron)
- 3–5 ms 콜드 스타트 (cold start)
- 유휴 상태(idle) 시 ~30 MB RAM 사용
React 19 프론트엔드가 UI를 처리합니다. Rust 레이어는 PTY, IPC, 도구 실행(tool execution) 및 보안을 담당합니다. 이 점이 중요합니다. 보안 게이트(security gates)가 Rust에서 실행되므로, JavaScript/React 레이어는 이를 우회할 수 없습니다. AI 레이어는 Tauri IPC를 통해 요청을 보내며, 명령이 실제로 실행될지 여부를 결정하는 것은 Rust 핸들러입니다.
4계층 보안 모델 (The four-layer security model)
모든 run_command 호출은 셸(shell)에 도달하기 전 네 개의 순차적인 게이트를 통과합니다.
L1 — 차단 목록 정규식 (Blocklist regex). 항상 실패하는 하드코딩된 패턴입니다. rm -rf /, 포크 폭탄(fork bomb) :(){ :|:& };:, dd if=/dev/zero 및 약 50여 개의 패턴이 포함됩니다. 이는 "사용자가 확인했다"는 사실만으로는 부족한 명령들로, 차단 목록은 정확히 무조건적인 차단을 위해 존재합니다.
L2 — 휴리스틱 위험 점수 산정 (Heuristic risk scoring). 명령 문자열은 일련의 신호들을 기준으로 점수가 매겨집니다. /를 건드리는지, 리다이렉션(>)을 사용하는지, sh로 파이프(pipe)를 연결하는지, 시스템 디렉토리를 참조하는지 등을 확인합니다. 결과값은 DESTRUCTIVE(파괴적), HIGH(높음), 또는 LOW(낮음)로 출력됩니다. 이 라벨은 확인 대화 상자에 표시되어, 특정 항목이 왜 플래그(flag)되었는지 확인할 수 있게 해줍니다.
L3 — 프로젝트 범위 허용 목록 (Project scope allowlist). 각 세션에는 구성된 프로젝트 디렉토리가 있습니다. AI가 작동할 수 있는 경로와 패턴인 globset을 정의할 수 있습니다. 범위를 벗어나는 모든 것은 L4에 도달하기 전에 플래그가 지정됩니다. 이는 선택 사항(opt-in)이지만, "이 프로젝트에서 작업하는 AI"와 "사용자의 전체 머신에 접근 권한이 있는 AI"를 구분 짓는 핵심 요소입니다.
L4 — 명시적 사용자 확인 (Explicit user confirmation). 모든 run_command는 전체 명령 텍스트, 위험 수준, 범위 확인 결과가 포함된 모달(modal)을 생성합니다. 자동 승인(auto-approve) 모드는 없으며, 이를 설정할 수 있는 방법도 없습니다.
L1과 L2는 비동기 오버헤드 없이 Rust에서 동기식(synchronously)으로 실행됩니다. L3는 globset 크레이트(crate)를 사용합니다. L4는 IPC 핸들러의 강력한 게이트입니다. AI 레이어의 어떤 호출 경로도 이를 통과하지 않고는 셸에 도달할 수 없습니다.
run_command 요청
│
├─ L1: 차단 목록 정규식 (blocklist regex) ────────────► 즉시 거부 (REJECT)
...
1.0 버전의 기타 출시 사항
도구 루프 (tool loop)와 보안 모델이 핵심입니다. 1.0의 나머지 모든 기능은 제가 그동안 미뤄왔던 것들입니다.
프로젝트 범위 + SQLite 지속성 (persistence). 이제 세션에 프로젝트 디렉토리가 부여됩니다. 대화 기록 (conversation history), 세션 상태 (session state), 그리고 설정 (config)은 모두 로컬 SQLite 데이터베이스에 저장됩니다. 어떤 데이터도 사용자의 기기를 벗어나지 않으며, 계정 생성도 필요하지 않습니다.
6개의 LLM 제공업체. OpenAI, Anthropic, DeepSeek, Qwen (Alibaba DashScope), Zhipu, 그리고 Moonshot (Kimi)을 지원합니다. 세션마다 교체하여 사용할 수 있습니다. 이 6개 업체는 커버리지를 위해 선정되었습니다. 서구권 API 제공업체와 더불어, 중국(CN)에서 낮은 지연 시간 (low-latency) 접속을 원하는 사용자를 위한 주요 중국 제공업체들을 포함했습니다.
8가지 테마, 영어 및 중국어 UI. 테마는 취향을 반영하여 구성되었습니다. 긴 세션 동안 눈이 더 편안하다고 느끼는 어두운 수묵화 (ink-wash) 테마도 있습니다.
분할 창 (Split-pane) CodeMirror 에디터. 창 내부에 빌트인된 파일 에디터입니다. 터미널 컨텍스트 (terminal context)를 잃지 않고 빠르게 편집할 수 있습니다.
macOS Developer ID 공증 (notarization). .dmg 파일이 서명 및 공증되었습니다. 첫 실행 시 Gatekeeper 경고가 나타나지 않습니다.
1.0에 포함되지 않은 사항
Windows 지원도 존재합니다. CI(지속적 통합)를 통해 빌드되며 저도 실행해 보았습니다. 하지만 macOS는 제가 매일 사용하는 플랫폼이며 예외 케이스 (edge cases)를 가장 잘 커버할 수 있는 환경입니다. Windows 테스트는 상대적으로 덜 철저합니다.
도구 호출 (tool-calling) 루프 내에서 AI 응답 스트리밍 (streaming)은 지원되지 않습니다. AI는 모든 도구 호출이 완료된 후에 응답합니다. 실제로는 대기 시간이 보통 2초 미만이지만, 여러 번의 읽기 (reads) 작업이 포함된 시퀀스의 경우 눈에 띄는 간격이 발생합니다. 이 부분은 1.1 버전에서 다시 검토하겠습니다.
플러그인 시스템 (Plugin system) 및 사용자 정의 도구 (user-defined tools)는 현재 구현되어 있지 않으며 로드맵에 포함되어 있습니다.
다운로드
GitHub release에서 바이너리 (Binary)를 받을 수 있습니다:
- macOS Apple Silicon
- Windows x86_64
- Windows ARM64
소스 코드는 GitHub에서 Apache 2.0 라이선스 하에 제공됩니다. 이슈 (Issues) 및 토론 (discussions)은 열려 있습니다. 보안 모델 (security model)에 대해 구체적으로 논의하고 싶다면 그곳에서 진행해 주세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기

