@bifos/dooray-cli 0.10.0 → 0.10.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.md CHANGED
@@ -209,6 +209,22 @@ interactive ($EDITOR) 모드에서는 위 6개 옵션이 무시되고 stderr 경
209
209
  `post edit --dry-run --json` 사용 시 출력에 `users: { to, cc }` 가 포함되어 API 호출 없이 변경 결과 미리보기 가능.
210
210
  `post create --dry-run` 은 본문만 출력하며 `users` 는 포함하지 않음.
211
211
 
212
+ **그룹 cc / mention 사용 예 (Issue #76 fix)**:
213
+
214
+ ```bash
215
+ # code 부분일치
216
+ dooray post create <project> ... --cc-group "개발"
217
+
218
+ # code 정확 일치
219
+ dooray post create <project> ... --mention-group "all"
220
+
221
+ # 19자리 id 직접 입력 (response shape robustness 또는 code 누락 그룹 회피)
222
+ dooray post create <project> ... --cc-group "<19자리 group id>"
223
+
224
+ # 후보 탐색
225
+ dooray project groups <project>
226
+ ```
227
+
212
228
  ```bash
213
229
  dooray post edit <project> <post-number> --cc-group dev-team --dry-run --json | jq '.users.cc'
214
230
  # 출력 예: [{ "type": "group", "group": { "projectMemberGroupId": "...", "members": [] } }, ...]
package/dist/index.js CHANGED
@@ -1549,13 +1549,15 @@ var projectWorkflowsCommand = new import_commander7.Command("workflows").descrip
1549
1549
  var import_commander8 = require("commander");
1550
1550
 
1551
1551
  // src/resolvers/member-group.ts
1552
+ var GROUP_ID_RE = /^\d{15,}$/;
1552
1553
  async function fetchAllMemberGroups(client, projectId) {
1553
1554
  const all = [];
1554
1555
  let page = 0;
1555
1556
  const size = RESOLVER_FETCH_PAGE_SIZE;
1556
1557
  while (true) {
1557
1558
  const res = await client.getProjectMemberGroups(projectId, { page, size });
1558
- for (const g of res.result) {
1559
+ const groups = res.result.flat();
1560
+ for (const g of groups) {
1559
1561
  all.push({ id: g.id, code: g.code });
1560
1562
  }
1561
1563
  const total = res.totalCount ?? all.length;
@@ -1576,17 +1578,30 @@ function hasValidCode(g) {
1576
1578
  }
1577
1579
  async function resolveMemberGroup(client, projectId, input2) {
1578
1580
  const groups = await ensureMemberGroups(client, projectId);
1581
+ if (GROUP_ID_RE.test(input2)) {
1582
+ const found = groups.find((g) => g.id === input2);
1583
+ if (found) {
1584
+ return { id: found.id, code: found.code ?? "" };
1585
+ }
1586
+ throw new DoorayCliError(
1587
+ `\uADF8\uB8F9 id \uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: "${input2}"
1588
+ \uC804\uCCB4 \uBAA9\uB85D\uC740 \`dooray project groups <project>\` \uB85C \uD655\uC778\uD558\uC138\uC694.`,
1589
+ EXIT_PARAM_ERROR
1590
+ );
1591
+ }
1579
1592
  const valid = groups.filter(hasValidCode);
1580
1593
  const skipped = groups.length - valid.length;
1581
1594
  if (skipped > 0) {
1582
1595
  process.stderr.write(
1583
- `\u26A0 ${skipped}\uAC1C \uADF8\uB8F9\uC5D0 code \uAC00 \uC5C6\uC5B4 \uB9E4\uCE6D\uC5D0\uC11C \uC81C\uC678\uD588\uC2B5\uB2C8\uB2E4 (Dooray API \uC751\uB2F5 mismatch \u2014 ADR-026).
1596
+ // ADR 번호 정정: ADR-026 ADR-028
1597
+ `\u26A0 ${skipped}\uAC1C \uADF8\uB8F9\uC5D0 code \uAC00 \uC5C6\uC5B4 \uB9E4\uCE6D\uC5D0\uC11C \uC81C\uC678\uD588\uC2B5\uB2C8\uB2E4 (ADR-028).
1598
+ id \uC9C1\uC811 \uC785\uB825 (15+\uC790\uB9AC numeric) \uB610\uB294 UI \uC218\uB3D9 cc / \`--cc <member>\` \uC6B0\uD68C \uAC00\uB2A5.
1584
1599
  `
1585
1600
  );
1586
1601
  }
1587
1602
  const adapter = valid.map((g) => ({ name: g.code, id: g.id, code: g.code }));
1588
1603
  const match = matchByName(adapter, input2, "\uADF8\uB8F9", (g) => `${g.code} (${g.id})`, {
1589
- helpHint: "dooray project groups <project>"
1604
+ helpHint: "\uC804\uCCB4 \uBAA9\uB85D: `dooray project groups <project>` / id \uC9C1\uC811 \uC785\uB825\uB3C4 \uAC00\uB2A5 (15+\uC790\uB9AC numeric \u2014 code \uB204\uB77D \uADF8\uB8F9\uB3C4 \uB9E4\uCE6D, ADR-028)"
1590
1605
  });
