Skip to content

0015. plan 템플릿과 규칙을 사용자 파일로 두고, 사이드바의 하네스 모드에서 고친다

This content is not available in your language yet.

“기본 틀” 방식의 plan 형식(유형별 섹션, R 번호, Status: 줄, 체크박스)은 코드에 박혀 있어 사용자가 바꿀 수 없었다. 형식의 원본도 둘이었다. 훅이 Claude에게 넣는 안내 문장(TEMPLATE_RULES)이 섹션을 풀어 설명했고, 앱이 worktree를 만들 때 쓰는 틀(planTemplates.ts)이 따로 있었다.

Belloga는 하네스를 주입하되 강제하지 않는 것을 목표로 한다. 사람마다 쓰는 틀이 다르므로 틀은 사용자가 정해야 한다. 다만 사용자의 하네스(~/.claude/)를 앱이 직접 고치면 그것을 건드리게 된다.

또 설치된 훅 스크립트는 문장을 글자 그대로 품고 있어서, 앱을 고쳐도 사용자가 스위치를 껐다 켜기 전까지 옛 안내가 나갔다.

템플릿의 원본을 ~/.belloga/agents/templates/의 사용자 파일로 옮긴다. 파일은 작업 유형별 requirements 네 개(requirements/{feature,bugfix,refactor,change}.md)와 design.md, tasks.md다. 앱 안에는 영어 기본값 md 한 벌만 두고, 없는 파일을 만들거나 기본으로 되돌릴 때만 쓴다.

  • 훅은 섹션 설명 대신 템플릿 폴더 경로와, 앱이 읽는 골격(type: 줄, R 번호, Status: 첫 줄, R 번호를 참조하는 체크박스)을 지키라는 문장을 넣는다. 파일 내용은 넣지 않는다.
  • 훅을 설치할 때 ~/.belloga/plans와 함께 ~/.belloga/agents/templates를 읽기 권한 폴더로 등록한다.
  • 앱을 켤 때 plan 훅이 설치되어 있으면 스크립트를 다시 쓰고 권한을 맞춘다. settings.json은 달라진 부분이 있을 때만 쓴다.
  • 앱을 켤 때, worktree를 만들 때, 하네스 모드를 열 때 없는 템플릿만 만든다. 있는 파일은 건드리지 않는다.

템플릿은 사이드바의 하네스 모드에서 고친다. 하네스 모드는 선택한 프로젝트와 상관없이 ~/.belloga/agents를 고정 루트로 보여 주고, 허용 목록(HARNESS_ROOTS)에 적은 폴더(rules, templates)만 보인다. 이 모드에서는 작업 영역의 탭 묶음을 숨기고 하네스 화면이 뜬다. 하네스 화면은 고른 파일의 역할 설명과 편집기를 보여 준다. templates는 수정과 기본으로 되돌리기만, rules는 규칙 만들기, 이름 바꾸기, 지우기까지 허용한다.

