다른 언어: English, Español, Português, 日本語, Deutsch, Français, 简体中文, Italiano, हिन्दी · 한국어 가이드 전체
공개: 저희는 100monkeys.ai에서 Carbon Forge를 만들고 있으므로 이 글은 만든 쪽의 설명으로 읽어 주세요. 이 가이드는 저희 AI 에이전트 하나가 공개 문서(영어), 주로 Working in lanes와 Code and files on the substrate를 바탕으로 초안을 쓰고 회사가 검토했으며, 이 한국어판은 영어 원문 가이드의 번역입니다. 아래의 모든 호출은 문서 자체의 예시이고, 인용은 영어 원문 옆에 번역을 붙였습니다. 문서가 답하지 않은 질문은 마지막 절에서 밝힙니다.
왜 하나의 changeset인가
문서 홈은 단위를 이렇게 정의합니다. "A changeset is many writes landed as one: every page, atom, code tree and library entry it names is written in one transaction under one intent, the changeset's intent, or nothing is written"(changeset은 하나로 랜딩되는 여러 쓰기입니다. 그것이 지정하는 모든 페이지, atom, 코드 트리, 라이브러리 항목이 하나의 intent, 즉 changeset의 intent 아래 한 트랜잭션으로 쓰이거나, 아무것도 쓰이지 않습니다)(Welcome to Carbon). 코드와 글은 하나의 기록에 속한 엔티티이므로, 독자는 새 코드 옆에서 옛 페이지를 만나지 않고, 되돌리기도 둘을 함께 되돌립니다.
lane과 트리에 쓸 수 있는 토큰이 필요합니다. 문서가 이 작업에 지정하는 프리셋은 SCM agent입니다.
1단계. trunk가 보호되어 있는지 확인하기
workspaces.get_settings {}
→ { "workspaceId": "…", "trunkProtected": true, "trunkProtectedEntities": false } "With trunkProtected, code trees, library entries and changesets go through a lane; with trunkProtectedEntities as well, page and atom edits do too."(trunkProtected가 켜져 있으면 코드 트리, 라이브러리 항목, changeset이 lane을 거칩니다. trunkProtectedEntities까지 켜져 있으면 페이지와 atom 편집도 그렇습니다.) 어느 쪽이든 여기서는 lane이 맞는 모양입니다. 문서는 "a change should be seen whole before it lands"(변경을 랜딩하기 전에 전체로 봐야 할 때) lane을 씁니다.
2단계. 변경을 위한 lane 열기
lanes.create { "label": "agent/7/fix-login" } 레이블은 슬래시로 구분한 소문자 세그먼트이며, 열린 lane 사이에서 고유합니다. "A lane costs nothing to open and holds no copy, so one per task, or one per agent, is the expected use."(lane은 여는 데 비용이 없고 복사본을 갖지 않으므로, 작업마다 또는 에이전트마다 하나씩 쓰는 것이 기대되는 사용법입니다.) owner를 넘기면 그 lane에 쓰고, 충돌을 해결하고, 랜딩하는 일을 여러분만 할 수 있습니다.
3단계. lane에서 코드 바꾸기
trees.apply_patch { "path": "app", "operations": [ { "op": "patch", "entry_path": "src/login.ts", "old_string": "password", "new_string": "magicLink" } ], "intent": "fix: accept magic links", "lane": "agent/7/fix-login" } 레이블을 lane으로 넘기면 "the write is held on the lane as a patch against the trunk"(쓰기는 trunk에 대한 패치로 lane에 보관되고), "the trunk is not written"(trunk에는 쓰이지 않습니다). trees.apply_patch는 연산만 보냅니다(파일 안의 치환, 쓰기, 삭제, 이동). trees.put은 트리의 전체 항목 목록을 보냅니다. 어느 쪽이든 "the lane keeps only what differs."(lane은 달라진 것만 보관합니다.)
4단계. 같은 lane에서 그것을 설명하는 페이지 바꾸기
pages.apply_patch { "pathOrId": "guides/login", "old_string": "Sign in with a password.", "new_string": "Sign in with a magic link.", "lane": "agent/7/fix-login" } 같은 레이블이므로 페이지 편집이 코드 옆에서 기다립니다. 변경이 페이지 이름도 바꾼다면 pages.move도 lane을 받으며, "a rename belongs to the change that needs it."(이름 변경은 그것이 필요한 변경에 속합니다.) 스크린숏도 같은 방식으로 library.put_at_path와 레이블로 넣습니다.
5단계. lane이 만들 결과 읽기
읽기에 같은 lane을 넘기면 "the answer is the trunk as it stands now with the lane's patches applied, composed on the call"(답은 지금의 trunk에 lane의 패치를 적용해 호출 시점에 구성한 것입니다). 페이지는 pages.read로, 코드는 trees.get, trees.diff, trees.grep으로 읽습니다. 그런 다음 전체를 검토합니다.
lanes.diff { "label": "agent/7/fix-login" }
lanes.get { "label": "agent/7/fix-login" } lanes.diff는 "entity by entity, the trunk's section and the lane's"(엔티티별로 trunk의 섹션과 lane의 섹션)를 답하고, lanes.get은 패치, 충돌, 그리고 landable을 답합니다. "open, at least one live patch, no conflict."(열려 있고, 살아 있는 패치가 하나 이상이고, 충돌이 없음.) 앱에서는 /<workspace>/lanes/<label>이 같은 내용을 보여 주며, 바뀐 텍스트 파일마다 unified diff로 표시합니다. lanes.export를 읽고 그 composition 해시에서 승인한 검토자는 "has approved exactly that change."(정확히 그 변경을 승인한 것입니다.)
6단계. 충돌에 답하기
그 사이 누군가 trunk에서 페이지나 파일의 같은 줄을 고쳤다면 패치는 충돌 상태가 되고, "nothing merges by itself."(아무것도 저절로 병합되지 않습니다.) lanes.conflicts는 패치, 원래의 섹션, 지금 trunk의 섹션, 그리고 그것을 바꾼 changeset을 줍니다. lanes.resolve로 답하거나 lanes.drop_patch로 패치를 버리세요. 파일 안의 치환은 "replays on the trunk's current file, so two agents changing different parts of one file both land."(trunk의 현재 파일에 다시 적용되므로, 한 파일의 다른 부분을 바꾸는 두 에이전트는 둘 다 랜딩합니다.)
7단계. intent를 붙여 한 번에 랜딩하기
lanes.land { "label": "agent/7/fix-login", "intent": "fix: accept magic links", "dry_run": true }
lanes.land { "label": "agent/7/fix-login", "intent": "fix: accept magic links" } 먼저 dry run을 실행하고, 그다음 랜딩합니다. "Every live patch is replayed as one changeset whose intent is lane agent/7/fix-login: fix: accept magic links"(살아 있는 모든 패치가 intent가 lane agent/7/fix-login: fix: accept magic links인 하나의 changeset으로 다시 적용되고), 자체 트랜잭션 안에서 다시 검사되며, "refused whole, with every conflict named, if anything moved."(무엇이든 움직였다면 모든 충돌의 이름을 밝히며 통째로 거부됩니다.) intent를 feat, fix, docs, chore, revert로 시작하면 릴리스 노트가 그 단어 아래 묶습니다. idempotency_key를 보내면 타임아웃 뒤의 재시도는 "answers the first landing's result instead of landing twice."(두 번 랜딩하지 않고 첫 랜딩의 결과를 답합니다.)
8단계. 랜딩 결과 다시 읽기
/<workspace>/changes/<id>를 여세요. intent 전체, 실행자, 랜딩한 lane, 봉인, 그리고 항목들이 코드 파일과 페이지를 함께 보여 줍니다. 바뀐 줄의 blame은 이제 여러분이 쓴 intent로 답합니다. trees.blame은 "each line's revision, changeset, intent, actor and landing lane"(각 줄의 리비전, changeset, intent, 실행자, 랜딩 lane)을 줍니다(Code and files). 둘을 한 번에 되돌리려면 changesets.revert가 랜딩이 쓴 모든 엔티티를 복원하는 새 changeset 하나를 씁니다.
문서가 답하지 않는 것
- lane 없이 한 번의 호출로 하는 경로. lanes 가이드는
"targets": [ … ]를 넘기는changesets.apply를 보여 주지만 거기서 target의 모양을 설명하지 않으므로, 이 가이드는 lane을 씁니다. - 어떤 페이지가 어떤 코드를 설명하는지. 여기서는 그 연결을 만들지 않습니다. 그것을 선언하는 것이 governed seams의 역할입니다(아래 관련 가이드 참고).