1591
1606
  return { id: match.id, code: match.code };
1592
1607
  }
@@ -5560,7 +5575,7 @@ function sanitizeArgv(argv) {
5560
5575
 
5561
5576
  // src/index.ts
5562
5577
  var program = new import_commander61.Command();
5563
- program.name("dooray").description("Dooray REST API CLI").version("0.10.0").option("--json", "JSON \uD615\uC2DD\uC73C\uB85C \uCD9C\uB825").option("--quiet", "ID\uB9CC \uCD9C\uB825").option("--no-color", "\uC0C9\uC0C1 \uBE44\uD65C\uC131\uD654");
5578
+ program.name("dooray").description("Dooray REST API CLI").version("0.10.1").option("--json", "JSON \uD615\uC2DD\uC73C\uB85C \uCD9C\uB825").option("--quiet", "ID\uB9CC \uCD9C\uB825").option("--no-color", "\uC0C9\uC0C1 \uBE44\uD65C\uC131\uD654");
5564
5579
  program.hook("preAction", () => {
5565
5580
  const opts = program.opts();
5566
5581
  if (opts.color === false || process.env.NO_COLOR) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bifos/dooray-cli",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "description": "CLI tool for Dooray project management — AI agent & terminal friendly",
5
5
  "keywords": [
6
6
  "dooray",
@@ -111,6 +111,7 @@ dooray doctor # 설정 검증
111
111
  | 참조자(cc) 멤버/그룹 추가 | `dooray post edit <project> <number> --cc-group <code>` — 기존 참조자 유지 + 그룹 추가 (dedupe, ADR-025) |
112
112
  | 참조자 전체 교체 | `dooray post edit <project> <number> --cc-clear --cc <name>` — 기존 참조자 비우고 신규 멤버만 |
113
113
  | 신규 업무 + 그룹 cc | `dooray post create <project> --title "..." --cc-group <code>` — 생성 시 그룹 참조자 포함 |
114
+ | `--cc-group <code\|id>` / `--mention-group <code\|id>` | 그룹 매칭 — 15+자리 numeric → id 직접 / 그 외 → code matchByName (부분일치, ADR-028) |
114
115
  | 상위 업무 설정/변경 | `dooray post edit <project> <number> --title "<원제목>" --parent <ref>` (`<ref>`: `<project>/<number>` 또는 raw postId. `--title` 필수, unset 미지원) |
115
116
  | `dooray post edit --id <postId> --tag <name>` | 태그 추가 (반복, dedupe) |
116
117
  | `dooray post edit --id <postId> --tag-clear --tag <name>` | 태그 전체 교체 |
@@ -451,6 +452,35 @@ dooray post comment latest <project> <number>
451
452
 
452
453
  ---
453
454
 
455
+ ## 그룹 멘션 / cc 시 AI agent 동선 (Issue #76, ADR-028)
456
+
457
+ 자연어 그룹명을 사용자가 지칭했을 때 AI agent 의 의사결정 순서:
458
+
459
+ 1. **사용자가 명확한 code 를 줬으면 바로 시도**
460
+ ```bash
461
+ dooray post create <project> --mention-group "<code>"
462
+ ```
463
+ 부분일치 가능 (예: "AI-Data" → "AI-Data파트" 매칭).
464
+
465
+ 2. **부분일치 모호 / 매칭 실패 시 후보 탐색**
466
+ ```bash
467
+ dooray project groups <project>
468
+ ```
469
+ ID + Code 표 출력.
470
+ AI agent 가 자연어 의도와 가장 가까운 code 선택 후 재시도.
471
+
472
+ 3. **모든 컬럼이 빈값일 때 (response shape 이상) 회피**
473
+ - ADR-028 fix 이후 거의 발생 안 함 (`fetchAllMemberGroups` 가 nested array 정규화)
474
+ - 만약 발생 시: 사용자에게 그룹 id (UI 의 그룹 URL 에서 19자리 numeric) 확인 요청
475
+ - `--cc-group <id>` / `--mention-group <id>` 직접 입력
476
+ - 또는 그룹 멤버를 개별 `--cc <member>` / `--mention <member>` 로 지정
477
+
478
+ 4. **모호한 자연어 매핑은 사용자에게 확인**
479
+ - 후보가 여러 개일 때 임의 선택 금지 — 사용자에게 선택지 제시
480
+ - 예: "AI-Data파트 / AI-Data실험팀 — 어느 그룹인가요?"
481
+
482
+ 순서 고정 — 멤버 먼저, 그룹 다음 (기존 정책 유지).
483
+
454
484
  ## 멘션·링크 자동 삽입 (first-class)
455
485
 
456
486
  `post create`, `post edit`, `post comment add`, `post comment edit` 모두 지원: