프로젝트 리소스
프로젝트에 GitHub 저장소나 로컬 디렉터리를 연결해 이후 실행에 안정적인 작업 컨텍스트를 제공합니다.
프로젝트 리소스는 이 작업 묶음에 어떤 코드가 필요하며 어디에서 실행할지 에이전트에게 알려 줍니다. 리소스는 프로젝트에 계속 연결되어 있으므로 각 이슈에 저장소 주소나 로컬 경로를 반복해서 붙여 넣을 필요가 없습니다.
현재 두 가지 리소스를 지원합니다.
| 리소스 | 적합한 경우 | 실행 위치 |
|---|---|---|
| GitHub 저장소 | 팀이 공유하는 코드베이스이며 런타임이 checkout을 관리해야 할 때 | 런타임이 관리하는 작업 디렉터리 |
| 로컬 디렉터리 | 이미 존재하는 checkout, 매우 큰 저장소, 로컬 변경 내용을 직접 확인해야 할 때 | 지정한 컴퓨터의 원본 디렉터리 |
리소스가 실행에 들어가는 방식
에이전트가 프로젝트 안의 이슈를 처리하면 Melso가 프로젝트 이름, 프로젝트 설명, 리소스 목록을 실행 컨텍스트에 추가하고 작업 디렉터리에 .multica/project/resources.json을 기록합니다.
워크스페이스에 연결된 저장소 목록은 항상 실행 컨텍스트에 포함됩니다. 프로젝트에 연결된 저장소는 그중 이 작업 묶음에서 사용할 코드와 기본 ref를 지정합니다.
로컬 디렉터리는 연결된 데몬에서만 유효합니다. 이번 실행을 담당한 데몬에 일치하는 로컬 디렉터리가 있으면 에이전트가 해당 디렉터리로 바로 들어가 작업합니다. 다른 컴퓨터에서는 프로젝트의 GitHub 저장소 또는 워크스페이스 저장소를 계속 사용합니다.
GitHub 저장소 추가
프로젝트를 열고 리소스에서 "리소스 추가"를 선택합니다. 워크스페이스에 이미 연결된 저장소를 고르거나 Git URL을 붙여 넣을 수 있습니다. 워크스페이스 저장소는 설정 → 코드 저장소에서 관리합니다. GitHub를 연결한 뒤 같은 페이지에서 GitHub에서 선택을 통해 App에 승인된 저장소를 가져올 수 있습니다.
저장소는 GitHub로 제한되지 않습니다. 런타임이 접근할 수 있는 Git URL이라면 모두 저장소 리소스로 사용할 수 있습니다. 자체 배포한 Melso에서는 설정 → 연동 → Git 코드 호스팅에서 자체 호스팅 Forgejo, Gitea, GitLab을 연결할 수도 있습니다. 자체 호스팅 Git 코드 호스팅을 참고하세요.
프로젝트를 만들 때 Repos에서 바로 저장소를 선택할 수도 있습니다. 하나의 프로젝트에 여러 GitHub 저장소를 연결할 수 있습니다.
리소스의 ref에는 이후 checkout에서 기본으로 사용할 브랜치, tag, commit을 지정할 수 있습니다. default_branch_hint는 에이전트에게 기본 브랜치 힌트만 제공하며 강제로 브랜치를 전환하지 않습니다.
로컬 디렉터리 추가
브라우저는 컴퓨터의 폴더를 선택할 수 없으므로 로컬 디렉터리 추가 화면은 Desktop에서만 제공됩니다.
이것은 비상구이지, 더 편리한 기본값이 아닙니다. local_directory는 다른 선택지가 없는 사람들을 위해 존재합니다 — 대표적인 사례는 체크아웃 하나가 수십 기가바이트인 게임 프로젝트로, 작업마다 다시 클론하는 것이 현실적으로 불가능한 경우입니다.
대상 디렉터리가 평범하게 클론할 수 있는 일반 git 저장소라면 대신 github_repo를 사용하세요: 기본적으로 워크트리 모드로 동작하므로 같은 저장소에 대한 작업을 무제한으로 동시에 실행할 수 있습니다. local_directory는 기본적으로 한 번에 하나의 작업만 실행합니다. 디렉터리 자체가 git 저장소라면 워크트리 모드를 켜서 동시 실행을 되찾을 수 있습니다(“작업이 디렉터리를 공유하는 방식” 참고). 결정하기 전에 위의 리소스 비교를 확인하세요.
- Desktop의 로컬 데몬이 온라인인지 확인합니다.
- 프로젝트의 리소스를 엽니다. 프로젝트 생성 대화상자의 로컬 디렉터리 탭에서도 프로젝트가 만들어지기 전에 같은 선택을 할 수 있습니다.
- "로컬 디렉터리 추가"를 선택한 뒤 사용할 폴더를 고릅니다.
- 작업이 그 폴더를 어떻게 사용할지 고릅니다 — 직접 또는 병렬이며, 차이는 "작업이 디렉터리를 공유하는 방식"에 설명되어 있습니다. 폴더가 git 저장소이고 그 기기의 런타임이 격리를 수행할 수 있으면 Desktop이 병렬을, 그렇지 않으면 직접을 미리 선택합니다. 그 자리에서 바꿀 수 있고, 나중에 리소스에서 디렉터리 옆 연필 아이콘으로도 바꿀 수 있습니다.
미리 선택은 지금 연결하는 디렉터리에만 적용됩니다. 이전에 연결한 디렉터리는 저장할 때의 모드를 그대로 유지합니다 — 기존 설정이 모르는 사이에 바뀌지 않습니다.
디렉터리는 절대 경로여야 하고 이미 존재해야 하며 현재 데몬이 읽고 쓸 수 있어야 합니다. 시스템 루트와 드라이브 루트(/, C:\), 사용자 홈 디렉터리 자체 및 각 홈 디렉터리의 상위 경로(/Users, /home, /root), 그리고 /etc, /var, /tmp, /usr, /opt 같은 시스템 디렉터리는 거부됩니다. 선택한 경로가 심볼릭 링크이면 실제 경로를 먼저 해석한 뒤 같은 규칙으로 다시 확인하며 직렬 잠금도 실제 경로를 기준으로 적용됩니다.
프로젝트 하나에는 같은 데몬에서 로컬 디렉터리를 최대 하나만 연결할 수 있습니다. 팀의 서로 다른 컴퓨터에서는 같은 프로젝트에 각자의 디렉터리를 연결할 수 있습니다.
기본값인 in_place 모드에서 로컬 디렉터리는 격리된 환경이 아닙니다. 에이전트가 현재 브랜치와 커밋하지 않은 파일을 직접 보고 수정하며, Melso는 브랜치 전환, stash, commit, push, PR 생성을 자동으로 수행하지 않습니다. 워크트리 모드는 이 점을 바꿉니다 — 아래 “작업이 디렉터리를 공유하는 방식”을 참고하세요.
작업이 디렉터리를 공유하는 방식
로컬 디렉터리에는 두 가지 실행 모드가 있으며 리소스별로 설정합니다. 리소스 패널에서 전환할 수 있고, CLI에서는 --execution-mode를 사용합니다. Desktop에서는 직접과 병렬로 표시하며, API와 CLI, 이 문서의 나머지 부분에서는 식별자를 사용합니다.
in_place(기본값) — "직접"
에이전트가 사용자의 디렉터리에서 직접 작업하며, 작업은 한 번에 하나씩 실행됩니다. 두 실행 태스크가 같은 실제 디렉터리를 사용하면 나중에 도착한 태스크가 waiting_local_directory 상태로 들어가 앞선 태스크가 디렉터리를 해제할 때까지 기다립니다. 서로 다른 심볼릭 링크 경로가 같은 디렉터리를 가리켜도 직렬로 실행됩니다.
기다리는 동안 디렉터리는 변경되지 않습니다. 대기 중인 태스크는 취소할 수 있으며 취소하지 않으면 디렉터리를 사용할 수 있을 때까지 계속 기다립니다.
worktree — "병렬"
각 작업이 저장소의 독립된 git 워크트리를 받으며, 워크트리는 런타임 자체의 작업 공간 디렉터리 안에 생성됩니다. 같은 디렉터리에 대한 작업들이 동시에 실행되고 어느 것도 대기하지 않으며, 어느 것도 사용자의 작업 사본에 쓰지 않습니다.
이 모드는 커밋이 하나 이상 있는 git 저장소를 요구합니다. 그렇지 않으면 조용히 직렬 실행으로 되돌아가는 대신 명시적인 오류로 실패합니다. 해당 머신의 런타임도 이 모드를 구현하고 있어야 합니다. 런타임은 연결할 때 그 기능을 선언하며, Melso는 버전 번호가 아니라 이 선언을 기준으로 판단합니다 — 개발 빌드는 구현이 전혀 없는 채로 충분히 새것처럼 보이는 버전 문자열을 가질 수 있기 때문입니다. 이 선언은 두 번 확인됩니다. 해당 머신의 런타임이 기능을 선언하지 않는 동안에는 리소스 저장이 거부되고 그 머신의 앱을 업데이트하라는 안내가 표시되며, 각 작업은 실제로 그것을 가져간 런타임을 기준으로 다시 확인됩니다 — 따라서 리소스를 저장한 뒤 다운그레이드된 머신에서는 작업이 조용히 제자리에서 실행되는 대신 이유와 함께 취소됩니다. worktree를 요청하는 것은 격리를 요청하는 것이며, 대신 작업 사본을 수정하는 것이 대체 동작이 되는 일은 없습니다.
에이전트가 보는 것과 사용자가 받는 것:
- 에이전트는
HEAD가 아니라 지금 보고 있는 상태에서 시작합니다. 커밋하지 않은 수정과 추적되지 않은 파일이 워크트리로 재현되므로, 더 이상 갖고 있지 않은 코드를 검토하지 않습니다. 사용자의 작업 사본, 인덱스, stash 목록은 절대 건드리지 않습니다. 그 상태를 충실히 재현할 수 없으면 — 재현 한도(2000개 파일 / 200 MiB)를 넘는 추적되지 않은 콘텐츠가 있는 경우 포함 — 알아볼 수 없는 트리에서 시작하는 대신 작업이 실패합니다. 보통은 아직 무시되지 않은 빌드 산출물을 gitignore에 추가하거나 정리하면 해결됩니다. - 결과물은 저장소 안의 브랜치이며 이름은
agent/<agent>/<task>형식입니다. 실행의 실행 세부 정보 패널에 브랜치 이름이 표시되고 복사할 수 있으며,git branch로도 찾을 수 있습니다.git log/git diff로 검토한 뒤 병합할지 cherry-pick할지 직접 결정합니다. Melso가 대신 병합하지 않습니다. 도중에 실패한 실행도 브랜치를 보고합니다. 에이전트가 만든 부분은 이미 커밋되어 있기 때문입니다. - 조용히 사라지는 것은 없습니다. 에이전트가 커밋하지 않고 남긴 변경 사항은 워크트리가 제거되기 전에 해당 브랜치로 커밋되며, 작업이 도중에 실패한 경우에도 마찬가지입니다. 드물게 그 커밋 자체를 할 수 없는 경우 — 예를 들어
commit.gpgSign이 켜져 있고 런타임이 서명 키를 사용할 수 없는 저장소 — 워크트리는 제거되지 않고 의도적으로 유지되며, 작업은 실패로 보고되고, 저장소에서git worktree list를 실행하면 해당 변경 사항이 있는 디렉터리를 확인할 수 있습니다. - 아무것도 변경하지 않은 작업은 아무것도 남기지 않습니다. 해당 브랜치는
git branch에 빈 항목으로 남지 않고 삭제됩니다.
워크트리는 런타임의 작업 공간 디렉터리 안에 있으므로 일반적인 정리 주기에 따라 회수되며, 저장소에는 브랜치만 남습니다.
셀프 호스팅 운영자 주의: 이 모드의 격리는 서버가 강제합니다(리소스 저장 시 한 번, 런타임이 각 작업을 가져갈 때 다시 한 번). 따라서 런타임을 언제 다운그레이드하더라도 차단됩니다. 유일하게 차단되지 않는 조합은 이 모드를 구현하지 않은 런타임이 연결된 상태에서 서버를 이 기능 이전 빌드로 롤백하는 것입니다 — 구버전 서버에는 이 게이트가 없고, 그런 런타임은 execution_mode를 무시한 채 작업을 원본 디렉터리에서 그대로 실행합니다. worktree 리소스가 존재하는 동안에는 해당 머신의 런타임이 모두 최신이 아닌 한 서버를 이 릴리스 이전으로 롤백하지 마십시오.
워크트리 모드는 git 저장소를 대상으로 합니다. git으로 관리되지 않는 일반 디렉터리는 계속 직렬로 실행됩니다 — 그것이 in_place의 역할입니다.
실행 중 기록되는 내용
에이전트가 만든 코드 변경 외에도 런타임이 현재 AI 코딩 도구에 필요한 지시 파일과 .multica/project/resources.json을 디렉터리에 기록할 수 있습니다. 버전 관리에 포함하고 싶지 않다면 .gitignore에 추가하세요.
Melso가 실행 환경을 정리할 때 연결된 로컬 디렉터리는 삭제하지 않습니다. 에이전트가 이 디렉터리에 만든 변경은 터미널에서 AI 코딩 도구를 직접 실행해 만든 변경과 성격이 같으므로 동일하게 검토해야 합니다.
CLI로 리소스 관리
# 프로젝트를 만들면서 저장소 연결
melso project create \
--title "Agent UX" \
--repo https://github.com/albertsalgueda/melso
# 리소스 확인 및 추가
melso project resource list <project-id>
melso project resource add <project-id> \
--type github_repo \
--url https://github.com/albertsalgueda/melso \
--ref main
# 지정한 데몬의 로컬 디렉터리 연결
melso project resource add <project-id> \
--type local_directory \
--local-path /absolute/path/to/repo \
--daemon-id <daemon-id>
# 로컬 git 저장소를 연결하고 작업을 각자의 워크트리에서 동시에 실행
melso project resource add <project-id> \
--type local_directory \
--local-path /absolute/path/to/repo \
--daemon-id <daemon-id> \
--execution-mode worktree
# 기존 로컬 디렉터리의 모드 전환
melso project resource update <project-id> <resource-id> --execution-mode worktree
melso project resource update <project-id> <resource-id> --execution-mode in_place
# 리소스 제거
melso project resource remove <project-id> <resource-id>리소스 변경은 이후 생성되는 실행 태스크에 적용되며 이미 끝난 실행 기록은 바꾸지 않습니다.