@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bifos/dooray-cli",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "CLI tool for Dooray project management — AI agent & terminal friendly",
5
5
  "keywords": [
6
6
  "dooray",
@@ -45,7 +45,10 @@ dooray doctor # 설정 검증
45
45
 
46
46
  자연어 요청을 커맨드로 변환할 때 아래 표를 참고한다.
47
47
 
48
- > **공통 (post 하위 16개 명령)**: `post get`/`edit`/`done`/`workflow`, `post comment list`/`add`/`edit`/`delete`, `post file list`/`upload`/`download`/`download-all`/`delete`, `post comment file list`/`upload`/`download`/`delete`는 `<project> <number>` 외에도 `--id <postId>`, `--url <url>`, 또는 첫 인자에 Dooray URL(`https://*.dooray.com/task/to/<postId>` 또는 브라우저 주소창 복사본 `https://*.dooray.com/task/<projectId>/<postId>`)을 직접 받는다. **사용자가 URL을 줬으면 그대로 첫 인자로 전달**하는 것이 가장 빠른 경로 (resolve 단계 단축, ADR-020).
48
+ > **공통 (post 하위 16개 명령)**: 아래 명령은 `<project> <number>` 외에도 `--id <postId>`, `--url <url>`, 또는 첫 인자에 Dooray URL 을 직접 받는다.
49
+ > `post get`/`edit`/`done`/`workflow`, `post comment list`/`add`/`edit`/`delete`, `post file list`/`upload`/`download`/`download-all`/`delete`, `post comment file list`/`upload`/`download`/`delete`.
50
+ > URL 형식: `https://*.dooray.com/task/to/<postId>` 또는 브라우저 주소창 복사본 `https://*.dooray.com/task/<projectId>/<postId>`.
51
+ > **사용자가 URL을 줬으면 그대로 첫 인자로 전달**하는 것이 가장 빠른 경로 (resolve 단계 단축, ADR-020).
49
52
 
50
53
  | 의도 | 커맨드 |
51
54
  |------|--------|
@@ -55,18 +58,20 @@ dooray doctor # 설정 검증
55
58
  | 프로젝트 멤버 보기 | `dooray project members <project>` 또는 `dooray member list <project>` (이름·organizationMemberId) |
56
59
  | 프로젝트 멤버 그룹 목록 | `dooray project groups <project>` (ID / Code) |
57
60
  | 프로젝트 태그 목록 | `dooray project tags <project>` (ID / Color / Name / Group / Mandatory) |
61
+ | 프로젝트 템플릿 목록 | `dooray project templates <project>` (id / templateName) |
58
62
  | 멤버 상세 (organizationMemberId) | `dooray member get <organizationMemberId>` (cache 우회, ADR-021) |
59
63
  | organization 전체 멤버 검색 | `dooray member search <keyword>` (이름 기본), `--email`(이메일 exact), `--user-code`(사번 like), `--user-code-exact`(사번 exact), `--page`/`--size` |
60
64
  | 업무 목록 조회 | `dooray post list <project>` |
61
65
  | 업무 검색 | `dooray post search <project> "<keyword>"` |
62
66
  | 업무 상세 보기 | `dooray post get <project> <number>` |
63
- | 업무 생성 | `dooray post create <project> --title "..." --body "..."` 또는 `--body-file <path>` (`--body`와 `--body-file`은 동시 사용 불가, `--tag`/`--parent`/`--workflow`/`--milestone` 지원) |
67
+ | 업무 생성 | `dooray post create <project> --title "..." [--body "..." \| --body-file <path>]` (`--tag`/`--parent`/`--workflow`/`--milestone` 지원) |
68
+ | 템플릿 기반 업무 생성 | `dooray post create <project> --template <name\|id>` — body/users/tags 자동 채움 (사용자 옵션 우선 override, ADR-027) |
64
69
  | 업무 제목/본문 수정 | `dooray post edit <project> <number> --title "..." --body "..."` 또는 `--body-file <path>` |
65
70
  | 업무 완료 처리 | `dooray post done <project> <number>` |
66
71
  | 업무 워크플로우 변경 | `dooray post workflow <project> <number> <workflow>` |
67
- | 댓글 조회 | `dooray post comment list <project> <number>` `--sort asc\|desc`, `--reverse`, `--latest <n>`, `--since <iso>`, `--from-author <name>` 필터 지원. table 출력은 Creator 이름 자동 채움, `--json`은 raw 유지 (ADR-021) |
72
+ | 댓글 조회 | `dooray post comment list <project> <number>` (`--sort`, `--reverse`, `--latest`, `--since`, `--from-author` 필터. table: Creator 자동 채움, `--json`: raw, ADR-021) |
68
73
  | 최신 댓글 조회 | `dooray post comment latest <project> <number>` — 최신 댓글 1개 빠른 조회. `-n <N>`으로 N개 지정 |
69
- | 단일 댓글 조회 | `dooray post comment get <project> <number> <comment-id> --json` 단일 댓글 본문·메타·attachments 직접 fetch. `comment list` 후 jq 필터 우회 불필요. `--id <postId> --comment-id <id>` / `--url <url> --comment-id <id>` 모드 지원 |
74
+ | 단일 댓글 조회 | `dooray post comment get <project> <number> <comment-id>` — 본문·메타·attachments 직접 fetch. `--id`/`--url` + `--comment-id` 모드 지원 |
70
75
  | 댓글 추가 | `dooray post comment add <project> <number> --body "..."` 또는 `--body-file <path>` |
71
76
  | 댓글 수정 | `dooray post comment edit <project> <number> <comment-id> --body "..."` 또는 `--body-file <path>` |
72
77
  | 댓글 삭제 | `dooray post comment delete <project> <number> <comment-id>` |
@@ -77,6 +82,17 @@ dooray doctor # 설정 검증
77
82
  | 위키 페이지 수정 (제목) | `dooray wiki page edit <project> <page-id> --title "..."` |
78
83
  | 위키 페이지 수정 (본문) | `dooray wiki page edit <project> <page-id> --body "..."` 또는 `--body-file ./new.md` |
79
84
  | 위키 페이지 수정 (에디터) | `dooray wiki page edit <project> <page-id>` (플래그 없으면 $EDITOR 열림) |
85
+ | 위키 페이지 첨부 목록 | `dooray wiki page file list <project> <page-id>` (general + inline 합산, type 컬럼) |
86
+ | 위키 페이지 첨부 업로드 | `dooray wiki page file upload <project> <page-id> --file <path> [--type inline_image]` (multipart type 순서 ADR-029) |
87
+ | 위키 페이지 첨부 다운로드 | `dooray wiki page file download <project> <page-id> --file-id <id> -o <dir>` |
88
+ | 위키 페이지 첨부 일괄 다운로드 | `dooray wiki page file download-all <project> <page-id> -o <dir>` (files + images 전부) |
89
+ | 위키 페이지 첨부 삭제 | `dooray wiki page file delete <project> <page-id> --file-id <id>` (confirm 없음) |
90
+ | 위키 페이지 댓글 목록 | `dooray wiki page comment list <project> <page-id> [--latest N]` (최신순) |
91
+ | 위키 페이지 최신 댓글 | `dooray wiki page comment latest <project> <page-id>` |
92
+ | 위키 페이지 댓글 조회 | `dooray wiki page comment get <project> <page-id> <comment-id>` |
93
+ | 위키 페이지 댓글 추가 | `dooray wiki page comment add <project> <page-id> --body "..."` ($EDITOR fallback) |
94
+ | 위키 페이지 댓글 수정 | `dooray wiki page comment edit <project> <page-id> <comment-id> --body "..."` |
95
+ | 위키 페이지 댓글 삭제 | `dooray wiki page comment delete <project> <page-id> <comment-id>` (confirm 없음) |
80
96
  | 메일 목록 조회 | `dooray mail list` |
81
97
  | 안읽은 메일 | `dooray mail list --unread` |
82
98
  | 메일 제목 검색 | `dooray mail list --search "<keyword>"` |
@@ -95,6 +111,10 @@ dooray doctor # 설정 검증
95
111
  | 참조자(cc) 멤버/그룹 추가 | `dooray post edit <project> <number> --cc-group <code>` — 기존 참조자 유지 + 그룹 추가 (dedupe, ADR-025) |
96
112
  | 참조자 전체 교체 | `dooray post edit <project> <number> --cc-clear --cc <name>` — 기존 참조자 비우고 신규 멤버만 |
97
113
  | 신규 업무 + 그룹 cc | `dooray post create <project> --title "..." --cc-group <code>` — 생성 시 그룹 참조자 포함 |
114
+ | 상위 업무 설정/변경 | `dooray post edit <project> <number> --title "<원제목>" --parent <ref>` (`<ref>`: `<project>/<number>` 또는 raw postId. `--title` 필수, unset 미지원) |
115
+ | `dooray post edit --id <postId> --tag <name>` | 태그 추가 (반복, dedupe) |
116
+ | `dooray post edit --id <postId> --tag-clear --tag <name>` | 태그 전체 교체 |
117
+ | `dooray post edit --id <postId> --tag-remove <name>` | 특정 태그 제거 |
98
118
 
99
119
  > **제목 옵션 네이밍**: `post` 와 `wiki page` 모두 `--title` 표준. `post`의 `--subject`는 deprecated alias로 당분간 동작하되, 새 코드에서는 `--title` 사용을 권장.
100
120
 
@@ -106,7 +126,7 @@ CLI로 처리 **불가능한** 작업. 아래 항목을 요청받으면 웹 UI
106
126
 
107
127
  | 작업 | 대체 경로 | 근거 |
108
128
  |---|---|---|
109
- | 위키 페이지 **삭제** | 웹 UI (`https://{tenant}.dooray.com/wiki/...`) | Dooray REST API 해당 엔드포인트 없음 (위키 댓글·첨부파일 삭제는 있지만 페이지 자체는 없음 — ADR 또는 Dooray 공식 API 문서 미제공) |
129
+ | 위키 페이지 **삭제** | 웹 UI (`https://{tenant}.dooray.com/wiki/...`) | Dooray REST API 미제공 (댓글·첨부파일 삭제는 있지만 페이지 삭제 endpoint 없음) |
110
130
  | 프로젝트 삭제 | 웹 UI (admin 페이지) | API 미지원 |
111
131
 
112
132
  위키 페이지를 잘못 만든 경우(테스트/중복) **soft delete(빈 제목·본문) 우회 금지** — 페이지가 트리에 남아 사용자 혼란 유발.
@@ -164,7 +184,8 @@ dooray post comment add <project> 42 --body "진행 상황 업데이트: 80% 완
164
184
 
165
185
  ### 시나리오 — 댓글에 스크린샷 자동 첨부
166
186
 
167
- 스크립트가 스크린샷을 댓글에 삽입하거나, 에이전트가 결과 파일을 첨부 댓글로 보고할 때 사용. Dooray REST API 가 댓글 전용 attachment endpoint 를 미지원하므로 내부적으로 post-level files API + 댓글 본문 PUT 합성으로 동작 (ADR-024).
187
+ 스크립트가 스크린샷을 댓글에 삽입하거나, 에이전트가 결과 파일을 첨부 댓글로 보고할 때 사용.
188
+ Dooray REST API 가 댓글 전용 attachment endpoint 를 미지원하므로 내부적으로 post-level files API + 댓글 본문 PUT 합성으로 동작 (ADR-024).
168
189
 
169
190
  ```bash
170
191
  # 1. 댓글을 먼저 만든다 (텍스트만, --json 으로 commentId 획득)
@@ -185,6 +206,36 @@ dooray wiki pages <project> --json
185
206
  dooray wiki page get <project> <pageId> --json
186
207
  ```
187
208
 
209
+ ### 위키 페이지 첨부파일 — 스킬 파일 팀 공유 (Issue #70)
210
+
211
+ **스킬 파일 팀 공유**: 팀 위키에 스킬 파일 (예: `SKILL.md`) 을 `wiki page file upload` 로 첨부 → 팀원이 `wiki page file download-all` 로 일괄 받아 `~/.claude/skills/` 에 그대로 설치.
212
+
213
+ ```bash
214
+ # 업로드 (일반 첨부)
215
+ dooray wiki page file upload <project> <page-id> --file ~/.claude/skills/my-skill/SKILL.md
216
+
217
+ # 팀원 쪽에서 일괄 다운로드
218
+ dooray wiki page file download-all <project> <page-id> -o ~/.claude/skills/my-skill/
219
+
220
+ # 첨부 목록 확인 (type 컬럼: general / inline_image)
221
+ dooray wiki page file list <project> <page-id>
222
+ ```
223
+
224
+ ### 위키 페이지 댓글 — 회의록 결정사항 자동 누적
225
+
226
+ **회의록 결정사항 자동 누적**: 회의록 위키 페이지에 자동화 봇이 `wiki page comment add` 로 결정사항을 댓글로 누적, `wiki page comment list --latest 20` 으로 최근 토론 흐름 추적.
227
+
228
+ ```bash
229
+ # 결정사항 댓글 추가
230
+ dooray wiki page comment add <project> <page-id> --body "결정: 배포일 2026-06-01 확정"
231
+
232
+ # 최근 20개 토론 흐름 조회
233
+ dooray wiki page comment list <project> <page-id> --latest 20
234
+
235
+ # 최신 댓글 1건 shortcut
236
+ dooray wiki page comment latest <project> <page-id>
237
+ ```
238
+
188
239
  ## 단일 댓글 본문 fetch
189
240
 
190
241
  `post comment get <project> <post-number> <comment-id> --json` 으로 단일 댓글의 본문 + attachments 를 곧장 fetch. `comment list` 후 jq 필터링 우회 불필요.
@@ -212,7 +263,8 @@ dooray wiki page get <project> <pageId> --json
212
263
 
213
264
  ### 업무 식별 방식 (post 하위 16개 명령 공통, ADR-020)
214
265
 
215
- `post get`/`edit`/`done`/`workflow`, `post comment list`/`add`/`edit`/`delete`, `post file list`/`upload`/`download`/`download-all`/`delete`, `post comment file list`/`upload`/`download`/`delete`는 4가지 입력을 모두 받는다:
266
+ 아래 16개 명령은 4가지 입력을 모두 받는다:
267
+ `post get`/`edit`/`done`/`workflow`, `post comment list`/`add`/`edit`/`delete`, `post file list`/`upload`/`download`/`download-all`/`delete`, `post comment file list`/`upload`/`download`/`delete`.
216
268
 
217
269
  ```bash
218
270
  # (1) 기존 positional — 가장 익숙한 형태
@@ -228,7 +280,9 @@ dooray post get --id <postId>
228
280
  dooray post get --url https://x.dooray.com/task/to/<postId>
229
281
  ```
230
282
 
231
- **우선순위 / 충돌 규칙**: `--id`+`--url` 동시 지정 → 에러. `--id`/`--url`+positional 동시 지정 → 에러. URL/`--id`/`--url` 모드는 standalone API(`getPost(postId)`)로 resolve 단계를 단축.
283
+ **우선순위 / 충돌 규칙**: `--id`+`--url` 동시 지정 → 에러.
284
+ `--id`/`--url`+positional 동시 지정 → 에러.
285
+ URL/`--id`/`--url` 모드는 standalone API(`getPost(postId)`)로 resolve 단계를 단축.
232
286
 
233
287
  **sub-id 옵션화** (URL/`--id`/`--url` 모드에서 필수):
234
288
  ```bash
@@ -267,7 +321,9 @@ dooray post create <project> \
267
321
  dooray post create <project> --title "제목" --body-file ./content.md
268
322
  ```
269
323
 
270
- > **`--workflow` 동작 주의**: 워크플로우 설정은 post 생성 *후속* 호출이므로, 워크플로우 resolve/설정에 실패해도 stderr 경고만 출력되고 **exit code는 0** (post는 이미 생성됨). 자동화 스크립트에서 워크플로우 적용 여부를 보장해야 하면 stderr를 별도 점검할 것.
324
+ > **`--workflow` 동작 주의**: 워크플로우 설정은 post 생성 *후속* 호출.
325
+ > resolve/설정에 실패해도 stderr 경고만 출력되고 **exit code는 0** (post는 이미 생성됨).
326
+ > 자동화 스크립트에서 워크플로우 적용 여부를 보장해야 하면 stderr를 별도 점검할 것.
271
327
 
272
328
  ### 업무 수정 (non-interactive)
273
329
 
@@ -304,9 +360,30 @@ dooray post edit --id "$POST_ID" --cc-group qa-team --dry-run --json \
304
360
 
305
361
  > interactive (`$EDITOR`) 모드에서는 위 옵션이 무시되고 stderr 경고가 출력됩니다.
306
362
 
363
+ ## 동명이인 우회 — 이메일 / memberId 직접 (Issue #58)
364
+
365
+ 이름이 동일한 멤버가 여러 명이라 `--cc 홍길동` 이 모호로 실패할 때:
366
+
367
+ ```bash
368
+ # 1) 이메일로 우회
369
+ dooray post edit --id "$POST_ID" --cc user.specific@example.com
370
+
371
+ # 2) 사전에 member search 로 ID 확보 후 직접
372
+ MEMBER_ID=$(dooray member search 홍길동 --json | jq -r '.[] | select(.externalEmailAddress=="user.specific@example.com") | .id')
373
+ dooray post edit --id "$POST_ID" --cc "$MEMBER_ID"
374
+ ```
375
+
376
+ `--to` / `--mention` 동일 분기 (resolveMember 인프라). 분기 규칙:
377
+ - `^\d{15,}$` — memberId 직접 사용
378
+ - 이메일 정규형 — searchMembers exact
379
+ - 그 외 — 이름 부분일치
380
+
307
381
  ## 신규 업무 생성 후 그룹 cc 첨부 (ADR-025)
308
382
 
309
- audit 리포트 분석 → 신규 업무 생성 → 후속으로 특정 그룹을 참조에 추가하는 자동화 패턴:
383
+ 자동화 패턴:
384
+ 1. audit 리포트 분석
385
+ 2. 신규 업무 생성
386
+ 3. 후속으로 특정 그룹을 참조에 추가
310
387
 
311
388
  ```bash
312
389
  # 1. 신규 업무 생성 (그룹 cc 포함)
@@ -322,6 +399,36 @@ dooray post edit --id "$POST_ID" --cc-group qa-team
322
399
 
323
400
  ---
324
401
 
402
+ ## 자식 업무 먼저 → 후속 부모 지정 (Issue #60)
403
+
404
+ ```bash
405
+ # 1. 자식 업무 생성 (parent 모르고)
406
+ CHILD_ID=$(dooray post create <project> --title "subtask A" --json | jq -r '.id')
407
+
408
+ # 2. 부모 결정 후 후속 지정
409
+ dooray post edit --id "$CHILD_ID" --title "subtask A" --parent <project>/<parent-number>
410
+ ```
411
+
412
+ **한계** (cmux-browser spike 결과): Dooray API 가 `unset-parent-post` 미제공 → CLI 로 parent 해제 불가. 필요 시 웹 UI 에서 처리.
413
+
414
+ ---
415
+
416
+ ## 태그 사후 분류 자동화 (Issue #66)
417
+
418
+ 분류 분석 결과를 받아 태그를 재분류하는 자동화는 단독 호출 패턴이 효율적:
419
+
420
+ ```bash
421
+ # 분석 스크립트가 분류한 태그 이름을 cli 로 적용 — body fetch 불요
422
+ POST_ID=$(...)
423
+ CATEGORY=$(...)
424
+ dooray post edit --id "$POST_ID" --tag "분류: $CATEGORY"
425
+ ```
426
+
427
+ 태그만 변경하는 시나리오에서 `--title` / `--body` 강제 없음.
428
+ mandatory 그룹은 친절한 에러 메시지로 안내 (ADR-019).
429
+
430
+ ---
431
+
325
432
  ### 댓글 추가 (non-interactive)
326
433
 
327
434
  ```bash
@@ -364,7 +471,8 @@ dooray post comment add P 1 --mention 홍길동 --mention-group 개발 --body ".
364
471
 
365
472
  ## Dooray 마크다운 링크 형식 (멤버·그룹·업무 멘션)
366
473
 
367
- 댓글/본문 작성 시 다음 형식으로 마크업하면 Dooray 앱이 인식해 inline 멘션·navigation으로 렌더링한다. ID는 본인 환경 값으로 채워 사용 — `dooray member get` / `project groups` / `post get` 등으로 조회.
474
+ 댓글/본문 작성 시 다음 형식으로 마크업하면 Dooray 앱이 인식해 inline 멘션·navigation으로 렌더링한다.
475
+ ID는 본인 환경 값으로 채워 사용 — `dooray member get` / `project groups` / `post get` 등으로 조회.
368
476
 
369
477
  ### 멤버 멘션
370
478
  ```markdown
@@ -416,7 +524,8 @@ dooray feedback --last --title "에러 제목" --body "추가 설명" --dry-run
416
524
  dooray feedback --last --title "에러 제목" --body "추가 설명" # 실제 등록
417
525
  ```
418
526
 
419
- > **참고**: `--last` 모드는 `trackLastRun: true` (ADR-023 opt-in)가 설정된 경우에만 직전 실패 명령이 자동 기록됨. argv는 시크릿 패턴(`--api-key`/`--token`/`Authorization`) 마스킹 후 저장.
527
+ > **참고**: `--last` 모드는 `trackLastRun: true` (ADR-023 opt-in)가 설정된 경우에만 직전 실패 명령이 자동 기록됨.
528
+ > argv는 시크릿 패턴(`--api-key`/`--token`/`Authorization`) 마스킹 후 저장.
420
529
 
421
530
  ## 에러 핸들링
422
531
 
@@ -432,6 +541,22 @@ CLI 에러 발생 시 복구 방법:
432
541
 
433
542
  ---
434
543
 
544
+ ## 정형 task 자동화 (Issue #59 / ADR-027)
545
+
546
+ 매주 같은 형식의 task 를 만드는 자동화는 템플릿 + override 패턴이 효율적:
547
+
548
+ ```bash
549
+ # 매주 월요일 실행되는 cron — "주간 릴리스 체크" 템플릿으로 자동 생성
550
+ TODAY=$(date +%Y-%m-%d)
551
+ POST_ID=$(dooray post create <project> \
552
+ --template "주간 릴리스 체크" \
553
+ --title "주간 릴리스 체크 — $TODAY" \
554
+ --json | jq -r '.id')
555
+ ```
556
+
557
+ 템플릿 본문의 `${year}` / `${month}` 등 매크로는 Dooray 가 자동 치환 (`interpolation=true` 기본).
558
+ 사용자 정의 변수는 미지원 — 필요 시 client 측 string replace 로 처리.
559
+
435
560
  ## 캐시
436
561
 
437
562
  프로젝트, 멤버, 워크플로우, 위키 정보는 `~/.dooray/cache/`에 캐시된다.