GJC / INSIDE THE SESSION
가재코드 코드 탐색 · 인터랙티브 해설

가재코드,
안에서 무슨 일이
일어날까?

하나의 대화 뒤에는 메인 실행, 하위 에이전트, 질문, 백그라운드 작업이 있습니다. 이들의 상태를 구분해야 키보드의 불빛도 정확해집니다.

● 코드에서 확인◇ 키크론 설계 제안예시 시뮬레이션 · 실제 연결 없음
01 / 단위세션 하나에 여러 작업

메인과 자식은 연결되어 있지만, 각각의 종료 시점은 다릅니다.

02 / 완료응답 끝 ≠ 소유 작업 전체 끝

어떤 단위가 끝났는지부터 확인해야 합니다.

03 / 관찰파일과 스트림은 다른 창

현재 스냅샷과 시간 순서의 사건은 서로 보완합니다.

먼저 01의 노드를 눌러 보고, 03에서 ‘부모 응답 종료’를 재현해 보세요. 코드 기준: 2026-09-06 조사 · f50b17a

01
코드에서 확인

GJC의 중심은 AgentSession입니다

사용자 요청을 실행하고, 발생한 이벤트를 여러 소비자에게 전달합니다. 아래 지도는 주요 상태 전달 경로입니다. 화살표는 관계를 나타내며 모든 내부 호출을 그린 것은 아닙니다.

가재코드 상태 전달 구조터미널 입력은 AgentSession에 요청을 전달합니다. Agent runtime에서 발생한 이벤트는 AgentSession을 통해 로컬 구독자, 확장 기능, 비동기 상태 파일로 전달됩니다. 확장 기능은 SDK runtime에 연결됩니다. 아래 일곱 버튼으로 각 요소를 설명합니다. 요청 시작 생명주기 이벤트 로컬 전달 확장 이벤트 비동기 저장 SDK 연동 실선: 이벤트 전달점선: 비동기 파일 저장
읽는 방향: 요청 입력 → 실행 이벤트 → 여러 소비자. Task와 백그라운드 작업의 계층은 03에서 따로 살펴봅니다.

AgentSession

session/agent-session.ts

한 대화 세션의 실행을 조정합니다. 로컬 이벤트 전달과 상태 파일 쓰기를 분리하므로 파일 쓰기가 늦거나 실패해도 대화형 실행이 반드시 멈추는 것은 아닙니다.

키크론의 관점: 현재 실행을 가장 가까이에서 관찰할 수 있는 지점입니다.

코드 근거 열기 ↗
GJC는 모델 호출 한 번을 뜻하지 않습니다. 세션을 유지하면서 모델·도구·확장·하위 작업을 조정하는 실행 시스템입니다.
02
이벤트 의미는 실제 코드 · 순서는 학습용 예시

‘기능 수정하고 테스트해줘’를 따라가 볼까요?

다음 단계를 눌러 이벤트를 한 개씩 진행하세요. 중요한 차이는 turn_endagent_end입니다.

01 / 09대기

아직 실행 전

사용자 입력 대기

터미널과 세션은 살아 있습니다. 에이전트가 일을 하지 않는 것과 프로세스가 종료된 것은 다릅니다.

응답 1코드 읽기
응답 2수정·테스트
응답 3결과 설명
학습용 EVENT TRACE · 실제 로그 아님
아직 실행 이벤트가 없습니다.
Coordinator의 turn.completed와 Agent runtime의 turn_end는 다릅니다. 전자는 관리하는 요청의 완료이고, 후자는 모델 응답 한 번과 도구 결과의 끝입니다.
agent_end도 성공이 아닐 수 있나요?

네. 종료 사유는 completed, paused, cancelled, maintenance 등으로 나뉩니다. 실패 진단과 유지보수 결과도 확인해야 합니다. 이벤트 이름 하나만 보고 초록색으로 바꾸면 취소와 일시정지도 성공처럼 보일 수 있습니다.

AgentEvent 타입 ↗
완료된 응답은 목표 달성의 증거인가요?