rules/의 규칙은 규칙 전용 SessionStart 훅이 본문을 넣는다. Belloga 터미널의 세션에서만 rules/*.md를 파일 이름 순서로 잇고, 앞에 “사용자 자신의 지시와 부딪히면 그쪽을 따르라”는 문장을 붙인다. frontmatter의 paths:는 떼어 내고 “다음 파일을 다룰 때만 적용한다”는 조건 문장으로 바꾼다. 규칙을 잇는 함수(buildRulesContext)는 src/shared의 순수 함수이고, 훅 스크립트에는 그 본문을 toString()으로 넣는다.

훅은 셋으로 나누고, 설정의 “Belloga 훅” 탭에서 따로 또는 한꺼번에 켜고 끈다. 세션 상태 훅, plan 훅, 규칙 훅이다. plan 훅과 규칙 훅은 같은 SessionStart 이벤트에 각자의 스크립트로 등록한다. 세션 상태 훅은 지금처럼 앱을 켤 때 자동으로 설치하고(0012), plan 훅과 규칙 훅은 사용자가 켤 때만 설치한다. 훅마다 등록하는 Claude Code 이벤트를 탭에 보여 준다.

0016에서 worktree 훅을 더해 훅이 넷이 되었다. plan 훅이 넣던 worktree 위치 문장은 worktree 훅으로 옮겼다.

  • ~/.claude/에 규칙과 틀을 직접 쓴다. 앱을 쓰지 않을 때도 사용자의 하네스가 바뀌어 다른 하네스와 부딪힌다(0007과 같은 문제). 기각했다.
  • 언어별 템플릿(ko, en)을 둔다. 사람이 읽는 문서라 앱 언어를 따르는 쪽이 자연스럽다. 그러나 언어가 늘수록 사용자가 관리할 파일이 배로 늘고, 앱 밖에서 도는 훅은 앱이 운영체제 언어로 정한 값을 알 수 없다. 영어 한 벌로 두고, 한국어 틀이 필요한 사용자는 자기 템플릿을 번역해 고치게 했다. 그 결과 ko 사용자의 worktree 미리 채우기도 영어 틀이 된다.
  • 기본값을 JSON에 담는다. 여러 줄짜리 마크다운이 \n 이스케이프로 바뀌어 읽고 고치기 어렵고 diff도 한 줄로 보인다. md 파일을 ?raw로 불러와 빌드에 넣었다.
  • 훅이 템플릿 본문을 넣는다. 확실하지만 SessionStart의 additionalContext는 1만 자에서 잘리고, 템플릿을 고칠 때마다 토큰이 늘어난다. 경로만 알리고 권한을 주어 Claude가 쓸 때 읽게 했다.
  • 안내 문장까지 실행할 때 파일에서 읽는다. 스크립트를 다시 쓰지 않아도 되지만, 스크립트와 테스트가 같은 문장을 내보낸다는 보장(스크립트가 상수를 글자 그대로 품는지 검사하는 테스트)이 깨진다. 고정 문장은 지금처럼 넣고, 바뀌는 것은 사용자 파일로 두었다. 옛 설치본은 앱을 켤 때 다시 쓰는 것으로 풀었다.
  • 설정 창에서 템플릿을 고친다. 설정 창은 파일을 열면 닫혀야 해서 고치는 동안 상태를 볼 수 없다. 하네스는 앱의 한 축이라 워크트리, 파일, git, 그래프와 나란히 둘 자리로 보고 사이드바 모드로 두었다.
  • 하네스 파일을 기존 탭 묶음에 연다. 탭 묶음의 열쇠는 연결한 프로젝트라서, 프로젝트가 없으면 열 자리가 없고 연결 목록을 새로 읽을 때 밖의 묶음이 지워진다. 탭 묶음을 숨기고 하네스 전용 화면을 띄웠다. 숨기기만 하므로 터미널과 세션은 끊기지 않는다.
  • 숨길 폴더를 고른다. 나중에 ~/.claude처럼 세션 기록과 인증 정보가 섞인 루트를 더하면 빠뜨린 것이 드러난다. 보일 폴더만 고르는 허용 목록으로 두었다.
  • 규칙을 Claude Code가 스스로 읽게 한다(.claude/rules/ 기본 로딩). paths: 조건이 실제 rules처럼 동작하고 1만 자 상한도 없다. claude -p로 실험해 보니 --add-dir 인자와 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1을 함께 줄 때만 추가 폴더의 규칙을 읽었고, 설정 파일의 permissions.additionalDirectories로 등록한 폴더는 환경 변수가 있어도 읽지 않았다. --add-dir은 사용자가 치는 명령의 인자라 claude 래퍼 없이는 넣을 수 없어 이번에는 기각했다. 래퍼를 들이면 다시 검토한다.
  • plan 안내와 규칙을 한 훅에 넣는다. 스크립트와 설정 항목이 하나로 줄지만, plan은 자기 하네스를 쓰고 규칙만 Belloga 것을 쓰는 조합을 막는다. 훅을 나누었다.
  • 규칙을 합치는 로직을 훅 스크립트에 따로 적는다. 스크립트는 다른 모듈을 가져올 수 없다. 따로 적으면 테스트한 코드와 실행되는 코드가 갈린다. 함수 본문을 toString()으로 넣고, 그 함수는 다른 모듈 값을 참조하지 않게 문장을 인자로 받는다. 빌드한 앱이 쓴 스크립트를 실행해 결과가 같은 것을 확인했다.
  • 관리 훅을 갱신할 때 지우고 뒤에 다시 붙인다(이전 동작). 같은 SessionStart에 관리 훅이 둘이 되자, 앱을 켤 때마다 두 갱신이 서로 순서를 바꿔 settings.json에 매번 썼다. 이미 있으면 제자리에서 바꾸게 했다.
  • 사용자가 템플릿을 고치면 다음에 Claude가 plan을 쓸 때와 앱이 worktree를 만들 때 바로 반영된다. 스크립트를 다시 설치하지 않아도 된다.
  • 앱이 켜질 때마다 ~/.claude/settings.json을 읽는다. 쓰는 것은 plan 훅이나 규칙 훅이 설치되어 있고 권한이나 명령이 달라졌을 때뿐이다.
  • 규칙은 세션을 시작할 때 한 번 들어가므로, paths: 규칙도 늘 컨텍스트에 있고 적용 여부는 AI가 판단한다. 규칙 전체가 1만 자를 넘으면 Claude Code가 넘는 부분을 파일로 빼므로 하네스 화면에서 경고한다.
  • 하네스 화면은 다른 파일을 고르거나 모드를 벗어날 때 고친 내용을 저장한다. 파일 탭과 달리 앱을 끌 때 저장하지 않은 변경을 묻지 않으므로, 고친 채 앱을 끄면 마지막 저장 뒤의 변경이 사라질 수 있다.
  • 사이드바를 접으면 하네스 화면도 사라지고 탭 묶음이 다시 보인다.
  • ~/.claude 표시와 claude 래퍼는 별도 작업으로 다룬다.