@bifos/dooray-cli 0.8.0 → 0.10.0

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.md CHANGED
@@ -23,7 +23,11 @@ npm install -g @bifos/dooray-cli
23
23
  dooray setup
24
24
  ```
25
25
 
26
- API Endpoint 선택 → API Key 입력 → 연결 테스트 → 메일 설정(선택)을 순서대로 진행합니다.
26
+ 아래 순서로 진행합니다:
27
+ 1. API Endpoint 선택
28
+ 2. API Key 입력
29
+ 3. 연결 테스트
30
+ 4. 메일 설정 (선택)
27
31
  API 토큰은 `https://{tenant}.dooray.com/setting/api/token`에서 발급할 수 있습니다.
28
32
 
29
33
  수동 설정도 가능합니다:
@@ -46,6 +50,7 @@ dooray project members <project> # 멤버 목록
46
50
  dooray project workflows <project> # 워크플로우 목록
47
51
  dooray project groups <project> # 멤버 그룹 목록 (ID / Code)
48
52
  dooray project tags <project> # 태그 목록 (ID / Color / Name / Group / Mandatory)
53
+ dooray project templates <project> # 템플릿 목록 (ID / Template Name, ADR-027)
49
54
  ```
50
55
 
51
56
  > **태그 캐시 갱신**: 이전 버전에서 캐시한 태그가 색상 없이 표시되면 `dooray cache clear` 실행 후 다시 조회하세요.
@@ -83,7 +88,8 @@ dooray post get <project> 42 --json # JSON 출력
83
88
  | `--id <postId>` | `dooray post get --id <postId>` |
84
89
  | `--url <url>` | `dooray post get --url https://x.dooray.com/task/to/...` |
85
90
 
86
- 대상: `post get`/`edit`/`done`/`workflow`, `post comment list`/`add`/`edit`/`delete`, `post file list`/`upload`/`download`/`download-all`/`delete`. AI 에이전트는 사용자 메시지의 Dooray URL을 그대로 첫 인자로 전달하면 가장 빠르다 (ADR-020).
91
+ 대상: `post get`/`edit`/`done`/`workflow`, `post comment list`/`add`/`edit`/`delete`, `post file list`/`upload`/`download`/`download-all`/`delete`.
92
+ AI 에이전트는 사용자 메시지의 Dooray URL을 그대로 첫 인자로 전달하면 가장 빠르다 (ADR-020).
87
93
 
88
94
  ### 업무 생성
89
95
 
@@ -106,7 +112,27 @@ dooray post create <project> \
106
112
  --milestone "Sprint 12"
107
113
  ```
108
114
 
109
- > mandatory-tag 정책 프로젝트(예: `<project>`)에서는 mandatory 그룹마다 1개 이상 `--tag`로 지정해야 한다. 누락 시 클라이언트가 사전 검증으로 후보 목록과 함께 에러 출력.
115
+ > mandatory-tag 정책 프로젝트(예: `<project>`)에서는 mandatory 그룹마다 1개 이상 `--tag`로 지정해야 한다.
116
+ > 누락 시 클라이언트가 사전 검증으로 후보 목록과 함께 에러 출력.
117
+
118
+ #### 템플릿 기반 정형 task (ADR-027)
119
+
120
+ ```bash
121
+ # 프로젝트의 템플릿 목록
122
+ dooray project templates <project>
123
+
124
+ # 템플릿으로 업무 생성 (body/users/tags 자동 채움)
125
+ dooray post create <project> --template "릴리스 플랜"
126
+
127
+ # 사용자 옵션 override — 일부 필드만 다르게
128
+ dooray post create <project> --template "릴리스 플랜" --title "v0.9 릴리스 계획" --tag "p0"
129
+
130
+ # 19자리 templateId 직접 입력
131
+ dooray post create <project> --template 1234567890123456789 --title "by id"
132
+ ```
133
+
134
+ `interpolation=true` 가 기본 — Dooray 가 `${year}`, `${month}` 같은 시스템 매크로를 응답에서 자동 치환.
135
+ 사용자 정의 변수 (`--field key=value`) 는 본 release scope 외.
110
136
 
111
137
  ### 업무 수정
112
138
 
@@ -123,7 +149,8 @@ dooray post edit <project> 42 --body-file ./updated.md
123
149
 
124
150
  #### 본문 변경 시 attachment 보호
125
151
 
126
- `post edit` 와 `post comment edit` 는 본문을 통째로 replace 합니다. 새 본문에 기존 inline attachment markdown(`![](/files/<id>)`)이 빠져 있으면 stderr 에 경고를 띄우고 (y/N) 로 물어봅니다.
152
+ `post edit` 와 `post comment edit` 는 본문을 통째로 replace 합니다.
153
+ 새 본문에 기존 inline attachment markdown(`![](/files/<id>)`)이 빠져 있으면 stderr 에 경고를 띄우고 (y/N) 로 물어봅니다.
127
154
 
128
155
  자동화 환경 (pipe / non-TTY) 에서는 그대로 abort 됩니다. 의도한 변경이면 `--no-confirm` 으로 다시 실행하세요.
129
156
 
@@ -179,13 +206,73 @@ dooray post create <project> --title "주간 audit" --cc-group dev-team
179
206
  ```