응답 종료는 실행 경계입니다. 테스트 통과, 목표 달성, 보고 가능한 결과 수령은 별도 의미입니다. 키크론 초록색을 ‘응답 완료’로 정할 수도 있지만 ‘모든 작업 완료’와 같은 뜻으로 설명하면 안 됩니다.

SDK 종료 분류 ↗
03
키크론 집계 정책 제안 · 아직 미구현

한 키 안의 여러 에이전트, 직접 바꿔 보세요

여기서는 ‘한 키 = 최상위 세션과 그 자식들’로 묶습니다. 초록색은 메인 정상 종료와 소유 작업의 정리가 모두 확인된 예시입니다. 실제 제품의 최종 표시 정책은 별도 결정 사항입니다.


01 / 08

메인과 두 자식이 실행 중

코드 조사와 구현을 나눠 실행하고, 테스트도 백그라운드에서 돌리고 있습니다.

세션 A에 메인, 조사·구현 서브에이전트와 백그라운드 작업이 연결됩니다. 아래 상태 요약을 확인하세요.

선은 소유 관계입니다. 원·기호·문구로 상태를 함께 구분합니다. 자식에게 독립 터미널이 있다는 뜻은 아닙니다.

메인
실행 중
조사 자식
실행 중
구현 자식
실행 중
백그라운드 작업
실행 중
이번 사건과 집계 근거 보기

아래 JSON은 설명용 정규화 모델입니다. 현재 GJC의 실제 wire 형식을 그대로 복사한 것이 아닙니다.

‘자식 완료’는 누구의 완료일까요?

조사 담당이 끝나도 메인이 코드를 쓰고 있을 수 있습니다. 부모 응답이 끝나도 백그라운드 테스트는 계속될 수 있습니다. 따라서 실행 상태, 미해결 질문, 자식·job 상태를 별도 보관합니다.

task:subagent:* 채널 정의 ↗

키를 누르면 어디로 가나요?

기본적으로 그 작업을 소유한 메인 세션의 터미널로 이동합니다. 자식은 hasUI:false로 생성될 수 있으므로 ‘자식 하나 = 터미널 하나’가 아닙니다.

자식 세션 생성 코드 ↗
04
현재 구현의 수신 범위 비교

어디에 연결해야 상태를 받을 수 있을까요?

‘스트림이 존재한다’와 ‘외부 관찰자가 필요한 모든 상태를 받을 수 있다’는 다른 조건입니다. 수신 경로를 선택해 차이를 확인하세요.

현재 구현

파일 감시는 현재 상태를 다시 읽는 방식입니다

GJC상태 파일 교체변경 알림 · 읽기

OS 파일 변경 알림을 받아 상태를 읽을 수 있습니다. 다만 파일은 마지막 상태를 담으므로, 읽기 전에 여러 번 바뀐 중간 전이는 사라질 수 있습니다.

알 수 있는 것

마지막으로 저장된 실행 상태와 일부 도구 활동.

이 경로만으로 부족한 것

전체 사건 순서, 자식 계층, 모든 질문·승인, 정확한 프로세스 생존.

소스 확인 ↗
일반 TUI 실행의 도구 이벤트가 모든 SDK 연결로 방송되지는 않습니다. 메시지·도구 스트리밍은 해당 실행의 SDK 소유 연결을 대상으로 합니다. 연결만 성공했다고 전체 관찰이 가능한 것은 아닙니다. 코드 확인 ↗
기존 선례

Herdr는 내부 이벤트를 듣습니다

installHerdrReporter(
  listener => session.subscribe(listener)
)

메인 시작·종료와 ask 도구 대기를 외부 앱에 보고합니다. GJC 안에 관찰 어댑터를 두는 구조가 이미 존재합니다.

모든 자식·백그라운드 작업·승인을 처리하는 완성형 어댑터는 아닙니다.

Herdr reporter ↗
키크론 제안

상태 관찰과 HID 출력을 분리합니다

