rootr-cli 0.17.0 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ko.md ADDED
@@ -0,0 +1,811 @@
1
+ # rootr-cli
2
+
3
+ Rootr(마크다운 지식협업 SaaS) 공식 CLI + MCP 서버. 에이전트나 사람이 Rootr 문서를
4
+ 로컬 파일처럼 읽고/쓰고/검색할 수 있게 해줍니다.
5
+
6
+ - `rootr` CLI: `ls`, `read`, `write`, `append`, `edit`, `search`, `rm`, `attach`, `ws`, `ask`, `config`
7
+ - `rootr mcp`: stdio 기반 MCP 서버 (Claude Code / Claude Desktop 등에 등록해서 사용), 도구 90종+
8
+ — 문서·워크스페이스/스캐폴딩·LOG 데이터스토어·RCA ask·이슈·웹훅·첨부파일에 더해
9
+ 스프레드시트/화이트보드/폼/프레젠테이션/페이지/녹음/CRM/데이터베이스까지. 정확한 목록은 MCP `tools/list`로 확인하세요.
10
+
11
+ 순수 Node.js ESM, 빌드 과정 없음. Node 18 이상 필요(내장 `fetch` 사용).
12
+
13
+ ## 링크
14
+
15
+ - 소스: https://github.com/gwmage/rootr-cli
16
+ - npm: https://www.npmjs.com/package/rootr-cli
17
+ - 원격 커넥터(설치 없이 바로 연결): `https://rootr.io/mcp` — Claude Code/Desktop 등에서
18
+ 로컬 CLI 설치 없이 원격 MCP 엔드포인트로 바로 연결할 수 있습니다. 로컬 CLI(`rootr mcp`)와
19
+ 기능은 동일하며, 자체 인프라에 CLI를 두고 싶을 때만 이 저장소를 설치하면 됩니다.
20
+ - 라이선스: MIT (`LICENSE` 참고)
21
+
22
+ ## 설치
23
+
24
+ 이 저장소 안에서 바로 실행하거나, 전역 설치할 수 있습니다.
25
+
26
+ ```bash
27
+ cd cli
28
+ npm install
29
+
30
+ # 방법 1: 직접 실행
31
+ node bin/rootr.js --help
32
+
33
+ # 방법 2: 전역 설치 (심볼릭 링크로 rootr 명령 사용)
34
+ npm install -g .
35
+ rootr --help
36
+ ```
37
+
38
+ ## 설정
39
+
40
+ 우선순위: **환경변수 > `~/.rootr/config.json`**
41
+
42
+ | 환경변수 | 설정파일 키 | 설명 |
43
+ |---|---|---|
44
+ | `ROOTR_API_KEY` | `apiKey` | `rootr_...` 형태의 API 키. 모든 요청에 `x-api-key` 헤더로 전송됩니다. |
45
+ | `ROOTR_WORKSPACE` | `workspace` | 워크스페이스 id |
46
+ | `ROOTR_BASE_URL` | `baseUrl` | 기본값 `https://rootr.io/api/v1` |
47
+
48
+ 설정 파일에 저장하기:
49
+
50
+ ```bash
51
+ rootr config --api-key rootr_xxxxxxxxxxxxxxxx --workspace ws_123
52
+ # 필요하면 온프레미스/개발 서버용 base-url도 지정 가능
53
+ rootr config --api-key rootr_xxx --workspace ws_123 --base-url https://dev.rootr.io/api/v1
54
+ ```
55
+
56
+ `~/.rootr/config.json`은 `chmod 600`으로 생성됩니다.
57
+
58
+ ### 키 2종
59
+
60
+ Rootr API 키는 두 종류가 있고, 도구별로 요구하는 종류가 다릅니다.
61
+
62
+ - **워크스페이스 키**: 특정 워크스페이스 안에서만 동작. 스코프는
63
+ `docs:read`/`docs:write`/`graph:read`/`ask`/`webhooks:manage` 중 일부.
64
+ 대부분의 문서/LOG/이슈/웹훅/ask 도구는 이 키로 충분합니다.
65
+ - **계정 키 (PAT)**: 사용자 계정 전체로 동작. `workspaces:create` 스코프가 있으면
66
+ 새 워크스페이스를 만들 수 있습니다 (`rootr_create_workspace`). 워크스페이스 키로
67
+ 워크스페이스 생성을 시도하면 403과 함께 계정 키가 필요하다는 힌트가 출력됩니다.
68
+
69
+ 현재 설정 확인 (API 키는 앞 12자만 표시):
70
+
71
+ ```bash
72
+ rootr config
73
+ # config file: /home/you/.rootr/config.json
74
+ # apiKey: rootr_abcd...
75
+ # workspace: ws_123
76
+ # baseUrl: https://rootr.io/api/v1
77
+ ```
78
+
79
+ ## CLI 사용법
80
+
81
+ 경로 인자 규칙: `/`로 시작하면 **경로**로 취급되어 by-path API로 노드 id를 알아냅니다
82
+ (워크스페이스 설정 필요). `/`로 시작하지 않으면 **노드 id**로 취급합니다.
83
+
84
+ ### 트리 조회
85
+
86
+ ```bash
87
+ rootr ls # 전체 트리
88
+ rootr ls /notes # /notes 하위만
89
+ ```
90
+
91
+ 출력: `TYPE\tpath` 형식, 경로 정렬.
92
+
93
+ ### 문서 읽기
94
+
95
+ ```bash
96
+ rootr read /notes/todo.md # 마크다운 원문을 stdout으로
97
+ rootr read /notes/todo.md --json # 메타데이터 포함 JSON 전체
98
+ rootr read <nodeId> # id로도 가능
99
+ ```
100
+
101
+ ### 문서 쓰기 (전체 교체, 없으면 생성)
102
+
103
+ ```bash
104
+ echo "# 제목" | rootr write /notes/new.md
105
+ rootr write /notes/new.md --file ./local.md
106
+ rootr write <nodeId> --file ./local.md --if-match "\"abc123\"" # 낙관적 동시성 제어
107
+ ```
108
+
109
+ 경로가 아직 없으면 자동으로 문서를 생성합니다(`createParents: true`).
110
+ `--if-match`를 지정했는데 그 사이 문서가 바뀌었으면 412 오류와 함께
111
+ "문서가 그 사이 변경됨: 다시 읽고 재시도" 힌트가 출력됩니다.
112
+
113
+ ### 안전하게 추가 (append) — 충돌 걱정 없는 기본 수단
114
+
115
+ ```bash
116
+ rootr append /notes/log.md "오늘 배포 완료"
117
+ rootr append /notes/log.md "- 항목 하나 더" --heading "## 할 일"
118
+ cat diff.md | rootr append /notes/log.md
119
+ rootr append /notes/log.md --file ./chunk.md
120
+ ```
121
+
122
+ `--heading`을 지정하면 해당 헤딩 섹션 끝에 추가되고, 없으면 문서 끝에 추가됩니다.
123
+ append는 전체 내용을 다시 쓰지 않으므로 다른 프로세스와 동시에 써도 충돌하지 않습니다.
124
+
125
+ ### 텍스트 치환 (edit)
126
+
127
+ ```bash
128
+ rootr edit /notes/todo.md --find "- [ ] 배포" --replace "- [x] 배포"
129
+ rootr edit /notes/todo.md --find "TODO" --replace "DONE" --all
130
+ ```
131
+
132
+ `--find`한 텍스트가 없거나 여러 번 나타나면(고유하지 않으면) 서버가 409를 반환하고
133
+ 그 이유가 그대로 출력됩니다. `--all`을 주면 모든 일치 항목을 치환합니다.
134
+
135
+ ### 검색
136
+
137
+ ```bash
138
+ rootr search "배포 절차"
139
+ ```
140
+
141
+ 출력: `path — snippet` 목록.
142
+
143
+ ### 문서 삭제 (휴지통으로)
144
+
145
+ ```bash
146
+ rootr rm /notes/todo.md # 확인 후 삭제
147
+ rootr rm /notes/todo.md --yes # 확인 없이 (스크립트용)
148
+ ```
149
+
150
+ 휴지통으로 옮기는 **복구 가능한** 삭제입니다. 30일이 지나면 자동으로 완전 삭제됩니다.
151
+ 되돌리려면 `rootr restore <id>` — 화면에서 Ctrl+Z 를 누르는 것과 같은 일입니다.
152
+ **경로가 아니라 id** 입니다(휴지통에 든 것은 이미 트리에 없어 경로로는 못 찾습니다).
153
+ `rootr rm` 이 마지막 줄에 그 id 를 찍어 주니 그대로 쓰면 됩니다. MCP 로는
154
+ `rootr_restore_node`. `--yes` 없이 실행하면 확인을 묻습니다
155
+ (파이프/CI처럼 입력이 없는 환경에서는 "아니오"로 처리되어 안전합니다).
156
+ `docs:write` 스코프가 필요합니다.
157
+
158
+ ### 워크스페이스 목록 · 전환
159
+
160
+ ```bash
161
+ rootr ws # 목록 (현재 워크스페이스에 *, 못 여는 곳은 표시)
162
+ rootr use "영업팀" # 전환 — id · 이름 · rootr.io 주소 아무거나
163
+ ```
164
+
165
+ `rootr ws` 출력은 `id\tname` 목록입니다. 등록된 키가 워크스페이스 전용 키뿐이면 목록에는
166
+ 보이지만 열 수 없는 워크스페이스에 `[등록된 키로는 접근 불가]`가 붙습니다 — 목록에 보이는
167
+ 것과 접근되는 것은 다릅니다. `rootr use`는 그 워크스페이스를 여는 키를 골라 함께 기억합니다.
168
+
169
+ ### 워크스페이스 여러 개 쓰기 (키 등록 + 전환)
170
+
171
+ 워크스페이스마다 키가 다르면 한 번만 등록해 두세요:
172
+
173
+ ```bash
174
+ rootr config --add-key rootr_xxx --label "영업팀"
175
+ rootr config # 등록된 키 목록 확인
176
+ ```
177
+
178
+ 이후 MCP에서 `rootr_use_workspace` 도구로 **이름·id·루터 웹 주소** 중 아무거나 주면 활성
179
+ 워크스페이스가 바뀌고, 그 워크스페이스를 담당하는 키가 자동으로 선택·기억됩니다. 계정
180
+ 키(PAT)를 쓰면 소속된 어느 워크스페이스로든 바로 전환됩니다.
181
+
182
+ 워크스페이스 키는 자기 워크스페이스 밖에서는 열리지 않습니다 — `rootr ws`(=`rootr_workspaces`)
183
+ 목록에 보여도 접근은 안 되는 경우가 있어, 등록된 키가 워크스페이스 키뿐이면 목록에
184
+ `[등록된 키로는 접근 불가]`를 함께 표시합니다.
185
+
186
+ 문서를 가리키는 웹 주소(`https://rootr.io/ko/w/<ws>/d/<doc>`)는 `rootr_read` 등 모든 노드
187
+ 인자에 그대로 붙여넣을 수 있습니다. 다른 워크스페이스의 주소면 "먼저 전환하라"고 알려줍니다.
188
+
189
+ > 원격 커넥터(`https://rootr.io/mcp`)는 승인할 때 고른 워크스페이스 하나에만 연결됩니다.
190
+ > 다른 워크스페이스가 필요하면 그 워크스페이스로 커넥터를 새로 발급하세요.
191
+
192
+ ### 사용량 한도
193
+
194
+ 프로그램(API 키·MCP) 호출 중 **조회 계열**(`docs:read`/`graph:read`/`ask`)에만 한도가 있습니다.
195
+ 쓰기·업로드는 제한하지 않습니다.
196
+
197
+ | 플랜 | 한도 |
198
+ | --- | --- |
199
+ | Free | **하루 180회** (KST 자정 리셋) |
200
+ | Team | 시간당 5,000회 |
201
+ | Business | 시간당 50,000회 |
202
+ | Platform | 무제한 |
203
+
204
+ 한도의 80%를 쓰면 MCP 도구 응답 끝에 남은 횟수 안내가 붙고, 다 쓰면 429와 함께
205
+ 업그레이드 링크가 담긴 안내가 나옵니다. 응답 헤더로도 확인할 수 있습니다
206
+ (`X-RateLimit-Remaining`, `X-RateLimit-Reset`, `X-RateLimit-Window`).
207
+
208
+ ### 서명문서 · 연구노트 (sign)
209
+
210
+ 서명문서는 마크다운 문서인데 **올리는 순간 본문이 얼고**, 결재라인에 적힌 사람들이
211
+ 차례로 서명합니다. 서명마다 공인시점확인(TSA)과 해시 체이닝이 붙어 위·변조를
212
+ 증명할 수 있고, 서명된 문서는 삭제되지 않습니다(30년 보존).
213
+ 전자결재와 국가R&D 전자연구노트가 같은 기능 하나입니다.
214
+
215
+ ```bash
216
+ # 만들기 — 본문·결재라인까지 한 번에. 연구노트는 점검자만 정하면 두 단계가 자동
217
+ rootr sign new "/연구노트/2026-08-25 실험기록" --file note.md --reviewer <연구책임자 userId>
218
+
219
+ # 결재라인을 직접 짜려면 (배열 순서 = 서명 순서)
220
+ cat > line.json <<'EOF'
221
+ [ { "label": "기재자", "members": [{ "userId": "u1", "role": "AUTHOR" }] },
222
+ { "label": "부서장", "rule": "ANY", "members": [{ "userId": "u2" }, { "userId": "u3" }] } ]
223
+ EOF
224
+ rootr sign line /연구노트/2026-08-25\ 실험기록 --file line.json
225
+
226
+ # 올리기: 확인 코드를 메일로 받고 → 그 6자리를 넘긴다
227
+ rootr sign code /연구노트/2026-08-25\ 실험기록
228
+ rootr sign submit /연구노트/2026-08-25\ 실험기록 --code 123456
229
+
230
+ # 다음 사람: 내 차례인 것만 보고 → 서명 (또는 사유를 달아 반려)
231
+ rootr sign list --pending
232
+ rootr sign code <id> && rootr sign approve <id> --code 123456
233
+ rootr sign reject <id> --comment "근거 자료가 빠졌습니다" --code 123456
234
+
235
+ # 여러 건 한 번에 (코드 하나로 최대 100건)
236
+ rootr sign code --bulk
237
+ rootr sign bulk <id1> <id2> <id3> --code 123456
238
+
239
+ # 증명
240
+ rootr sign verify <id> # 본문·서명·시점확인·원장이 성한지
241
+ rootr sign ledger # 워크스페이스 원장 전체 재계산
242
+ ```
243
+
244
+ **확인 코드는 CLI가 대신 만들어 줄 수 없습니다.** 코드는 서명하는 사람 메일로만
245
+ 가고, 서버가 개인키를 보관하는 구조에서 그게 "본인이 눌렀다"의 유일한 증거입니다.
246
+ 10분 유효, 5회 틀리면 죽고, 30초 안에 다시 요청하면 거절됩니다.
247
+
248
+ 서명된 문서는 고치는 게 아니라 **개정본**을 냅니다(`rootr sign revise <id> --note "…"`).
249
+ 원본은 `SUPERSEDED`로 남습니다 — 지침이 "고친 흔적과 원본이 모두 보여야 한다"를
250
+ 요구하기 때문입니다.
251
+
252
+ ### 제보 보내기 (feedback)
253
+
254
+ ```bash
255
+ rootr feedback "행을 추가하려는데 rootr_add_row가 칸 이름을 못 찾는다고 합니다. 칸 id로 바꾸니 됐습니다." --kind friction
256
+ rootr feedback --file report.md --kind bug --email me@example.com
257
+ cat error.log | rootr feedback --kind bug
258
+ ```
259
+
260
+ 오류·불편·제안을 Rootr 팀에 보냅니다. **로그인도, 워크스페이스도, API 키도 필요
261
+ 없습니다** — 키가 틀려서 아무것도 못 하는 상태에서도 보내집니다(그 제보가 우리가
262
+ 제일 받고 싶은 제보입니다). 사용량 한도에도 걸리지 않고, 크레딧도 쓰지 않습니다.
263
+
264
+ `--kind`는 `bug`(안 되는 것) · `friction`(되지만 불편·헷갈림) · `idea`(있으면 좋겠다) ·
265
+ `praise` · `other` 중 하나이며, 생략하면 `other`입니다. `--title`을 안 주면 본문 첫
266
+ 줄이 제목이 됩니다. 답을 받고 싶을 때만 `--email`을 주세요.
267
+
268
+ 같은 사람이 10분 안에 같은 내용을 또 보내면 한 건으로 합칩니다 — 실패 재시도
269
+ 안에서 반복 호출해도 목록이 더러워지지 않습니다.
270
+
271
+ ### RCA 질의응답 (ask)
272
+
273
+ ```bash
274
+ rootr ask "지난주 배포 후 지연이 왜 늘었어?"
275
+ rootr ask "왜 결제 실패가 늘었지?" --workspace ws_123
276
+ ```
277
+
278
+ 워크스페이스의 지식그래프(GraphRAG)에 질문하고 답변 본문 + 인용(문서 경로: 인용문)을 출력합니다.
279
+ `ask` 스코프가 필요합니다. `--workspace`를 생략하면 설정된 기본 워크스페이스를 사용합니다.
280
+
281
+ ### 팀의 기억 (memory)
282
+
283
+ ```bash
284
+ rootr memory # 전체 회상 (상태·id·종류·출처)
285
+ rootr memory --query 세미나 --kind 지시 # 걸러서 보기
286
+ rootr memory add "보고 시각은 KST로만 표기한다" --kind 지시 --source /규칙.md
287
+ rootr memory edit <id> --content "고친 문장" # 그 기억만 고치기(준 칸만 바뀜)
288
+ rootr memory edit <id> --kind 참고 # 종류만 고치기
289
+ rootr memory forget <id> # 폐기(--hard면 행 삭제)
290
+ ```
291
+
292
+ 세션이 끝나도 남는, 워크스페이스 전체가 공유하는 한 줄 사실입니다. MCP의
293
+ `rootr_remember`/`rootr_recall`/`rootr_forget`과 같은 길을 터미널에서 쓰는
294
+ 명령이고, 화면의 "기억" 메뉴와도 같은 데이터를 봅니다. **긴 건 문서로, 한 줄은
295
+ 기억으로** — 자세한 규칙은 MCP 도구 설명을 참고하세요.
296
+
297
+ ## MCP 서버로 사용하기
298
+
299
+ `rootr mcp`는 stdio로 MCP(Model Context Protocol) 서버를 구동합니다. 제공 도구 167종:
300
+
301
+ 노드를 가리키는 인자(`target`, `databaseId`, `spreadsheetId`, `formId`, `crmId`, `trackerId`,
302
+ `recordingId`, `presentationId`, `whiteboardId`, `logId`, `parentId` 등)는 **노드 id와 경로를 모두**
303
+ 받습니다 — CLI와 같은 규칙으로 `/`로 시작하면 경로로 해석합니다.
304
+ 즉 `rootr_add_row`에 `databaseId: "/제작 공정/칸반"`을 그대로 넘길 수 있어,
305
+ 경로만 아는 에이전트가 uuid를 찾아 헤맬 필요가 없습니다.
306
+ `rootr_list`·`rootr_search` 출력도 각 줄 끝에 `[노드 id]`를 함께 표시합니다.
307
+
308
+ #### 문서 (workspace 키, docs:read/docs:write)
309
+
310
+ | 도구 | 설명 |
311
+ |---|---|
312
+ | `rootr_list` | 워크스페이스 트리 목록 |
313
+ | `rootr_read` | 문서 마크다운 읽기 |
314
+ | `rootr_append` | **(권장)** 문서에 안전하게 추가 — 충돌 불가능 |
315
+ | `rootr_edit` | 정확한 텍스트 스니펫 치환 |
316
+ | `rootr_write` | 문서 전체 교체(파괴적) 또는 신규 생성 |
317
+ | `rootr_search` | 워크스페이스 검색 |
318
+ | `rootr_comment_document` | 문서에 댓글 달기 |
319
+ | `rootr_list_document_comments` | 문서에 달린 댓글 목록 |
320
+ | `rootr_duplicate_node` | 노드 통째로 복제(하위까지) |
321
+ | `rootr_move_node` | 노드 옮기기 / 이름 바꾸기 |
322
+
323
+ 에이전트에게는 가능하면 `rootr_append`/`rootr_edit`을 우선 사용하고,
324
+ `rootr_write`는 정말 전체를 다시 쓸 때만 (가능하면 `ifMatch`와 함께) 쓰도록
325
+ 각 도구 설명에 명시되어 있습니다.
326
+
327
+ #### 첨부파일 (workspace 키, docs:write)
328
+
329
+ | 도구 | 설명 |
330
+ |---|---|
331
+ | `rootr_upload_attachment` | 로컬 파일(`filePath`) 또는 base64(`base64Data`)를 업로드하고 `{id, url, markdown}` 반환 |
332
+ | `rootr_attach_image_to_document` | 위 업로드 + 지정 문서에 `rootr_append`로 바로 삽입 (가장 흔한 용법) |
333
+
334
+ `url`은 `/attachments/{id}/raw` — 로그인 없이 렌더되는 공개 경로라 published(`/p/`) 문서에도
335
+ 그대로 쓸 수 있습니다. CLI에서는 `rootr attach <file> [--doc <path|id>] [--heading "## X"] [--alt <text>]`.
336
+
337
+ #### 워크스페이스 / 스캐폴딩
338
+
339
+ | 도구 | 필요 스코프 | 설명 |
340
+ |---|---|---|
341
+ | `rootr_workspaces` | 계정 키 또는 워크스페이스 키 | 내 워크스페이스 목록 |
342
+ | `rootr_scaffold_plan` | 워크스페이스 불필요 | 짓기 1단계 — 물어볼 것·설계 규칙·건축 자재 목록을 받는다 |
343
+ | `rootr_scaffold_review` | 워크스페이스 불필요 | 짓기 2단계 — **만들기 전에** 설계를 검사받는다(점수·고칠 곳). 컴파일러처럼 고쳐 가며 짓는다 |
344
+ | `rootr_create_workspace` | **계정 키(PAT) + workspaces:create** | 짓기 3단계 — 계획된 트리로 새 워크스페이스 생성(검사 결과도 같이 돌려준다) |
345
+ | `rootr_scaffold_apply` | docs:write | 짓기 3단계 — 기존 워크스페이스에 트리 적용(검사 결과도 같이 돌려준다) |
346
+ | `rootr_delete_workspace` | **계정 키(PAT) + OWNER** | 짓다 실패해 남은 **빈 워크스페이스 치우기**. 이름을 그대로 다시 적어야 지워진다(되돌릴 수 없음) |
347
+
348
+ 스캐폴딩은 **plan → 물어보기 → 설계 → review → 고치기 → apply** 한 바퀴입니다.
349
+ `review` 를 건너뛰면 "얇은 마크다운 파일 묶음"이 됩니다. CLI 로도 같은 세 단계를 쓸 수 있습니다:
350
+ `rootr scaffold plan "..."` / `rootr scaffold review --file tree.json` / `rootr scaffold apply --file tree.json`.
351
+
352
+ #### LOG 데이터스토어 (docs:read/docs:write)
353
+
354
+ | 도구 | 설명 |
355
+ |---|---|
356
+ | `rootr_create_log_store` | 타입드 LOG 스토어 생성 (필드: string/int/float/bool/datetime/json/enum/level/relation) |
357
+ | `rootr_update_log_fields` | 필드 스키마 갱신 — **전체 교체**(유지할 필드도 다시 보내야 함) |
358
+ | `rootr_add_log_entries` | 엔트리(행) 추가 |
359
+ | `rootr_query_log_entries` | 엔트리 조회/필터(시간범위·source·level·anomalyOnly) |
360
+ | `rootr_log_stats` | 집계 통계(hour/day/source/level × count/avg/max/min/sum) |
361
+
362
+ #### RCA 질의응답 (ask 스코프)
363
+
364
+ | 도구 | 설명 |
365
+ |---|---|
366
+ | `rootr_ask` | 지식그래프(GraphRAG)에 자연어 질문, 답변+인용 반환 |
367
+
368
+ #### 이슈 트래커 (docs:read/docs:write)
369
+
370
+ | 도구 | 설명 |
371
+ |---|---|
372
+ | `rootr_create_issue_tracker` | 이슈 트래커 생성 |
373
+ | `rootr_list_issues` | 이슈 목록(state/label/type/assignee/검색어 필터) |
374
+ | `rootr_create_issue` | 이슈 생성(labels/type/parentIssueId 지원) |
375
+ | `rootr_get_issue` | 이슈 상세 조회 |
376
+ | `rootr_update_issue` | 이슈 갱신(닫기: state=CLOSED + stateReason) |
377
+ | `rootr_comment_issue` | 이슈에 댓글 추가 |
378
+
379
+ #### 웹훅 (webhooks:manage 스코프)
380
+
381
+ | 도구 | 설명 |
382
+ |---|---|
383
+ | `rootr_list_webhooks` | 워크스페이스 웹훅 목록 |
384
+ | `rootr_create_webhook` | 웹훅 생성 — 응답의 secret은 **1회만 노출** |
385
+ | `rootr_delete_webhook` | 웹훅 삭제 |
386
+
387
+ #### 표(DATABASE) — 행과 열 (docs:read/docs:write)
388
+
389
+ | 도구 | 설명 |
390
+ |---|---|
391
+ | `rootr_read_database` | 스키마(열 정의)+행 전체 읽기 — **다른 표 도구를 쓰기 전에 먼저** (`includeBody: true` 면 행마다 상세 내용까지) |
392
+ | `rootr_list_rows` | 행만 조회(스키마 제외, `includeBody` 지원, `backlinks: true`면 "나를 가리키는 다른 표의 행"도 함께) |
393
+ | `rootr_add_row` | 행 추가 (`values`는 열 이름 또는 id로 지정, `body`로 상세 내용까지) |
394
+ | `rootr_update_row` | 행 수정 (칸반 카드 이동 = select 열 값 변경, `body`로 상세 내용 교체) |
395
+ | `rootr_bulk_create_rows` | 행 여러 개를 한 번에 추가 |
396
+ | `rootr_bulk_update_rows` | 여러 행을 **같은 값**으로 한 번에 수정 |
397
+ | `rootr_bulk_update_rows_each` | 여러 행을 **행마다 다른 값**으로 한 번에 수정 |
398
+ | `rootr_delete_row` | 행 삭제 |
399
+ | `rootr_bulk_delete_rows` | 행 여러 개를 한 번에 삭제 |
400
+ | `rootr_create_view` | 보기 추가 — 테이블/보드/캘린더/타임라인/갤러리 (달력은 `calendarScale`로 주·달·해) |
401
+ | `rootr_update_view` | 보기 수정 — 열 숨기기·이름·그룹·필터·정렬·열 너비·달력 단위(`calendarScale`) |
402
+ | `rootr_delete_view` | 보기 삭제 |
403
+ | `rootr_create_row_page` | 행에 상세 페이지 붙이기(문서 또는 서명문서) |
404
+ | `rootr_set_row_page_type` | 앞으로 만드는 행이 무엇으로 열릴지 정하기 |
405
+ | `rootr_unlink_row_page` | 행과 상세 페이지의 연결 끊기 |
406
+ | `rootr_add_column` | **열 추가** — 기존 열·행은 그대로 |
407
+ | `rootr_update_column` | 열 이름 변경 / select 선택지 교체 |
408
+ | `rootr_delete_column` | 열 삭제(파괴적) |
409
+ | `rootr_read_database_permissions` | 표에 걸린 자물쇠 보기 |
410
+ | `rootr_set_database_permissions` | 표 잠그기 — 칸·뷰 잠금 / 본인 행만 / 관리자만 고칠 칸 |
411
+ | `rootr_read_database_notifications` | 표 알림 규칙 보기 |
412
+ | `rootr_set_database_notifications` | 표 알림 규칙 저장 — 누구에게·언제·어떤 것만 |
413
+ | `rootr_list_database_buttons` | 표 위 **버튼** 목록 보기(고칠 수 있는지 `myLevel`도 함께) |
414
+ | `rootr_set_database_buttons` | 버튼 만들고 고치기 — **목록 통째로 교체**(남길 것도 같이 보내야 함) |
415
+ | `rootr_run_database_button` | 버튼 누르기 — 행 만들기·값 채우기·AI로 칸 채우기가 순서대로 |
416
+ | `rootr_list_document_commits` | 공개 문서에 온 변경 제안 목록 |
417
+ | `rootr_merge_document_commit` | 변경 제안 반영(세 벌 병합 — 덮어쓰기 아님) |
418
+ | `rootr_reject_document_commit` | 변경 제안 거절(사유는 제안자에게 전달) |
419
+ | `rootr_read_node_access` | 이 문서·폴더를 누가 볼 수 있는지(공개범위 + 따로 준 권한) |
420
+ | `rootr_set_node_visibility` | 비공개로 잠그기 / 상위 설정 따르기 |
421
+ | `rootr_grant_node_permission` | 한 사람(또는 그룹)에게 READ·WRITE·MANAGE 주기 |
422
+ | `rootr_revoke_node_permission` | 준 권한 거두기 |
423
+ | `rootr_update_form_response` | 이미 들어온 폼 응답 고치기(폼 검사 규칙 다시 통과) |
424
+ | `rootr_delete_form_response` | 폼 응답 한 건 삭제 |
425
+ | `rootr_create_form_collector` | 응답 모을 표·스프레드시트를 **만들어서** 연결(표는 질문 그대로 칸 생성) |
426
+
427
+ **표 버튼 — 매번 하는 준비 동작을 한 번에.** 새 건이 생길 때마다 상태=접수, 담당=나,
428
+ 마감=오늘+7 을 손으로 다시 채우는 일을 버튼 하나로 만듭니다. 단계는 **적힌 순서대로**
429
+ 돌고 **앞 단계가 만든 행을 뒤 단계가 받으므로**, "행을 만들고 → 그 행의 요약을 AI가 쓰고
430
+ → 그 행을 연다"가 한 번 누름으로 끝납니다. 값에는 `@today` · `@today+7` · `@me` 를 쓸 수
431
+ 있고 누르는 그 시점에 채워집니다. 버튼은 권한을 늘리지 않습니다 — **누른 사람 권한 그대로**
432
+ 돕니다(만들기·고치기는 관리자, 누르기는 편집 권한).
433
+
434
+ ```bash
435
+ rootr db buttons <표> # 지금 달린 버튼 보기
436
+ rootr db buttons <표> --file buttons.json # 목록 통째로 저장(남길 것도 같이)
437
+ rootr db button-run <표> <버튼id> # 한 번 누르기 (--rows id,id 로 고른 행 지정)
438
+ rootr db view <표> <뷰> --scale year # 달력 보기를 주·달·해 중에서
439
+ ```
440
+
441
+ ```json
442
+ [{ "label": "접수", "icon": "📥", "steps": [
443
+ { "kind": "add_row", "values": { "상태": "접수", "담당": "@me", "마감": "@today+7" } },
444
+ { "kind": "ai_fill", "target": "created", "propId": "요약", "prompt": "{제목}을 한 문장으로 요약해." },
445
+ { "kind": "open_row" }
446
+ ] }]
447
+ ```
448
+
449
+ 스캐폴드로 표를 지을 때도 `database.buttons` 에 같은 모양을 넣으면 **표와 함께** 달립니다.
450
+
451
+ **행에 댓글 달기.** 표의 한 행에 댓글을 달려면 `rootr_comment_document` 에 **표**를
452
+ `target` 으로, **행 id**를 `blockId` 으로 줍니다(읽기는 `rootr_list_document_comments`,
453
+ 명령줄은 `rootr comments <표> --block <행id>`). 상세 문서가 없는 행에도 달립니다.
454
+ `@[userId]` 로 사람을 부르면 알림이 가고, 그 알림은 **그 행**을 열면서 댓글을 짚어 줍니다.
455
+
456
+ **사람 칸은 여러 명을 담습니다.** 회의 참석자·공동 담당처럼 여럿이 들어가는 자리가
457
+ 흔해서, 값은 이름 목록(`["김대표","이팀장"]`)입니다. 이름 하나만 보내도 받아 주고
458
+ 목록으로 맞춰 돌려줍니다. 새로 들어온 사람에게만 알림이 갑니다.
459
+
460
+ **"만들면서 같이 잠그기".** 공개범위는 스캐폴드 트리에서도 노드마다 지정할 수 있습니다 —
461
+ `{ name: "채용", visibility: "PRIVATE", access: [{ subjectId: "<userId>", level: "READ" }] }`.
462
+ 폴더는 만들어 주면서 잠그는 건 사람이 따로 해야 하는 상태가 되지 않도록, 한 번에 갑니다.
463
+ 명령줄에서는 `rootr access <경로|id> --private`, `--grant <userId> --level READ`,
464
+ `--revoke <userId>` 입니다. (웹에 공개하는 것과는 다릅니다 — 그건 `rootr_set_document_public`.)
465
+
466
+ 응답 모을 곳은 `rootr form collect <폼> --to db|sheet`로 **만들면서** 연결합니다 —
467
+ 표로 만들면 폼 질문 그대로 칸이 생기므로, 표를 미리 만들고 칸 이름을 맞출 필요가 없습니다
468
+ (이름이 하나라도 어긋나면 그 칸은 영영 빈 칸으로 남습니다). 스캐폴드 트리에서는 폼 노드에
469
+ `form.collectInto: "database" | "spreadsheet"`로 같은 일을 합니다.
470
+
471
+ 폼 응답은 `rootr form responses <폼> [--latest]`로 보고, `rootr form response-edit <응답id>
472
+ --values '{"필드id":"값"}'`로 고치고, `rootr form response-rm <응답id> --yes`로 지웁니다.
473
+ `--latest`는 같은 사람이 여러 번 낸 것 중 마지막 한 건만 남깁니다(익명 제출은 합치지 않습니다).
474
+
475
+ 행의 **상세 내용(본문 메모)** — 화면에서 칸반 카드를 열면 속성 아래에 적는 그 글 — 은
476
+ `body`로 오갑니다. 실체는 표 밑에 달리는 문서 한 장이고, 없으면 쓸 때 만들어집니다.
477
+ 명령줄에서도 됩니다: `rootr db row-add <표> --values '{"제목":"킥오프"}' --body "..."`,
478
+ `rootr db row-body <표> <rowId> --file memo.md`, `rootr db rows <표> --body`.
479
+
480
+ 열은 **한 번에 하나씩** 다룹니다. REST의 `PATCH /databases/:id`는 `properties`
481
+ 배열을 통째로 교체하기 때문에, 에이전트가 배열을 다시 만들다 빠뜨린 열이 그대로
482
+ 사라집니다. 위 세 도구는 서버가 병합하므로 나머지 열이 없어지지 않습니다.
483
+
484
+ - **열을 추가해도 기존 행 데이터는 건드리지 않습니다** — 새 열은 값이 채워지기 전까지 빈 칸으로 읽힙니다.
485
+ - **열의 `type`은 바꿀 수 없습니다**(모든 행의 값을 다시 써야 하므로). 새 열을 만들어 값을 옮기세요.
486
+ - `title` 열은 추가로 만들 수도, 삭제할 수도 없습니다.
487
+ - 삭제한 열의 값은 행 안에 남아 있지만 화면에는 나오지 않습니다 — 사용자 확인 후 호출하세요.
488
+
489
+ #### 폼(FORM) — 받아 적는 창구 (docs:read/docs:write)
490
+
491
+ | 도구 | 설명 |
492
+ |---|---|
493
+ | `rootr_create_form` | 폼 만들기 — 질문 정의·응답 모을 표(`targetDatabaseId`)까지 한 번에 |
494
+ | `rootr_read_form` | 질문 정의와 설정 읽기 — **고치기 전에 먼저** |
495
+ | `rootr_update_form` | 질문·설정 수정(`config`는 아래 설명 참고) |
496
+ | `rootr_create_form_collector` | 응답 모을 표·스프레드시트를 **만들어서** 연결(표는 질문 그대로 칸 생성) |
497
+ | `rootr_list_form_responses` | 들어온 응답 목록 |
498
+ | `rootr_submit_form_response` | 응답 한 건 제출(사람 대신 넣어 줄 때) |
499
+ | `rootr_update_form_response` | 이미 들어온 응답 고치기(폼 검사 규칙 다시 통과) |
500
+ | `rootr_delete_form_response` | 응답 한 건 삭제 |
501
+ | `rootr_create_form_share_link` | 폼 전용 공유 링크 발급(`/f/<토큰>`) |
502
+ | `rootr_list_form_share_links` | 발급된 공유 링크 목록 |
503
+
504
+ 폼을 밖에 여는 정상 경로는 **`rootr_publish_node`** 입니다 — 발행하면 `/p/<슬러그>`
505
+ 주소가 나오고 **응답 받기도 같이 켜집니다**. `config.publicSubmit`을 손으로 만질 일은
506
+ 거의 없고, 그만 받고 싶으면 `closesAt`·`maxResponses`를 걸거나 발행을 내리세요.
507
+ `config.theme`은 `clean`·`paper`·`noir`·`ocean`·`sunset`·`mint`·`bento`·`brutal`·
508
+ `vivid`·`dark` 10종이며, `cover`/`logo`는 이미지 **주소**라 `rootr_upload_attachment`로
509
+ 먼저 올리고 받은 url을 넣습니다(비워 두면 기본 커버가 붙습니다).
510
+
511
+ #### 웹에 공개 발행 (docs:write)
512
+
513
+ | 도구 | 설명 |
514
+ |---|---|
515
+ | `rootr_publish_node` | **아무 노드나** 공개 — 문서·표·폼·시트·화이트보드·덱, 하위까지 |
516
+ | `rootr_set_node_public` | 이미 공개한 것의 설정 변경(하위 포함 여부·검색 노출·만료) |
517
+ | `rootr_node_public_status` | 지금 공개돼 있는지, 주소는 무엇인지 |
518
+ | `rootr_publish_document` | 문서 전용 발행(구형 — 새로 짤 때는 `rootr_publish_node`) |
519
+ | `rootr_set_document_public` | 문서 전용 공개 설정 변경 |
520
+ | `rootr_document_public_status` | 문서 전용 공개 상태 |
521
+
522
+ #### 스프레드시트 (docs:read/docs:write)
523
+
524
+ | 도구 | 설명 |
525
+ |---|---|
526
+ | `rootr_create_spreadsheet` | 스프레드시트 만들기(시트 여러 장 가능) |
527
+ | `rootr_read_spreadsheet` | 시트·셀·수식 읽기 |
528
+ | `rootr_patch_spreadsheet_cells` | **(권장)** 셀 값·수식만 콕 집어 쓰기 |
529
+ | `rootr_update_spreadsheet` | 설정·아이콘 변경, 또는 시트 전체 교체(파괴적) |
530
+ | `rootr_create_sheet` | 시트(탭) 추가 |
531
+ | `rootr_update_sheet` | 시트 한 장 이름 변경·크기 조정 |
532
+ | `rootr_delete_sheet` | 시트(탭) 삭제 |
533
+
534
+ #### 화이트보드 (docs:read/docs:write)
535
+
536
+ | 도구 | 설명 |
537
+ |---|---|
538
+ | `rootr_create_whiteboard` | 화이트보드 만들기 |
539
+ | `rootr_read_whiteboard` | 도형·연결선 읽기 |
540
+ | `rootr_update_whiteboard` | 장면 교체 또는 병합(merge), 설정·아이콘 |
541
+
542
+ #### 녹음 · 회의록 (docs:read/docs:write)
543
+
544
+ | 도구 | 설명 |
545
+ |---|---|
546
+ | `rootr_create_recording` | 녹음 노드 만들기 |
547
+ | `rootr_upload_recording_audio` | 오디오 올리기(올리면 받아쓰기가 시작됩니다) |
548
+ | `rootr_transcribe_recording` | 받아쓰기 실행/재실행 |
549
+ | `rootr_read_recording` | 받아쓴 글·화자 구간 읽기 |
550
+ | `rootr_rename_recording_speakers` | 화자 이름 바꾸기(화자1 → 김대표) |
551
+ | `rootr_summarize_recording` | 요약·회의록 만들기 |
552
+ | `rootr_download_recording_audio` | 원본 오디오 내려받기 |
553
+
554
+ #### CRM (docs:read/docs:write)
555
+
556
+ | 도구 | 설명 |
557
+ |---|---|
558
+ | `rootr_crm_create` | CRM 노드 만들기(파이프라인·칸 정의) |
559
+ | `rootr_crm_get` | 파이프라인·칸·건수 보기 |
560
+ | `rootr_crm_update` | 파이프라인·칸·설정 수정 |
561
+ | `rootr_crm_list_companies` / `rootr_crm_get_company` | 회사 목록 / 상세(연락처·딜·활동·할 일) |
562
+ | `rootr_crm_upsert_company` | 회사 추가·수정·삭제 |
563
+ | `rootr_crm_list_contacts` / `rootr_crm_get_contact` | 연락처 목록 / 상세 |
564
+ | `rootr_crm_upsert_contact` | 연락처 추가·수정·삭제 |
565
+ | `rootr_crm_list_deals` / `rootr_crm_get_deal` | 딜 목록 / 상세 |
566
+ | `rootr_crm_upsert_deal` | 딜 추가·수정·삭제 |
567
+ | `rootr_crm_move_deal` | 딜을 다음 칸으로 옮기기(칸반 카드 이동) |
568
+ | `rootr_crm_log_activity` / `rootr_crm_list_activities` | 활동 기록 남기기 / 타임라인 조회 |
569
+ | `rootr_crm_upsert_task` / `rootr_crm_list_tasks` | 후속 할 일 만들기·수정 / 목록 |
570
+ | `rootr_crm_import` | 여러 건 한 번에 가져오기 |
571
+
572
+ #### 템플릿 (docs:read/docs:write)
573
+
574
+ | 도구 | 설명 |
575
+ |---|---|
576
+ | `rootr_list_templates` | 문서·표 템플릿 목록 |
577
+ | `rootr_apply_template` | 템플릿으로 노드 만들기 |
578
+ | `rootr_save_as_template` | 지금 노드를(또는 즉석 정의를) 템플릿으로 저장 |
579
+ | `rootr_update_template` | 템플릿 수정 |
580
+
581
+ #### 기억 (docs:read / docs:write)
582
+
583
+ | 도구 | 설명 |
584
+ |---|---|
585
+ | `rootr_remember` | 한 줄 사실을 기억시키기(같은 내용이면 갈아끼움). `memoryId`를 함께 주면 그 기억을 그 자리에서 고치기 |
586
+ | `rootr_recall` | 이 워크스페이스가 아는 것 꺼내 오기 |
587
+ | `rootr_forget` | 더 이상 맞지 않는 기억 폐기 |
588
+
589
+ **에이전트에게**: 이건 세션이 끝나도 남는, **워크스페이스 전체가 공유하는** 기억입니다
590
+ (개인 메모는 여기 두지 말고 자기 메모리에 두세요). **긴 건 문서로, 한 줄은
591
+ 기억으로, 그리고 기억은 반드시 문서를 가리키게** 하세요 — 이야기를 기억에 밀어
592
+ 넣으면 기억이 "짧은 문서 더미"가 되면서 둘 다 망합니다. 규칙·결정한 이유·한 번
593
+ 겪은 함정을 남기고, 그 근거가 된 문서 경로를 `source`로 같이 주세요(그래야 그
594
+ 문서가 바뀔 때 루터가 "확인 필요" 표시를 답니다).
595
+
596
+ 기억은 워크스페이스를 처음 만질 때 **도구 응답에 자동으로 딸려옵니다** — 굳이
597
+ `rootr_recall`을 먼저 부르지 않아도 눈앞에 놓입니다. 이 자동 회상은 무료 조회
598
+ 한도를 쓰지 않습니다.
599
+
600
+ 사람이 직접 보고 고치려면 워크스페이스 왼쪽 메뉴의 **기억**에서 볼 수 있고,
601
+ "표로 열기"를 누르면 평범한 표로 열려 권한·기록이 그대로 따라옵니다.
602
+
603
+ #### 제보 (인증 불필요)
604
+
605
+ | 도구 | 설명 |
606
+ |---|---|
607
+ | `rootr_send_feedback` | 오류·불편·제안 보내기 — 키가 없거나 틀려도 들어갑니다 |
608
+
609
+ **에이전트에게**: 이 도구는 시켜야 부르는 도구가 아닙니다. 일하다가 예상 못 한
610
+ 오류를 만나거나, 도구가 설명과 다르게 동작하거나, 우회를 하게 되거나, 사용자가
611
+ "이거 안 된다/헷갈린다"고 말하면 **묻지 말고 그 자리에서 한 번 보내고** 하던 일을
612
+ 계속하세요. 도구 설명에도 같은 말이 적혀 있습니다. 같은 문제로 두 번 보내지 마세요
613
+ (10분 내 같은 내용은 자동으로 합쳐집니다).
614
+
615
+ #### 읽음 확인 (docs:read/docs:write)
616
+
617
+ | 도구 | 설명 |
618
+ |---|---|
619
+ | `rootr_set_read_requirement` | 이 문서를 반드시 읽게 하기(대상·기한) |
620
+ | `rootr_read_requirement` | 누가 읽었고 누가 안 읽었는지 |
621
+ | `rootr_clear_read_requirement` | 읽음 요구 해제 |
622
+
623
+ #### 서명문서 · 연구노트 (docs:read/docs:write)
624
+
625
+ | 도구 | 설명 |
626
+ |---|---|
627
+ | `rootr_create_signed_document` | 서명문서 만들기 — 본문·모드·결재라인까지 한 번에 |
628
+ | `rootr_read_signed_document` | 결재라인 진행·서명 목록·내 차례인지(`canSign`) |
629
+ | `rootr_set_approval_line` | 결재라인 다시 짜기 (올리기 전에만) |
630
+ | `rootr_apply_research_note_preset` | 연구노트로 전환 + 기재자→점검자 두 단계 자동 |
631
+ | `rootr_request_signing_code` | 확인 코드를 서명자 메일로 발송 (서명 전 필수) |
632
+ | `rootr_submit_signed_document` | 올리기 — 본문이 얼고 기안자가 첫 서명 |
633
+ | `rootr_sign_document` | 내 차례에 서명 |
634
+ | `rootr_reject_signed_document` | 반려 (사유 필수) |
635
+ | `rootr_reopen_signed_document` | 아무도 서명 안 한 초안 다시 열기 |
636
+ | `rootr_revise_signed_document` | 개정본 만들기 (원본은 남는다) |
637
+ | `rootr_verify_signed_document` | 위변조 검증 — 본문·서명·시점확인·원장 |
638
+ | `rootr_list_signed_documents` | 목록 (`pendingMine`: 내 차례인 것만) |
639
+ | `rootr_bulk_sign_documents` | 코드 하나로 최대 100건 묶음 서명 |
640
+ | `rootr_verify_ledger` | 워크스페이스 원장(해시 체인) 전체 재계산 |
641
+
642
+ 에이전트가 대신 눌러 줄 수 없는 자리가 하나 있습니다 — **서명**. 확인 코드는
643
+ 사람 메일로만 가므로 흐름은 항상 `rootr_request_signing_code` → 사람에게 6자리를
644
+ 물어봄 → `rootr_sign_document` 입니다. 코드를 지어내면 403이고, 5회 틀리면 코드가
645
+ 죽습니다.
646
+
647
+ 표의 행마다 서명문서를 붙이려면 `rootr_create_database`에 `rowPageType: "SIGNED"`를
648
+ 주세요 — 그 표는 행을 열 때마다 서명문서(연구노트)가 만들어집니다(실험 기록 대장,
649
+ 점검 대장).
650
+
651
+ #### 문서 버전 / 삭제
652
+
653
+ | 도구 | 설명 |
654
+ |---|---|
655
+ | `rootr_document_versions` | 문서 버전 히스토리 조회 |
656
+ | `rootr_read_document_version` | 그 시점 본문을 그대로 읽기(되돌리기 전에 확인용) |
657
+ | `rootr_restore_document_version` | 문서를 예전 버전으로 되돌리기 |
658
+ | `rootr_update_node` | 아무 노드나 이름·아이콘 변경 / 옮기기 |
659
+ | `rootr_delete_node` | 노드를 휴지통으로 이동(복구 가능) |
660
+
661
+ #### 페이지 (웹페이지)
662
+
663
+ 페이지(PAGE)는 **바깥 사람이 볼 화면**입니다 — 행사 안내·제품 소개·신청 받기처럼
664
+ 링크 하나로 보여 줄 것. 전용 MCP 도구(`rootr_create_page`, `rootr_read_page`,
665
+ `rootr_append_page_blocks`, `rootr_update_page`, `rootr_update_page_block`,
666
+ `rootr_read_page_live_data`)로 저작합니다.
667
+
668
+ HTML을 짜는 것이 아니라 **정해진 블록 14종을 골라 쌓습니다** — `hero` `text`
669
+ `features` `gallery` `pricing` `testimonials` `faq` `timeline` `cta` `footer` +
670
+ 표에서 값을 끌어오는 `liveStats` `liveTable` `liveChart` + 신청을 받는 `form` + 자유 블록 `custom`.
671
+
672
+ `custom`은 **격리된 방**입니다: HTML/CSS를 마음대로 쓰되 `sandbox` 아이프레임 안에서만
673
+ 그려집니다(스크립트 없음·같은 출처 아님·바깥 통신 차단). 그래서 대담한 CSS도 바깥 화면을
674
+ 못 덮습니다 — 저장할 때 `<script>`와 `on*=`는 지워집니다. 방 안에서는 페이지 분위기 색을
675
+ `var(--pg-text)` `var(--pg-card)` `var(--pg-accent)` 처럼 쓸 수 있습니다.
676
+ 블록별 props는 **`/llms.txt`의 "Pages" 섹션**에 표로 정리돼 있습니다.
677
+
678
+ ```bash
679
+ # 페이지 만들기 (블록을 생략하면 hero/text/footer 뼈대로 시작)
680
+ curl -X POST "$BASE/workspaces/$WS/pages" -H "x-api-key: $KEY" \
681
+ -H 'Content-Type: application/json' \
682
+ -d '{"name":"가을 행사","config":{"theme":"midnight"},
683
+ "blocks":[{"type":"hero","props":{"title":"가을 개발자 밋업","subtitle":"10월 12일 · 서울"}}]}'
684
+
685
+ # 블록 덧붙이기(있는 블록은 그대로) / 통째 교체 / 라이브 값 확인
686
+ curl -X POST "$BASE/pages/$ID/blocks" -d '{"blocks":[{"type":"faq","props":{"items":[...]}}]}' ...
687
+ curl -X PATCH "$BASE/pages/$ID" -d '{"config":{"theme":"warm"}}' ...
688
+ curl "$BASE/pages/$ID/live-data" -H "x-api-key: $KEY"
689
+ ```
690
+
691
+ `liveStats`/`liveTable`/`liveChart`의 `source.nodeId`는 같은 워크스페이스의
692
+ DATABASE·LOG 노드이고, 칸은 **이름**으로 가리킵니다(칸 id가 아닙니다).
693
+ `form` 블록의 `formNodeId`에 폼 노드를 걸면 방문자가 **그 자리에서 신청**합니다 —
694
+ 폼을 따로 공개할 필요가 없습니다. 비공개(PRIVATE) 서브트리에 있는 표·폼은 공개
695
+ 페이지에서 조용히 빠집니다(일부러 그렇습니다).
696
+
697
+ 공개는 여느 노드와 같습니다: `POST /v1/nodes/:id/publish` → `rootr.io/p/{slug}`.
698
+
699
+ #### 프레젠테이션
700
+
701
+ 프레젠테이션(PRESENTATION)은 전용 MCP 도구(`rootr_create_presentation`,
702
+ `rootr_read_presentation`, `rootr_append_presentation_slides`,
703
+ `rootr_update_presentation_slide`, `rootr_reorder_presentation_slides`,
704
+ `rootr_update_presentation`)로 저작합니다. 슬라이드에 넣을 그림은
705
+ `rootr_generate_image`(문장으로 이미지 생성)와 `rootr_remove_image_background`(배경 지우기)로
706
+ 만들 수 있습니다 — 둘 다 AI 크레딧을 씁니다. 아래처럼 **같은 API 키로 REST를 직접
707
+ 호출**해도 됩니다 (`x-api-key` 헤더, `docs:write`):
708
+
709
+ ```bash
710
+ # 덱 생성 (슬라이드 포함 가능)
711
+ curl -X POST "$BASE/workspaces/$WS/presentations" -H "x-api-key: $KEY" \
712
+ -H 'Content-Type: application/json' \
713
+ -d '{"name":"제안서","slides":[{"id":"SLD-001","kind":"cover","title":"..."}]}'
714
+
715
+ # 슬라이드 부분 수정(머지) / 추가 / 순서 변경
716
+ curl -X PATCH "$BASE/presentations/$ID/slides/SLD-001" -H "x-api-key: $KEY" \
717
+ -H 'Content-Type: application/json' -d '{"slide":{"notes":"발표 대본"}}'
718
+ curl -X POST "$BASE/presentations/$ID/slides" -d '{"slides":[...]}' ...
719
+ curl -X POST "$BASE/presentations/$ID/reorder" -d '{"order":["SLD-002","SLD-001"]}' ...
720
+ ```
721
+
722
+ ##### 슬라이드에 다이어그램 그려 넣기
723
+
724
+ 구조도·업무 흐름도·순서도·데이터 흐름도·상태도는 손으로 SVG를 짜지 말고
725
+ `rootr_create_diagram_slide`에 **형식이 정해진 JSON 스펙**을 넘기세요. 서버가
726
+ 검증하고 그려서 슬라이드에 바로 꽂습니다 — 화면은 물론 PDF·PPTX 내보내기에도
727
+ 그대로 나옵니다. 슬라이드의 `diagram`(mermaid) 필드는 **뷰어가 그리지 않으므로**
728
+ 이 도구를 쓰는 것이 유일한 방법입니다.
729
+
730
+ 종류마다 스펙 모양이 다르니 **`rootr_diagram_schema`로 스키마와 예제를 먼저
731
+ 받아보세요.** 맞지 않는 스펙은 어느 항목이 왜 틀렸는지와 고치는 법을 달아 거절되니,
732
+ 그대로 고쳐 다시 부르면 됩니다.
733
+
734
+ ```bash
735
+ # 스펙 모양 보기 (architecture | workflow | sequence | dataflow | lifecycle)
736
+ curl "$BASE/diagram-types/workflow/schema" -H "x-api-key: $KEY"
737
+
738
+ # 그려서 슬라이드에 꽂기 (slideId를 주면 그 슬라이드를 다시 그린다)
739
+ curl -X POST "$BASE/presentations/$ID/diagram-slides" -H "x-api-key: $KEY" \
740
+ -H 'Content-Type: application/json' \
741
+ -d '{"type":"workflow","spec":{...},"title":"이슈는 검수를 통과해야만 main에 들어간다",
742
+ "blocks":[{"heading":"검수가 관문","body":"..."}]}'
743
+ ```
744
+
745
+ `quality`는 기본 `standard`이고, `showcase`는 손으로 다듬은 대표 그림용 엄격
746
+ 기준이라 `standard`가 통과시키는 스펙도 거절합니다. 그림 속 글자는 지식 그래프에
747
+ 들어가지 않으니 사실은 `title`·`blocks`·`notes`에도 남기세요.
748
+
749
+ **고품질 덱을 만들 때는 슬라이드 `html` 필드에 1280×720 완결 HTML을 직접 구워
750
+ 넣는 방식을 권장**합니다 — 뷰어가 기본 템플릿 대신 그대로 렌더합니다(완전 자유
751
+ 디자인). 필수 규칙(외부 요청 차단이라 전부 인라인, 이미지=data URI 내장, 폰트
752
+ 폴백 스택, `<span class="pn">`=페이지번호, 그래프용 텍스트(title/blocks/notes/alt)
753
+ 병행 유지)은 **`/llms.txt`의 "Presentations" 섹션**에 정리돼 있습니다 — 저작 전에
754
+ 꼭 읽어보세요. AI 이미지 생성은 `POST /v1/workspaces/:ws/images/generate`(AI
755
+ 크레딧 차감)를 사용합니다.
756
+
757
+ 모든 도구 설명은 영어(에이전트가 소비하는 스키마)로 작성되어 있고, JSON을 반환하는
758
+ 도구는 보기 좋게 들여쓴 JSON 텍스트로 응답합니다. `workspace` 인자를 받는 도구는
759
+ 생략 시 `ROOTR_WORKSPACE`/설정파일의 기본 워크스페이스를 사용하며, 그것도 없으면
760
+ 명확한 에러를 반환합니다.
761
+
762
+ ### Claude Code / Claude Desktop에 등록하기
763
+
764
+ `~/.claude.json`(Claude Code) 또는 Claude Desktop의 MCP 설정 파일에 다음을 추가:
765
+
766
+ ```json
767
+ {
768
+ "mcpServers": {
769
+ "rootr": {
770
+ "command": "node",
771
+ "args": ["/path/to/rootr/backend/cli/bin/rootr.js", "mcp"],
772
+ "env": {
773
+ "ROOTR_API_KEY": "rootr_xxxxxxxxxxxxxxxx",
774
+ "ROOTR_WORKSPACE": "ws_123"
775
+ }
776
+ }
777
+ }
778
+ }
779
+ ```
780
+
781
+ 전역 설치했다면 `command`를 `"rootr"`, `args`를 `["mcp"]`로만 써도 됩니다.
782
+
783
+ ## 에러 처리
784
+
785
+ API가 비-2xx를 반환하면 응답 본문의 `message`(있으면)를 stderr에 출력하고
786
+ exit code 1로 종료합니다. 상황별 힌트:
787
+
788
+ - `401`/`403` → API 키/워크스페이스 스코프 확인 안내
789
+ - `412` → "문서가 그 사이 변경됨: 다시 읽고 재시도" 안내 (If-Match 불일치)
790
+ - `409` → 서버가 준 이유 메시지를 그대로 표시 (예: edit의 find 불일치/중복)
791
+
792
+ ## 개발 메모
793
+
794
+ - 의존성: `@modelcontextprotocol/sdk`(MCP 서버), `zod`(도구 입력 스키마).
795
+ CLI 자체(`bin/rootr.js`, `lib/config.js`, `lib/client.js`, `lib/resolve.js`)는
796
+ 외부 의존성 없이 동작합니다.
797
+ - 빌드 스텝 없음 — 순수 ESM 자바스크립트.
798
+ - 파일 구성:
799
+ - `bin/rootr.js` — 엔트리포인트, 명령 디스패치
800
+ - `lib/config.js` — 설정 로드/저장
801
+ - `lib/client.js` — Rootr REST API 클라이언트(문서/워크스페이스/스캐폴딩/LOG/ask/이슈/웹훅)
802
+ - `lib/resolve.js` — path/id 타겟 해석 공통 로직
803
+ - `lib/mcp.js` — MCP stdio 서버 진입점, 도구 모듈 조립
804
+ - `lib/mcp-tools/shared.js` — MCP 도구 공통 헬퍼(textResult/jsonResult/errorResult/makeClient/requireWorkspace)
805
+ - `lib/mcp-tools/documents.js` — 문서 도구 6종
806
+ - `lib/mcp-tools/workspaces.js` — 워크스페이스/스캐폴딩 도구 4종
807
+ - `lib/mcp-tools/logs.js` — LOG 데이터스토어 도구 5종
808
+ - `lib/mcp-tools/ask.js` — RCA ask 도구 1종
809
+ - `lib/mcp-tools/issues.js` — 이슈 트래커 도구 6종
810
+ - `lib/mcp-tools/webhooks.js` — 웹훅 도구 3종
811
+ - `lib/mcp-tools/misc.js` — 문서버전/삭제 도구 2종