180
207
 
181
208
  interactive ($EDITOR) 모드에서는 위 6개 옵션이 무시되고 stderr 경고가 출력됩니다.
182
- `post edit --dry-run --json` 사용 시 출력에 `users: { to, cc }` 가 포함되어 API 호출 없이 변경 결과 미리보기 가능. (`post create --dry-run` 은 본문만 출력하며 `users` 는 포함하지 않음.)
209
+ `post edit --dry-run --json` 사용 시 출력에 `users: { to, cc }` 가 포함되어 API 호출 없이 변경 결과 미리보기 가능.
210
+ `post create --dry-run` 은 본문만 출력하며 `users` 는 포함하지 않음.
183
211
 
184
212
  ```bash
185
213
  dooray post edit <project> <post-number> --cc-group dev-team --dry-run --json | jq '.users.cc'
186
214
  # 출력 예: [{ "type": "group", "group": { "projectMemberGroupId": "...", "members": [] } }, ...]
187
215
  ```
188
216
 
217
+ #### 생성 후 태그 변경 (Issue #66)
218
+
219
+ ```bash
220
+ # 기존 태그 유지 + 신규 추가 (dedupe)
221
+ dooray post edit --id <postId> --tag "<group>: <name>"
222
+
223
+ # 기존 태그 전부 제거 + 신규만 적용
224
+ dooray post edit --id <postId> --tag-clear --tag "<group>: <name>"
225
+
226
+ # 특정 태그만 제거 (기존 유지)
227
+ dooray post edit --id <postId> --tag-remove "<group>: <name>"
228
+ ```
229
+
230
+ `--title` / `--body` 없이 단독 호출 가능 — 기존 본문은 자동 재전송.
231
+ mandatory tag 그룹은 `post create` 와 동일하게 사전 검증 (ADR-019).
232
+
233
+ #### 상위 업무 변경 (`--parent`)
234
+
235
+ ```bash
236
+ # 자식 업무에 부모 지정
237
+ dooray post edit <project> <child-number> --title "<원제목>" --parent <project>/<parent-number>
238
+
239
+ # 다른 부모로 변경
240
+ dooray post edit --id <postId> --title "<원제목>" --parent <other-parent-postId>
241
+ ```
242
+
243
+ 내부적으로 `client.updatePost` 호출 후 별도 `POST .../set-parent-post` endpoint 추가 호출.
244
+ **parent 해제 (top-level 화)** 는 Dooray API 가 미지원이라 웹 UI 에서 수동 처리.
245
+
246
+ interactive ($EDITOR) 모드에서 `--parent` 사용 시 무시 + stderr 경고.
247
+ **parent 만 단독 변경하려면 `--title "<원제목>"` 동반 필요** — `post edit` 는 본문 변경(`--title`/`--body`) 동반 시에만 non-interactive 분기로 들어감.
248
+ parent 변경은 그 분기 안에서만 수행됨. (Issue #60)
249
+
250
+ `--dry-run --json` 출력의 `parentChange` 필드는 **사용자 입력 원문 그대로** (`<project>/<number>` 또는 raw postId).
251
+ resolver 처리 전 미리보기 값이며 실제 호출 대상 `postId` 가 아님.
252
+ dry-run 은 API 미호출 원칙을 유지해 `resolvePostRef` 도 건너뜀.
253
+
254
+ #### `--to` / `--cc` / `--mention` 입력 형식 (자동 분기)
255
+
256
+ 이름 외에도 이메일 / organizationMemberId 직접 입력 가능 — **동명이인 우회 + ID 직접 입력** (Issue #58):
257
+
258
+ ```bash
259
+ # 이름 (이전부터 지원, 부분일치)
260
+ dooray post create <project> --title "..." --cc 홍길동
261
+
262
+ # 이메일 (동명이인 우회)
263
+ dooray post create <project> --title "..." --cc user@example.com
264
+
265
+ # organizationMemberId 직접
266
+ dooray post create <project> --title "..." --cc 1234567890123456789
267
+ ```
268
+
269
+ 분기 규칙 (`resolveMember` 자동 판단):
270
+ - `^\d{15,}$` — memberId 직접 사용
271
+ - `^[^\s@]+@[^\s@]+\.[^\s@]+$` — 이메일, `searchMembers` exact 조회
272
+ - 그 외 — 이름 부분일치
273
+
274
+ `member search --email` 의 인프라 재사용.
275
+
189
276
  #### comment list 필터 옵션
190
277
 
191
278
  ```bash
@@ -250,6 +337,79 @@ dooray wiki page edit <project> <page-id> --body "..." | --body-file <path> #
250
337
  dooray wiki page edit <project> <page-id> # $EDITOR (플래그 없을 때)
251
338
  ```
252
339
 
340
+ #### 위키 페이지 첨부파일 (Issue #70)
341
+
342
+ post 의 `post file` 명령군과 동일 패턴 — `<project> <page-id>` 외에도 `--id`/`--url`/positional URL 지원.
343
+
344
+ ```bash
345
+ # 목록 (general 첨부 + inline image 둘 다 표시, type 컬럼)
346
+ dooray wiki page file list <project> <page-id>
347
+
348
+ # 업로드 (기본 general — 페이지 하단 첨부 영역)
349
+ dooray wiki page file upload <project> <page-id> --file ./SKILL.md
350
+ # stdout: attachFileId + 파일 메타 출력
351
+
352
+ # 인라인 이미지 업로드 (본문 markdown 은 사용자가 직접 박음)
353
+ dooray wiki page file upload <project> <page-id> --file ./diagram.png --type inline_image
354
+ # stdout 에 본문 삽입용 markdown snippet 안내
355
+
356
+ # 다운로드
357
+ dooray wiki page file download <project> <page-id> --file-id <id> -o ./
358
+
359
+ # 페이지 모든 첨부 (files + images) 일괄 다운로드
360
+ dooray wiki page file download-all <project> <page-id> -o ./attachments/
361
+
362
+ # 삭제 (confirm 없이 즉시)
363
+ dooray wiki page file delete <project> <page-id> --file-id <id>
364
+
365
+ # URL 모드 (--id 모드는 --project 동반 필요)
366
+ dooray wiki page file list "https://<tenant>.dooray.com/wiki/<wikiId>/<pageId>"
367
+ dooray wiki page file upload --id <pageId> --project <project> --file ./README.md
368
+ ```
369
+
370
+ **주의**:
371
+ - `upload` 시 multipart 필드 순서 (`type` → `file`) 가 중요.
372
+ 클라이언트가 자동으로 강제 (ADR-029 참조)
373
+ - `inline_image` 로 올린 파일은 본문에 markdown 으로 박혀야 위키에서 보임.
374
+ upload stdout 의 snippet 을 복사해서 `dooray wiki page edit` 으로 본문에 직접 추가
375
+ - `delete` 는 confirm 없이 즉시 삭제 (실수 방지 책임은 호출자)
376
+
377
+ #### 위키 페이지 댓글
378
+
379
+ post 의 `post comment` 명령군과 동일 패턴 — `<project> <page-id>` 외에도 `--id`/`--url`/positional URL 지원.
380
+
381
+ ```bash
382
+ # 목록 (최신순)
383
+ dooray wiki page comment list <project> <page-id>
384
+ dooray wiki page comment list <project> <page-id> --latest 5
385
+
386
+ # 최신 1건 shortcut
387
+ dooray wiki page comment latest <project> <page-id>
388
+
389
+ # 단일 조회
390
+ dooray wiki page comment get <project> <page-id> <comment-id>
391
+
392
+ # 추가 — interactive ($EDITOR) 또는 옵션
393
+ dooray wiki page comment add <project> <page-id> # $EDITOR
394
+ dooray wiki page comment add <project> <page-id> --body "회의 결정 사항"
395
+ dooray wiki page comment add <project> <page-id> --body-file ./note.md
396
+ echo "댓글" | dooray wiki page comment add <project> <page-id> --body -
397
+
398
+ # 수정 — interactive ($EDITOR, 기존 본문 prefill) 또는 옵션
399
+ dooray wiki page comment edit <project> <page-id> <comment-id> --body "..."
400
+
401
+ # 삭제 (confirm 없이 즉시)
402
+ dooray wiki page comment delete <project> <page-id> <comment-id>
403
+
404
+ # URL 모드
405
+ dooray wiki page comment list "https://<tenant>.dooray.com/wiki/<wikiId>/<pageId>"
406
+ ```
407
+
408
+ **post comment 와의 차이**:
409
+ - mention / cc / 받는 사람 미지원 — wiki API 부재
410
+ - 첨부 파일 미지원 — wiki comment 전용 endpoint 부재 (페이지 본문 파일은 `wiki page file` 사용)
411
+ - 본문은 markdown 그대로 전송 (mimeType 자동)
412
+
253
413
  ### 메일
254
414
 
255
415
  IMAP을 통해 Dooray 메일을 조회할 수 있습니다. 메일 설정은 `dooray setup`에서 한 번에 진행하거나, 수동으로 설정할 수 있습니다.
@@ -309,7 +469,8 @@ dooray post comment delete --url <url> --comment-id <commentId>
309
469
 
310
470
  ### 댓글 첨부 파일 (`post comment file *`)
311
471
 
312
- 자동화로 댓글에 인라인 이미지 / 파일을 삽입할 때 사용. 4 명령 (list/upload/download/delete) 모두 `<project> <post-number> <comment-id>` 또는 `--id <postId> --comment-id <logId>` / `--url <url> --comment-id <logId>` 패턴 지원 (ADR-020).
472
+ 자동화로 댓글에 인라인 이미지 / 파일을 삽입할 때 사용.
473
+ 4 명령 (list/upload/download/delete) 모두 `<project> <post-number> <comment-id>` 또는 `--id <postId> --comment-id <logId>` / `--url <url> --comment-id <logId>` 패턴 지원 (ADR-020).
313
474
 
314
475
  ```bash
315
476
  # 첨부 목록
@@ -345,7 +506,8 @@ dooray post list <project> --quiet | xargs -I{} dooray post done <project> {}
345
506
 
346
507
  ## AI 에이전트 연동
347
508
 
348
- `skills/dooray-cli/SKILL.md`에 AI 에이전트를 위한 스킬 파일이 포함되어 있습니다. Claude Code 등의 AI 에이전트에서 dooray-cli를 자동으로 활용할 수 있도록 의도→커맨드 매핑, 체이닝 예시, 에러 핸들링 가이드가 포함되어 있습니다.
509
+ `skills/dooray-cli/SKILL.md`에 AI 에이전트를 위한 스킬 파일이 포함되어 있습니다.
510
+ Claude Code 등의 AI 에이전트에서 dooray-cli를 자동으로 활용할 수 있도록 의도→커맨드 매핑, 체이닝 예시, 에러 핸들링 가이드가 포함되어 있습니다.
349
511
 
350
512
  ```bash
351
513
  # 스킬 파일 복사 (Claude Code 예시)
@@ -409,7 +571,7 @@ dooray --help
409
571
 
410
572
  ### CI (`.github/workflows/ci.yml`)
411
573
  - 트리거: `main` 으로 push, `main` 대상 PR
412
- - 동작: `pnpm install --frozen-lockfile` `pnpm test` `pnpm build` (Node 18, ubuntu-latest)
574
+ - 동작: `pnpm install --frozen-lockfile`, `pnpm test`, `pnpm build` (Node 18, ubuntu-latest)
413
575
  - 별도 secret 불필요
414
576
 
415
577
  ### Claude code review (`.github/workflows/claude-code-review.yml`)
@@ -425,11 +587,13 @@ dooray --help
425
587
 
426
588
  #### 비용 / 토큰
427
589
 
428
- 각 PR 당 4 specialist 가 모두 `haiku` 모델로 동작 — 평균 PR 1건 당 수십 센트 수준. PR 자동 트리거 비활성화하려면 `claude-code-review.yml` 의 `if:` 조건에서 `github.event_name == 'pull_request'` 분기를 제거하고 `/review` 댓글 트리거만 남길 수 있음.
590
+ 각 PR 당 4 specialist 가 모두 `haiku` 모델로 동작 — 평균 PR 1건 당 수십 센트 수준.
591
+ PR 자동 트리거 비활성화하려면 `claude-code-review.yml` 의 `if:` 조건에서 `github.event_name == 'pull_request'` 분기를 제거하고 `/review` 댓글 트리거만 남길 수 있음.
429
592
 
430
593
  #### Fork PR 제한
431
594
 
432
- GitHub Actions 정책상 fork 에서 열린 PR 은 `secrets.CLAUDE_CODE_OAUTH_TOKEN` 에 접근 못 해 **자동 리뷰가 silent 하게 skip** 된다. fork 기여자가 리뷰를 받으려면 maintainer 가 PR 댓글에 `/review` 를 작성하여 base repo 컨텍스트로 워크플로를 트리거해야 한다.
595
+ GitHub Actions 정책상 fork 에서 열린 PR 은 `secrets.CLAUDE_CODE_OAUTH_TOKEN` 에 접근 못 해 **자동 리뷰가 silent 하게 skip** 된다.
596
+ fork 기여자가 리뷰를 받으려면 maintainer 가 PR 댓글에 `/review` 를 작성하여 base repo 컨텍스트로 워크플로를 트리거해야 한다.
433
597
 
434
598
  ## 라이센스
435
599