GJC 안에서 관찰메인 + Task 이벤트 + jobs + 질문/승인
최소 상태만 전달로컬 소켓 · 첫 연결/재연결 시 snapshot
키크론에서 집계세션별 상태 → 고정 키 → LED · 터미널 이동

공개 확장으로 부족한 관찰 지점은 GJC 쪽 추가 구현이 필요할 수 있습니다. 여기서는 네트워크 연결을 실행하지 않습니다.

05

더 깊이 이해하고 싶을 때

한 번에 다 읽지 않아도 됩니다. 파일의 의미, 식별자, 실패 복구, 현재 키크론의 변경 지점을 필요할 때 펼쳐 보세요.

① .gjc 안에는 무엇이 저장되나요?
프로젝트 실행 디렉터리/ └─ .gjc/ ├─ _session-<encodedSessionId>/ │ └─ runtime/ │ └─ runtime-state.json ← 런타임 상태 └─ state/ └─ sdk/ └─ <sessionId>.json ← SDK 연결 정보

조사한 커밋에서 런타임 상태와 SDK 연결 정보는 다른 위치를 사용합니다. 명시적 환경 설정과 실행 모드에 따라 경로가 달라질 수 있습니다. SDK 연결 정보의 직접 소비는 공식 외부 통합 경로로 안내되지 않습니다.

필드오해하면 안 되는 것
state마지막으로 기록한 런타임 상태모든 작업을 합친 전역 상태 아님
live기본 작성 경로는 state === running프로세스가 살아 있다는 별도 증거 아님
updated_at생명주기 상태 기록 시각매초 갱신되는 생존 신호 아님
active_tool_countin-flight 도구 호출 수에이전트 수 아님
activity.seq도구 활동 변경 순번모든 상태 이벤트의 전역 순번 아님

공개 도구 목록은 최대 8개로 제한되지만 개수는 별도로 유지합니다. 파일의 수정 시간이 오래됐다는 이유만으로 세션을 종료 처리하면 긴 도구 실행을 오판할 수 있습니다.

중복 쓰기 제한과 상태 작성 ↗
② sessionId, agentId, PID, 터미널 ID가 왜 모두 필요한가요?

각 식별자는 다른 질문에 답합니다. 프로젝트 이름 하나나 PID 하나로 합치면 다른 실행을 같은 작업으로 오인할 수 있습니다.

01프로젝트 경로

어디의 코드를 다루는가? 같은 프로젝트에 독립 세션이 여러 개 있을 수 있습니다.

02sessionId

어느 대화 세션인가? 전환·재개·분기와 물리 터미널의 수명은 다릅니다.

03actor / owner

어떤 자식이며 누가 소유하는가? 부모의 이벤트 버스 문맥도 함께 유지합니다.

04실행 세대 / 순번

어느 실행의 몇 번째 사건인가? 이전 실행의 늦은 종료가 새 실행을 덮지 않게 합니다.

05터미널 이동 대상

키를 누르면 어느 화면을 여는가? GJC sessionId만으로 모든 앱의 화면을 찾을 수는 없습니다.

PID는 재사용될 수 있으므로 SDK는 프로세스 incarnation과 endpoint generation 등을 고려합니다. 설명용 시뮬레이터의 runId는 개념 표현이며 실제 SDK 필드명을 통일한 것이 아닙니다.

Broker identity / liveness ↗
③ 질문 하나에 답했는데 왜 아직 대기 중일 수 있나요?

질문이 여러 개일 수 있기 때문입니다. 대기 상태는 boolean 하나보다 미해결 질문·승인 ID의 집합으로 보는 편이 정확합니다. 부모와 자식, 로컬 UI와 원격 응답 경로가 서로 다른 대기 상태를 가질 수 있습니다.

AskTool은 실제 TUI가 있으면 로컬 UI를 우선합니다. 원격 answer source가 있으면 로컬·원격 응답을 경합시킵니다. headless에서는 workflow gate 같은 경로를 사용합니다. 답변·취소·시간 초과를 같은 질문에 결속해야 잔여 대기가 남지 않습니다.

단순한 ask 도구 시작·종료 추적은 좋은 출발점입니다. 하지만 권한 확인, 확장 UI, 워크플로 승인 전체를 포괄한다고 보장할 수는 없습니다.
AskTool의 로컬/원격 분기 ↗
④ 연결이 끊기면 마지막 상태를 계속 보여주면 되나요?

마지막 상태를 참고 정보로 남길 수는 있지만 ‘현재 확인된 상태’로 보여주면 안 됩니다. 관찰 신뢰도와 작업 상태를 분리해야 합니다.

연결됨 → 사건 수신 → 연결 끊김
                    ↓
            현재 상태 확인 불가
                    ↓ 재연결
             현재 스냅샷 취득
                    ↓
          이후 사건을 순서대로 적용

SDK event ring의 기본 보관 크기는 256개입니다. 순번에 gap이 생기면 현재 상태를 다시 맞춰야 합니다. SDK의 (revision, generation, seq)와 Coordinator의 namespace별 seq는 서로 다른 순서 체계입니다.

주기적인 연결 heartbeat와 업무 상태를 반복 조회하는 폴링은 목적이 다릅니다. ‘상태는 이벤트로 받고 연결은 heartbeat로 확인’하는 설계는 가능합니다.

이벤트 보관 및 gap ↗
⑤ 같은 프로젝트를 한 키로 묶으면 무엇이 달라지나요?

세션 가족별 배정은 A와 B에 별도 키를 줍니다. 프로젝트 그룹은 A와 B를 한 키 아래에 합칩니다. 후자는 키를 아낄 수 있지만 어떤 세션의 상태인지 한눈에 구분하기 어렵고, 키 입력 시 이동 우선순위와 순환 규칙이 필요합니다.

03의 체크박스를 켜면 세션 A가 끝나도 같은 프로젝트의 B가 실행 중이라 초록색이 되지 않습니다. 그룹의 ‘완료’를 어떻게 정의하느냐에 따른 차이입니다.

작업공간의 개발 티켓은 최상위 GJC 세션별 키 배정과 Orca 터미널 이동을 기술합니다. 이 HTML의 프로젝트 그룹은 비교 학습용이며 확정된 추가 기능이 아닙니다.

⑥ 현재 키크론 코드에서 무엇을 재사용하나요?
영역현재 코드GJC 적용 시
장치 제어keychron_hid.pyLED 출력과 조명 원복 재사용 후보
상태 수집orca_status.pyGJC 상태 스트림 어댑터 추가
실행 루프indicator.py수신 큐와 렌더 주기를 분리
그룹 집계worktree_tracker.py워크트리 대신 세션·자식 계층 추적
키 입력·이동digit_hold.py / orca_navigation.py세션을 정확한 Orca pane에 연결

현재 키크론은 작업 중=노랑, 응답 대기=주황, 오류=빨강, 완료=초록, 혼합=자홍, 유휴=하늘색을 사용합니다. 현재 집계는 done + working을 done으로 표시합니다. 03의 소유 작업 전체 집계는 새로운 정책 제안입니다.

현재 macOS 입력 조건은 Orca가 앞에 있을 때의 Option+숫자입니다. 단순히 GJC 데이터 소스만 바꾸면 입력과 화면 이동의 연결까지 자동으로 바뀌지 않습니다.

30초 이해도 확인

메인이 끝났고 테스트 자식이 실행 중입니다.

‘소유 작업 전체 완료’를 알리는 초록색은 언제 켜야 할까요?

이 HTML에서 확실히 구분한 것

코드 사실이벤트 타입, 호출 경로, 파일과 SDK의 경계
설계 제안세션 가족 집계, RGB 우선순위, 관찰 어댑터
아직 확인하지 않은 것설치 버전의 실제 이벤트, 터미널 이동, 물리 키보드 E2E

코드 근거를 직접 열어 보기

모든 링크는 조사한 커밋으로 고정했습니다. 본문은 관련 실행 경로를 교차 조사한 해설이며 저장소 전체 파일의 전수 검증은 아닙니다.