@bifos/dooray-cli 0.9.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/dist/index.js CHANGED
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/index.ts
27
- var import_commander48 = require("commander");
27
+ var import_commander61 = require("commander");
28
28
  var import_chalk7 = __toESM(require("chalk"));
29
29
 
30
30
  // src/commands/config.ts
@@ -801,6 +801,131 @@ var DoorayApiClient = class {
801
801
  throw await toDoorayCliError(e);
802
802
  }
803
803
  }
804
+ // ─── Wiki Page Files (ADR-029) ──────────────────────
805
+ async uploadWikiPageFile(wikiId, pageId, filePath, type) {
806
+ try {
807
+ const fileName = (0, import_node_path3.basename)(filePath);
808
+ const fileBuffer = await (0, import_promises3.readFile)(filePath);
809
+ const buildFormData = () => {
810
+ const fd = new FormData();
811
+ fd.append("type", type);
812
+ fd.append("file", new Blob([fileBuffer]), fileName);
813
+ return fd;
814
+ };
815
+ const url = `${this.baseUrl}wiki/v1/wikis/${wikiId}/pages/${pageId}/files`;
816
+ const res = await fetch(url, {
817
+ method: "POST",
818
+ headers: { Authorization: this.authHeader },
819
+ body: buildFormData(),
820
+ redirect: "manual"
821
+ });
822
+ if (res.status === 307) {
823
+ const location = res.headers.get("location");
824
+ if (!location) {
825
+ throw new DoorayCliError("\uC704\uD0A4 \uD30C\uC77C \uC5C5\uB85C\uB4DC \uB9AC\uB2E4\uC774\uB809\uD2B8 URL\uC744 \uBC1B\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.", EXIT_API_ERROR);
826
+ }
827
+ const uploadRes = await fetch(location, {
828
+ method: "POST",
829
+ headers: { Authorization: this.authHeader },
830
+ body: buildFormData()
831
+ });
832
+ if (!uploadRes.ok) {
833
+ throw new DoorayCliError(`\uC704\uD0A4 \uD30C\uC77C \uC5C5\uB85C\uB4DC \uC2E4\uD328 (${uploadRes.status})`, EXIT_API_ERROR);
834
+ }
835
+ return await uploadRes.json();
836
+ }
837
+ if (!res.ok) {
838
+ throw new DoorayCliError(`\uC704\uD0A4 \uD30C\uC77C \uC5C5\uB85C\uB4DC \uC2E4\uD328 (${res.status})`, EXIT_API_ERROR);
839
+ }
840
+ return await res.json();
841
+ } catch (e) {
842
+ if (e instanceof DoorayCliError) throw e;
843
+ throw await toDoorayCliError(e);
844
+ }
845
+ }
846
+ async downloadWikiPageFile(wikiId, pageId, fileId) {
847
+ try {
848
+ const res = await this.api.get(`wiki/v1/wikis/${wikiId}/pages/${pageId}/files/${fileId}`, {
849
+ redirect: "manual",
850
+ throwHttpErrors: false
851
+ });
852
+ if (res.status !== 307) {
853
+ throw new DoorayCliError(
854
+ `\uC704\uD0A4 \uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC \uC2E4\uD328 (\uC608\uC0C1 status 307, \uC2E4\uC81C ${res.status})`,
855
+ EXIT_API_ERROR
856
+ );
857
+ }
858
+ const location = res.headers.get("location");
859
+ if (!location) {
860
+ throw new DoorayCliError("\uC704\uD0A4 \uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC \uB9AC\uB2E4\uC774\uB809\uD2B8 URL\uC744 \uBC1B\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.", EXIT_API_ERROR);
861
+ }
862
+ const fileRes = await fetch(location, {
863
+ headers: { Authorization: this.authHeader }
864
+ });
865
+ if (!fileRes.ok) {
866
+ throw new DoorayCliError(`\uC704\uD0A4 \uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC \uC2E4\uD328 (${fileRes.status})`, EXIT_API_ERROR);
867
+ }
868
+ const disposition = fileRes.headers.get("content-disposition");
869
+ let fileName = `file-${fileId}`;
870
+ if (disposition) {
871
+ const match = disposition.match(/filename\*?=(?:UTF-8''|"?)([^";]+)/i);
872
+ if (match) fileName = (0, import_node_path3.basename)(decodeURIComponent(match[1].replace(/"/g, "")));
873
+ }
874
+ const buffer = await fileRes.arrayBuffer();
875
+ return { buffer, fileName };
876
+ } catch (e) {
877
+ if (e instanceof DoorayCliError) throw e;
878
+ throw await toDoorayCliError(e);
879
+ }
880
+ }
881
+ async deleteWikiPageFile(wikiId, pageId, fileId) {
882
+ try {
883
+ return await this.api.delete(`wiki/v1/wikis/${wikiId}/pages/${pageId}/files/${fileId}`).json();
884
+ } catch (e) {
885
+ throw await toDoorayCliError(e);
886
+ }
887
+ }
888
+ // ─── Wiki Page Comments ─────────────────────────────
889
+ async getWikiPageComments(wikiId, pageId, params) {
890
+ try {
891
+ return await this.api.get(`wiki/v1/wikis/${wikiId}/pages/${pageId}/comments`, {
892
+ searchParams: {
893
+ ...params?.page !== void 0 && { page: params.page },
894
+ ...params?.size !== void 0 && { size: params.size }
895
+ }
896
+ }).json();
897
+ } catch (e) {
898
+ throw await toDoorayCliError(e);
899
+ }
900
+ }
901
+ async getWikiPageComment(wikiId, pageId, commentId) {
902
+ try {
903
+ return await this.api.get(`wiki/v1/wikis/${wikiId}/pages/${pageId}/comments/${commentId}`).json();
904
+ } catch (e) {
905
+ throw await toDoorayCliError(e);
906
+ }
907
+ }
908
+ async addWikiPageComment(wikiId, pageId, body) {
909
+ try {
910
+ return await this.api.post(`wiki/v1/wikis/${wikiId}/pages/${pageId}/comments`, { json: body }).json();
911
+ } catch (e) {
912
+ throw await toDoorayCliError(e);
913
+ }
914
+ }
915
+ async updateWikiPageComment(wikiId, pageId, commentId, body) {
916
+ try {
917
+ return await this.api.put(`wiki/v1/wikis/${wikiId}/pages/${pageId}/comments/${commentId}`, { json: body }).json();
918
+ } catch (e) {
919
+ throw await toDoorayCliError(e);
920
+ }
921
+ }
922
+ async deleteWikiPageComment(wikiId, pageId, commentId) {
923
+ try {
924
+ return await this.api.delete(`wiki/v1/wikis/${wikiId}/pages/${pageId}/comments/${commentId}`).json();
925
+ } catch (e) {
926
+ throw await toDoorayCliError(e);
927
+ }
928
+ }
804
929
  // ─── Templates ──────────────────────────────────────
805
930
  async getProjectTemplates(projectId, params) {
806
931
  try {
@@ -1424,13 +1549,15 @@ var projectWorkflowsCommand = new import_commander7.Command("workflows").descrip
1424
1549
  var import_commander8 = require("commander");
1425
1550
 
1426
1551
  // src/resolvers/member-group.ts
1552
+ var GROUP_ID_RE = /^\d{15,}$/;
1427
1553
  async function fetchAllMemberGroups(client, projectId) {
1428
1554
  const all = [];
1429
1555
  let page = 0;
1430
1556
  const size = RESOLVER_FETCH_PAGE_SIZE;
1431
1557
  while (true) {
1432
1558
  const res = await client.getProjectMemberGroups(projectId, { page, size });
1433
- for (const g of res.result) {
1559
+ const groups = res.result.flat();
1560
+ for (const g of groups) {
1434
1561
  all.push({ id: g.id, code: g.code });
1435
1562
  }
1436
1563
  const total = res.totalCount ?? all.length;
@@ -1451,17 +1578,30 @@ function hasValidCode(g) {
1451
1578
  }
1452
1579
  async function resolveMemberGroup(client, projectId, input2) {
1453
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
+ }
1454
1592
  const valid = groups.filter(hasValidCode);
1455
1593
  const skipped = groups.length - valid.length;
1456
1594
  if (skipped > 0) {
1457
1595
  process.stderr.write(
1458
- `\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.
1459
1599
  `
1460
1600
  );
1461
1601
  }
1462
1602
  const adapter = valid.map((g) => ({ name: g.code, id: g.id, code: g.code }));
1463
1603
  const match = matchByName(adapter, input2, "\uADF8\uB8F9", (g) => `${g.code} (${g.id})`, {
1464
- 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)"
1465
1605
  });
1466
1606
  return { id: match.id, code: match.code };
1467
1607
  }
@@ -1854,6 +1994,7 @@ async function resolvePost(client, projectId, postNumber) {
1854
1994
  // src/utils/dooray-url.ts
1855
1995
  var TASK_URL_RE = /^https?:\/\/[\w.-]+\.dooray\.com\/task\/to\/(\d+)(?:[/?#].*)?$/;
1856
1996
  var TASK_URL_ALT_RE = /^https?:\/\/[\w.-]+\.dooray\.com\/task\/(?:\d+)\/(\d+)(?:[/?#].*)?$/;
1997
+ var WIKI_URL_RE = /^https?:\/\/[\w.-]+\.dooray\.com\/wiki\/(\d+)\/(\d+)(?:[/?#].*)?$/;
1857
1998
  function parseDoorayTaskUrl(input2) {
1858
1999
  const m1 = TASK_URL_RE.exec(input2);
1859
2000
  if (m1) return m1[1];
@@ -1861,6 +2002,11 @@ function parseDoorayTaskUrl(input2) {
1861
2002
  if (m2) return m2[1];
1862
2003
  return null;
1863
2004
  }
2005
+ function parseDoorayWikiUrl(input2) {
2006
+ const m = WIKI_URL_RE.exec(input2);
2007
+ if (!m) return null;
2008
+ return { wikiId: m[1], pageId: m[2] };
2009
+ }
1864
2010
  function isLikelyDoorayUrl(input2) {
1865
2011
  return /^https?:\/\//.test(input2);
1866
2012
  }
@@ -4034,122 +4180,790 @@ var wikiPageEditCommand = new import_commander38.Command("edit").description("\u
4034
4180
  `);
4035
4181
  });
4036
4182
 
4037
- // src/commands/member/index.ts
4038
- var import_commander42 = require("commander");
4183
+ // src/commands/wiki/page-file/index.ts
4184
+ var import_commander44 = require("commander");
4039
4185
 
4040
- // src/commands/member/get.ts
4186
+ // src/commands/wiki/page-file/list.ts
4041
4187
  var import_commander39 = require("commander");
4042
4188
 
4043
- // src/formatters/member.ts
4044
- function formatMemberDetail(member, opts) {
4045
- if (opts.json) {
4046
- printJson(member);
4047
- return;
4189
+ // src/resolvers/wiki-page-input.ts
4190
+ var INPUT_HELP2 = "\uC704\uD0A4 \uD398\uC774\uC9C0\uB97C \uC2DD\uBCC4\uD560 \uC815\uBCF4\uAC00 \uBD80\uC871\uD569\uB2C8\uB2E4. \uB2E4\uC74C \uC911 \uD558\uB098\uB97C \uC785\uB825\uD558\uC138\uC694:\n - <project> <page-id> \uC608: my-project 4071828729722696495\n - --id <page-id> --project <project> (\uB610\uB294 --url)\n - <Dooray URL> \uC608: https://x.dooray.com/wiki/<wikiId>/<pageId>";
4191
+ async function resolveWikiPageInput(client, args) {
4192
+ const { projectArg, pageIdArg, idOpt, urlOpt, project } = args;
4193
+ const hasPositional = !!projectArg || !!pageIdArg;
4194
+ if (idOpt && urlOpt) {
4195
+ throw new DoorayCliError("--id\uC640 --url\uC740 \uB3D9\uC2DC\uC5D0 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
4048
4196
  }
4049
- if (opts.quiet) {
4050
- process.stdout.write(member.id + "\n");
4051
- return;
4197
+ if ((idOpt || urlOpt) && hasPositional) {
4198
+ throw new DoorayCliError(
4199
+ "--id/--url\uACFC positional \uC778\uC790(<project> <page-id>)\uB294 \uB3D9\uC2DC\uC5D0 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
4200
+ EXIT_PARAM_ERROR
4201
+ );
4052
4202
  }
4053
- const lines = [
4054
- `\uC774\uB984: ${member.name}`,
4055
- ...member.englishName ? [`\uC601\uBB38\uBA85: ${member.englishName}`] : [],
4056
- ...member.nickname ? [`\uBCC4\uBA85: ${member.nickname}`] : [],
4057
- ...member.userCode ? [`\uC0AC\uBC88/ID: ${member.userCode}`] : [],
4058
- ...member.externalEmailAddress ? [`\uC678\uBD80 \uC774\uBA54\uC77C: ${member.externalEmailAddress}`] : [],
4059
- `member-id: ${member.id}`
4060
- ];
4061
- process.stdout.write(lines.join("\n") + "\n");
4062
- }
4063
- function formatMemberList(rows, opts) {
4064
- output(opts, {
4065
- headers: ["ID", "Name", "Role"],
4066
- rows: rows.map((r) => [r.id, r.name, r.role ?? ""]),
4067
- raw: rows,
4068
- ids: rows.map((r) => r.id)
4069
- });
4070
- }
4071
- function formatMemberSearchResults(members, opts) {
4072
- output(opts, {
4073
- headers: ["ID", "Name", "UserCode", "Nickname", "Email"],
4074
- rows: members.map((m) => [
4075
- m.id,
4076
- m.name,
4077
- m.userCode ?? "",
4078
- m.nickname ?? "",
4079
- m.externalEmailAddress ?? ""
4080
- ]),
4081
- raw: members,
4082
- ids: members.map((m) => m.id)
4083
- });
4203
+ if (urlOpt) {
4204
+ const parsed = parseDoorayWikiUrl(urlOpt);
4205
+ if (!parsed) {
4206
+ throw new DoorayCliError(
4207
+ `--url \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: "${urlOpt}"
4208
+ \uC608: https://x.dooray.com/wiki/<wikiId>/<pageId>`,
4209
+ EXIT_PARAM_ERROR
4210
+ );
4211
+ }
4212
+ return parsed;
4213
+ }
4214
+ if (projectArg && !pageIdArg && isLikelyDoorayUrl(projectArg)) {
4215
+ const parsed = parseDoorayWikiUrl(projectArg);
4216
+ if (!parsed) {
4217
+ throw new DoorayCliError(
4218
+ `Dooray Wiki URL \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: "${projectArg}"
4219
+ \uC608: https://x.dooray.com/wiki/<wikiId>/<pageId>`,
4220
+ EXIT_PARAM_ERROR
4221
+ );
4222
+ }
4223
+ return parsed;
4224
+ }
4225
+ if (idOpt) {
4226
+ const projectCode = project ?? projectArg;
4227
+ if (!projectCode) {
4228
+ throw new DoorayCliError(
4229
+ "--id \uBAA8\uB4DC\uB294 --project <code> \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4 (\uB610\uB294 \uCCAB positional \uC5D0 project code).",
4230
+ EXIT_PARAM_ERROR
4231
+ );
4232
+ }
4233
+ const wikiId = await resolveWiki(client, projectCode);
4234
+ return { wikiId, pageId: idOpt };
4235
+ }
4236
+ if (projectArg && pageIdArg) {
4237
+ const wikiId = await resolveWiki(client, projectArg);
4238
+ return { wikiId, pageId: pageIdArg };
4239
+ }
4240
+ throw new DoorayCliError(INPUT_HELP2, EXIT_PARAM_ERROR);
4084
4241
  }
4085
4242
 
4086
- // src/commands/member/get.ts
4087
- var memberGetCommand = new import_commander39.Command("get").description("\uBA64\uBC84 \uC0C1\uC138 \uC815\uBCF4 \uC870\uD68C (organizationMemberId)").argument("<member-id>", "\uC870\uD68C\uD560 organization member ID").action(async (memberId) => {
4088
- const globalOpts = memberGetCommand.optsWithGlobals();
4243
+ // src/commands/wiki/page-file/list.ts
4244
+ function formatSize3(bytes) {
4245
+ if (bytes < 1024) return `${bytes}B`;
4246
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
4247
+ return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
4248
+ }
4249
+ var wikiPageFileListCommand = new import_commander39.Command("list").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uCCA8\uBD80\uD30C\uC77C \uBAA9\uB85D \uC870\uD68C (general + inline image)").argument("[project]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (\uB610\uB294 \uCCAB \uC778\uC790\uC5D0 Dooray Wiki URL)").argument("[page-id]", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID (project\uC640 \uD568\uAED8 \uC0AC\uC6A9)").option("--id <pageId>", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID (--project \uB3D9\uBC18 \uD544\uC694)").option("--url <url>", "Dooray Wiki URL").option("--project <code>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (--id \uBAA8\uB4DC\uC5D0\uC11C wikiId \uD574\uC11D\uC6A9)").action(async (project, pageIdArg, opts) => {
4250
+ const globalOpts = wikiPageFileListCommand.optsWithGlobals();
4089
4251
  const config = await getConfigOrThrow();
4090
4252
  const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4091
- const res = await client.getMemberDetail(memberId);
4092
- formatMemberDetail(res.result, globalOpts);
4253
+ const { wikiId, pageId } = await resolveWikiPageInput(client, {
4254
+ projectArg: project,
4255
+ pageIdArg,
4256
+ idOpt: opts.id,
4257
+ urlOpt: opts.url,
4258
+ project: opts.project
4259
+ });
4260
+ startSpinner("\uCCA8\uBD80\uD30C\uC77C \uBAA9\uB85D \uC870\uD68C \uC911...");
4261
+ try {
4262
+ const res = await client.getWikiPage(wikiId, pageId);
4263
+ const files = (res.result.files ?? []).map((f) => ({ ...f, type: "general" }));
4264
+ const images = (res.result.images ?? []).map((f) => ({ ...f, type: "inline_image" }));
4265
+ const merged = [...files, ...images];
4266
+ stopSpinner(true, `\uCCA8\uBD80\uD30C\uC77C ${merged.length}\uAC1C (general ${files.length} + inline ${images.length})`);
4267
+ output(globalOpts, {
4268
+ headers: ["ID", "Type", "\uD30C\uC77C\uBA85", "\uD06C\uAE30"],
4269
+ rows: merged.map((f) => [f.id, f.type, f.name, formatSize3(f.size)]),
4270
+ raw: merged,
4271
+ ids: merged.map((f) => f.id)
4272
+ });
4273
+ } catch (e) {
4274
+ stopSpinner(false);
4275
+ throw e;
4276
+ }
4093
4277
  });
4094
4278
 
4095
- // src/commands/member/list.ts
4279
+ // src/commands/wiki/page-file/upload.ts
4096
4280
  var import_commander40 = require("commander");
4097
- var memberListCommand = new import_commander40.Command("list").description("\uD504\uB85C\uC81D\uD2B8 \uBA64\uBC84 \uBAA9\uB85D").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").action(async (project) => {
4098
- const globalOpts = memberListCommand.optsWithGlobals();
4281
+ var wikiPageFileUploadCommand = new import_commander40.Command("upload").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uCCA8\uBD80\uD30C\uC77C \uC5C5\uB85C\uB4DC (multipart type \uC21C\uC11C \uAC15\uC81C, ADR-029)").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray Wiki URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C \uACBD\uB85C").argument("[arg2]", "page-id \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C \uACBD\uB85C").argument("[arg3]", "\uD30C\uC77C \uACBD\uB85C (positional 3\uAC1C \uBAA8\uB4DC)").option("--id <pageId>", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID").option("--url <url>", "Dooray Wiki URL").option("--project <code>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (--id \uBAA8\uB4DC\uC5D0\uC11C wikiId \uD574\uC11D\uC6A9)").option("--file <path>", "\uC5C5\uB85C\uB4DC\uD560 \uD30C\uC77C \uACBD\uB85C (positional \uB300\uCCB4)").option("--type <type>", "\uD30C\uC77C \uD0C0\uC785: general | inline_image (\uAE30\uBCF8 general)", "general").action(async (arg1, arg2, arg3, opts) => {
4099
4282
  const config = await getConfigOrThrow();
4100
4283
  const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4101
- startSpinner("\uBA64\uBC84 \uBAA9\uB85D \uC870\uD68C \uC911...");
4102
- const projectId = await resolveProject(client, project);
4103
- const members = await ensureMembers(client, projectId);
4104
- stopSpinner(true, `${members.length}\uBA85`);
4105
- formatMemberList(
4106
- members.map((m) => ({ id: m.organizationMemberId, name: m.name })),
4107
- globalOpts
4108
- );
4109
- });
4110
-
4111
- // src/commands/member/search.ts
4112
- var import_commander41 = require("commander");
4113
- var memberSearchCommand = new import_commander41.Command("search").description("organization \uC804\uCCB4\uC5D0\uC11C \uBA64\uBC84 \uAC80\uC0C9").argument("[keyword]", "\uC774\uB984 \uAC80\uC0C9\uC5B4 (--email/--user-code \uBBF8\uC9C0\uC815 \uC2DC name\uC73C\uB85C \uAC80\uC0C9)").option("--email <email>", "\uC678\uBD80 \uC774\uBA54\uC77C (\uCF64\uB9C8 \uAD6C\uBD84 \uAC00\uB2A5, exact match)").option("--user-code <code>", "\uC0AC\uBC88 like \uAC80\uC0C9").option("--user-code-exact <code>", "\uC0AC\uBC88 exact match").option("--page <n>", "\uD398\uC774\uC9C0 (\uAE30\uBCF8 0)", "0").option("--size <n>", "\uD398\uC774\uC9C0 \uD06C\uAE30 (\uAE30\uBCF8 20, max 100)", "20").action(async (keyword, opts) => {
4114
- const globalOpts = memberSearchCommand.optsWithGlobals();
4115
- const filterCount = [keyword, opts.email, opts.userCode, opts.userCodeExact].filter(Boolean).length;
4116
- if (filterCount === 0) {
4284
+ const fileType = opts.type;
4285
+ if (fileType !== "general" && fileType !== "inline_image") {
4117
4286
  throw new DoorayCliError(
4118
- "\uAC80\uC0C9 \uC870\uAC74\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. positional <keyword>(=name) \uB610\uB294 --email/--user-code/--user-code-exact \uC911 \uD558\uB098 \uC774\uC0C1.",
4287
+ `--type \uC740 general \uB610\uB294 inline_image \uC5EC\uC57C \uD569\uB2C8\uB2E4 (\uC785\uB825: ${opts.type})`,
4119
4288
  EXIT_PARAM_ERROR
4120
4289
  );
4121
4290
  }
4122
- if (keyword && (opts.email || opts.userCode || opts.userCodeExact)) {
4123
- throw new DoorayCliError(
4124
- "positional <keyword>(name)\uC640 --email/--user-code/--user-code-exact \uC635\uC158\uC740 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00.",
4125
- EXIT_PARAM_ERROR
4126
- );
4291
+ let projectArg;
4292
+ let pageIdArg;
4293
+ let filePath = opts.file;
4294
+ if (opts.id || opts.url) {
4295
+ if (arg2 || arg3) {
4296
+ throw new DoorayCliError(
4297
+ "--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uD30C\uC77C \uACBD\uB85C \uC678 positional \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. --file \uC635\uC158 \uC0AC\uC6A9\uC744 \uAD8C\uC7A5\uD569\uB2C8\uB2E4.",
4298
+ EXIT_PARAM_ERROR
4299
+ );
4300
+ }
4301
+ filePath = filePath ?? arg1;
4302
+ } else if (arg3) {
4303
+ projectArg = arg1;
4304
+ pageIdArg = arg2;
4305
+ filePath = filePath ?? arg3;
4306
+ } else if (arg1 && !arg2) {
4307
+ projectArg = arg1;
4308
+ if (!filePath) {
4309
+ throw new DoorayCliError(
4310
+ "URL/--id \uBAA8\uB4DC \uC678\uC5D0\uC11C\uB294 <project> <page-id> \uB458 \uB2E4 \uB610\uB294 --file \uC635\uC158\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
4311
+ EXIT_PARAM_ERROR
4312
+ );
4313
+ }
4314
+ } else {
4315
+ projectArg = arg1;
4316
+ pageIdArg = arg2;
4317
+ if (!filePath) {
4318
+ throw new DoorayCliError(
4319
+ "<file> \uC774 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --file \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
4320
+ EXIT_PARAM_ERROR
4321
+ );
4322
+ }
4127
4323
  }
4128
- const config = await getConfigOrThrow();
4129
- const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4130
- const size = Math.min(Math.max(1, Number(opts.size) || 20), 100);
4131
- const page = Math.max(0, Number(opts.page) || 0);
4132
- startSpinner("\uBA64\uBC84 \uAC80\uC0C9 \uC911...");
4133
- const res = await client.searchMembers({
4134
- ...keyword && { name: keyword },
4135
- ...opts.email && { externalEmailAddresses: opts.email },
4136
- ...opts.userCode && { userCode: opts.userCode },
4137
- ...opts.userCodeExact && { userCodeExact: opts.userCodeExact },
4138
- page,
4139
- size
4324
+ if (!filePath) {
4325
+ throw new DoorayCliError("\uD30C\uC77C \uACBD\uB85C\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
4326
+ }
4327
+ const { wikiId, pageId } = await resolveWikiPageInput(client, {
4328
+ projectArg,
4329
+ pageIdArg,
4330
+ idOpt: opts.id,
4331
+ urlOpt: opts.url,
4332
+ project: opts.project
4140
4333
  });
4141
- stopSpinner(true, `${res.totalCount}\uAC74 (\uC774 \uD398\uC774\uC9C0 ${res.result.length})`);
4142
- formatMemberSearchResults(res.result, globalOpts);
4143
- });
4334
+ startSpinner(`\uD30C\uC77C \uC5C5\uB85C\uB4DC \uC911... (${fileType})`);
4335
+ try {
4336
+ const res = await client.uploadWikiPageFile(wikiId, pageId, filePath, fileType);
4337
+ stopSpinner(true, "\uC5C5\uB85C\uB4DC \uC644\uB8CC");
4338
+ process.stdout.write(`attachFileId: ${res.result.attachFileId}
4339
+ `);
4340
+ process.stdout.write(`name: ${res.result.name}
4341
+ `);
4342
+ process.stdout.write(`size: ${res.result.size}
4343
+ `);
4344
+ process.stdout.write(`type: ${res.result.type}
4345
+ `);
4346
+ if (fileType === "inline_image") {
4347
+ process.stdout.write("\n\uBCF8\uBB38 \uC0BD\uC785\uC6A9 markdown snippet (\uC9C1\uC811 wiki page edit \uC73C\uB85C \uBCF8\uBB38\uC5D0 \uBC15\uC73C\uC138\uC694):\n");
4348
+ process.stdout.write(` ![${res.result.name}](/wikis/${wikiId}/files/${res.result.attachFileId})
4349
+ `);
4350
+ }
4351
+ } catch (e) {
4352
+ stopSpinner(false);
4353
+ throw e;
4354
+ }
4355
+ });
4356
+
4357
+ // src/commands/wiki/page-file/download.ts
4358
+ var import_commander41 = require("commander");
4359
+ var import_promises11 = require("fs/promises");
4360
+ var import_node_path9 = require("path");
4361
+ var wikiPageFileDownloadCommand = new import_commander41.Command("download").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uCCA8\uBD80\uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray Wiki URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg2]", "page-id \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg3]", "\uD30C\uC77C ID (positional 3\uAC1C \uBAA8\uB4DC)").option("--id <pageId>", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID").option("--url <url>", "Dooray Wiki URL").option("--project <code>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (--id \uBAA8\uB4DC\uC5D0\uC11C wikiId \uD574\uC11D\uC6A9)").option("--file-id <fileId>", "\uD30C\uC77C ID (positional \uB300\uCCB4)").option("-o, --output <dir>", "\uC800\uC7A5 \uB514\uB809\uD1A0\uB9AC", ".").action(async (arg1, arg2, arg3, opts) => {
4362
+ const config = await getConfigOrThrow();
4363
+ const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4364
+ let projectArg;
4365
+ let pageIdArg;
4366
+ let fileId = opts.fileId;
4367
+ if (opts.id || opts.url) {
4368
+ if (arg2 || arg3) {
4369
+ throw new DoorayCliError(
4370
+ "--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uD30C\uC77C ID \uC678 \uCD94\uAC00 positional \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. --file-id \uC635\uC158 \uC0AC\uC6A9\uC744 \uAD8C\uC7A5\uD569\uB2C8\uB2E4.",
4371
+ EXIT_PARAM_ERROR
4372
+ );
4373
+ }
4374
+ fileId = fileId ?? arg1;
4375
+ } else if (arg3) {
4376
+ projectArg = arg1;
4377
+ pageIdArg = arg2;
4378
+ fileId = fileId ?? arg3;
4379
+ } else if (arg1 && !arg2) {
4380
+ projectArg = arg1;
4381
+ if (!fileId) {
4382
+ throw new DoorayCliError(
4383
+ "URL/--id \uBAA8\uB4DC\uC5D0\uC11C\uB294 --file-id \uC635\uC158\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
4384
+ EXIT_PARAM_ERROR
4385
+ );
4386
+ }
4387
+ } else {
4388
+ projectArg = arg1;
4389
+ pageIdArg = arg2;
4390
+ if (!fileId) {
4391
+ throw new DoorayCliError(
4392
+ "<file-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --file-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
4393
+ EXIT_PARAM_ERROR
4394
+ );
4395
+ }
4396
+ }
4397
+ if (!fileId) {
4398
+ throw new DoorayCliError("\uD30C\uC77C ID\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
4399
+ }
4400
+ const { wikiId, pageId } = await resolveWikiPageInput(client, {
4401
+ projectArg,
4402
+ pageIdArg,
4403
+ idOpt: opts.id,
4404
+ urlOpt: opts.url,
4405
+ project: opts.project
4406
+ });
4407
+ startSpinner("\uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC \uC911...");
4408
+ try {
4409
+ const { buffer, fileName } = await client.downloadWikiPageFile(wikiId, pageId, fileId);
4410
+ const outputPath = (0, import_node_path9.join)(opts.output, (0, import_node_path9.basename)(fileName));
4411
+ await (0, import_promises11.writeFile)(outputPath, Buffer.from(buffer));
4412
+ stopSpinner(true, `\uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC: ${outputPath}`);
4413
+ process.stdout.write(`${outputPath}
4414
+ `);
4415
+ } catch (e) {
4416
+ stopSpinner(false);
4417
+ throw e;
4418
+ }
4419
+ });
4420
+
4421
+ // src/commands/wiki/page-file/download-all.ts
4422
+ var import_commander42 = require("commander");
4423
+ var import_promises12 = require("fs/promises");
4424
+ var import_node_path10 = require("path");
4425
+ var wikiPageFileDownloadAllCommand = new import_commander42.Command("download-all").description("\uC704\uD0A4 \uD398\uC774\uC9C0\uC758 \uBAA8\uB4E0 \uCCA8\uBD80\uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC (general + inline image)").argument("[project]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (\uB610\uB294 \uCCAB \uC778\uC790\uC5D0 Dooray Wiki URL)").argument("[page-id]", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID (project\uC640 \uD568\uAED8 \uC0AC\uC6A9)").option("--id <pageId>", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID (--project \uB3D9\uBC18 \uD544\uC694)").option("--url <url>", "Dooray Wiki URL").option("--project <code>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (--id \uBAA8\uB4DC\uC5D0\uC11C wikiId \uD574\uC11D\uC6A9)").option("-o, --output <dir>", "\uC800\uC7A5 \uB514\uB809\uD1A0\uB9AC", ".").action(async (project, pageIdArg, opts) => {
4426
+ const config = await getConfigOrThrow();
4427
+ const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4428
+ const { wikiId, pageId } = await resolveWikiPageInput(client, {
4429
+ projectArg: project,
4430
+ pageIdArg,
4431
+ idOpt: opts.id,
4432
+ urlOpt: opts.url,
4433
+ project: opts.project
4434
+ });
4435
+ startSpinner("\uD30C\uC77C \uBAA9\uB85D \uC870\uD68C \uC911...");
4436
+ let allFiles;
4437
+ try {
4438
+ const pageRes = await client.getWikiPage(wikiId, pageId);
4439
+ allFiles = [...pageRes.result.files ?? [], ...pageRes.result.images ?? []];
4440
+ } catch (e) {
4441
+ stopSpinner(false);
4442
+ throw e;
4443
+ }
4444
+ if (allFiles.length === 0) {
4445
+ stopSpinner(true, "\uCCA8\uBD80\uD30C\uC77C \uC5C6\uC74C");
4446
+ process.stdout.write("\uCCA8\uBD80\uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n");
4447
+ return;
4448
+ }
4449
+ stopSpinner(true, `${allFiles.length}\uAC1C \uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC \uC2DC\uC791`);
4450
+ await (0, import_promises12.mkdir)(opts.output, { recursive: true });
4451
+ let successCount = 0;
4452
+ const failures = [];
4453
+ for (const f of allFiles) {
4454
+ try {
4455
+ const { buffer, fileName } = await client.downloadWikiPageFile(wikiId, pageId, f.id);
4456
+ await (0, import_promises12.writeFile)((0, import_node_path10.join)(opts.output, fileName), Buffer.from(buffer));
4457
+ process.stdout.write(`\u2713 ${fileName}
4458
+ `);
4459
+ successCount++;
4460
+ } catch (e) {
4461
+ failures.push({ fileId: f.id, error: e instanceof Error ? e.message : String(e) });
4462
+ process.stderr.write(`\u2717 ${f.name} (${f.id}): ${e instanceof Error ? e.message : String(e)}
4463
+ `);
4464
+ }
4465
+ }
4466
+ process.stdout.write(`
4467
+ \uC644\uB8CC: ${successCount}/${allFiles.length}
4468
+ `);
4469
+ if (failures.length > 0) {
4470
+ throw new DoorayCliError(
4471
+ `${failures.length}\uAC1C \uD30C\uC77C \uB2E4\uC6B4\uB85C\uB4DC \uC2E4\uD328 (\uC131\uACF5: ${successCount}/${allFiles.length})`,
4472
+ EXIT_API_ERROR
4473
+ );
4474
+ }
4475
+ });
4476
+
4477
+ // src/commands/wiki/page-file/delete.ts
4478
+ var import_commander43 = require("commander");
4479
+ var wikiPageFileDeleteCommand = new import_commander43.Command("delete").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uCCA8\uBD80\uD30C\uC77C \uC0AD\uC81C").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC, Dooray Wiki URL, \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg2]", "page-id \uB610\uB294 (`--id`/`--url` \uBAA8\uB4DC\uC77C \uB54C) \uD30C\uC77C ID").argument("[arg3]", "\uD30C\uC77C ID (positional 3\uAC1C \uBAA8\uB4DC)").option("--id <pageId>", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID").option("--url <url>", "Dooray Wiki URL").option("--project <code>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (--id \uBAA8\uB4DC\uC5D0\uC11C wikiId \uD574\uC11D\uC6A9)").option("--file-id <fileId>", "\uD30C\uC77C ID (positional \uB300\uCCB4)").action(async (arg1, arg2, arg3, opts) => {
4480
+ const config = await getConfigOrThrow();
4481
+ const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4482
+ let projectArg;
4483
+ let pageIdArg;
4484
+ let fileId = opts.fileId;
4485
+ if (opts.id || opts.url) {
4486
+ if (arg2 || arg3) {
4487
+ throw new DoorayCliError(
4488
+ "--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uD30C\uC77C ID \uC678 \uCD94\uAC00 positional \uC778\uC790\uB97C \uBC1B\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. --file-id \uC635\uC158 \uC0AC\uC6A9\uC744 \uAD8C\uC7A5\uD569\uB2C8\uB2E4.",
4489
+ EXIT_PARAM_ERROR
4490
+ );
4491
+ }
4492
+ fileId = fileId ?? arg1;
4493
+ } else if (arg3) {
4494
+ projectArg = arg1;
4495
+ pageIdArg = arg2;
4496
+ fileId = fileId ?? arg3;
4497
+ } else if (arg1 && !arg2) {
4498
+ projectArg = arg1;
4499
+ if (!fileId) {
4500
+ throw new DoorayCliError(
4501
+ "URL/--id \uBAA8\uB4DC\uC5D0\uC11C\uB294 --file-id \uC635\uC158\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
4502
+ EXIT_PARAM_ERROR
4503
+ );
4504
+ }
4505
+ } else {
4506
+ projectArg = arg1;
4507
+ pageIdArg = arg2;
4508
+ if (!fileId) {
4509
+ throw new DoorayCliError(
4510
+ "<file-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --file-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
4511
+ EXIT_PARAM_ERROR
4512
+ );
4513
+ }
4514
+ }
4515
+ if (!fileId) {
4516
+ throw new DoorayCliError("\uD30C\uC77C ID\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.", EXIT_PARAM_ERROR);
4517
+ }
4518
+ const { wikiId, pageId } = await resolveWikiPageInput(client, {
4519
+ projectArg,
4520
+ pageIdArg,
4521
+ idOpt: opts.id,
4522
+ urlOpt: opts.url,
4523
+ project: opts.project
4524
+ });
4525
+ startSpinner("\uD30C\uC77C \uC0AD\uC81C \uC911...");
4526
+ try {
4527
+ await client.deleteWikiPageFile(wikiId, pageId, fileId);
4528
+ stopSpinner(true, "\uC0AD\uC81C \uC644\uB8CC");
4529
+ process.stdout.write(`\uD30C\uC77C(${fileId})\uC774 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
4530
+ `);
4531
+ } catch (e) {
4532
+ stopSpinner(false);
4533
+ throw e;
4534
+ }
4535
+ });
4536
+
4537
+ // src/commands/wiki/page-file/index.ts
4538
+ var wikiPageFileCommand = new import_commander44.Command("file").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uCCA8\uBD80\uD30C\uC77C \uAD00\uB828 \uBA85\uB839 (Issue #70, ADR-029)");
4539
+ wikiPageFileCommand.addCommand(wikiPageFileListCommand);
4540
+ wikiPageFileCommand.addCommand(wikiPageFileUploadCommand);
4541
+ wikiPageFileCommand.addCommand(wikiPageFileDownloadCommand);
4542
+ wikiPageFileCommand.addCommand(wikiPageFileDownloadAllCommand);
4543
+ wikiPageFileCommand.addCommand(wikiPageFileDeleteCommand);
4544
+
4545
+ // src/commands/wiki/page-comment/index.ts
4546
+ var import_commander51 = require("commander");
4547
+
4548
+ // src/commands/wiki/page-comment/list.ts
4549
+ var import_commander45 = require("commander");
4550
+
4551
+ // src/formatters/wiki-comment.ts
4552
+ function formatWikiCommentList(comments, opts) {
4553
+ output(opts.globalOpts, {
4554
+ headers: ["ID", "\uC791\uC131\uC790", "\uC0DD\uC131\uC77C", "\uBCF8\uBB38 (\uC694\uC57D)"],
4555
+ rows: comments.map((c) => [
4556
+ c.id,
4557
+ c.creator.member.name,
4558
+ c.createdAt,
4559
+ truncate(c.body.content, 60)
4560
+ ]),
4561
+ raw: comments,
4562
+ ids: comments.map((c) => c.id)
4563
+ });
4564
+ }
4565
+ function formatWikiCommentDetail(comment, globalOpts) {
4566
+ if (globalOpts.json) {
4567
+ printJson(comment);
4568
+ return;
4569
+ }
4570
+ if (globalOpts.quiet) {
4571
+ printQuiet([comment.id]);
4572
+ return;
4573
+ }
4574
+ process.stdout.write(`ID: ${comment.id}
4575
+ `);
4576
+ process.stdout.write(`Page ID: ${comment.page.id}
4577
+ `);
4578
+ process.stdout.write(`\uC791\uC131\uC790: ${comment.creator.member.name}
4579
+ `);
4580
+ process.stdout.write(`\uC0DD\uC131\uC77C: ${comment.createdAt}
4581
+ `);
4582
+ if (comment.modifiedAt && comment.modifiedAt !== comment.createdAt) {
4583
+ process.stdout.write(`\uC218\uC815\uC77C: ${comment.modifiedAt}
4584
+ `);
4585
+ }
4586
+ process.stdout.write(`
4587
+ ${comment.body.content}
4588
+ `);
4589
+ }
4590
+ function truncate(s, n) {
4591
+ const oneLine = s.replace(/\s+/g, " ").trim();
4592
+ return oneLine.length <= n ? oneLine : oneLine.slice(0, n - 1) + "\u2026";
4593
+ }
4594
+
4595
+ // src/commands/wiki/page-comment/list.ts
4596
+ var wikiPageCommentListCommand = new import_commander45.Command("list").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uB313\uAE00 \uBAA9\uB85D \uC870\uD68C (\uCD5C\uC2E0\uC21C)").argument("[project]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (\uB610\uB294 \uCCAB \uC778\uC790\uC5D0 Dooray Wiki URL)").argument("[page-id]", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID").option("--id <pageId>", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID (--project \uB3D9\uBC18)").option("--url <url>", "Dooray Wiki URL").option("--project <code>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (--id \uBAA8\uB4DC\uC6A9)").option("--size <n>", "\uD398\uC774\uC9C0 \uD06C\uAE30 (\uAE30\uBCF8 20, \uCD5C\uB300 100)", (v) => parseInt(v, 10)).option("--page <n>", "\uD398\uC774\uC9C0 \uBC88\uD638 (0\uBD80\uD130)", (v) => parseInt(v, 10)).option("--latest <n>", "\uCD5C\uC2E0 N\uAC1C\uB9CC (size \uB300\uC2E0 \uC0AC\uC6A9)", (v) => parseInt(v, 10)).action(async (project, pageIdArg, opts) => {
4597
+ const globalOpts = wikiPageCommentListCommand.optsWithGlobals();
4598
+ const config = await getConfigOrThrow();
4599
+ const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4600
+ const { wikiId, pageId } = await resolveWikiPageInput(client, {
4601
+ projectArg: project,
4602
+ pageIdArg,
4603
+ idOpt: opts.id,
4604
+ urlOpt: opts.url,
4605
+ project: opts.project
4606
+ });
4607
+ const size = opts.latest ?? opts.size ?? 20;
4608
+ const page = opts.page ?? 0;
4609
+ startSpinner("\uB313\uAE00 \uBAA9\uB85D \uC870\uD68C \uC911...");
4610
+ try {
4611
+ const res = await client.getWikiPageComments(wikiId, pageId, { size, page });
4612
+ stopSpinner(true, `\uB313\uAE00 ${res.result.length}\uAC74 (\uCD1D ${res.totalCount})`);
4613
+ formatWikiCommentList(res.result, { globalOpts, totalCount: res.totalCount });
4614
+ } catch (e) {
4615
+ stopSpinner(false);
4616
+ throw e;
4617
+ }
4618
+ });
4619
+
4620
+ // src/commands/wiki/page-comment/latest.ts
4621
+ var import_commander46 = require("commander");
4622
+ var wikiPageCommentLatestCommand = new import_commander46.Command("latest").description("\uCD5C\uC2E0 \uB313\uAE00 1\uAC74 \uC870\uD68C (= comment list --latest 1)").argument("[project]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (\uB610\uB294 \uCCAB \uC778\uC790\uC5D0 Dooray Wiki URL)").argument("[page-id]", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID").option("--id <pageId>", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID (--project \uB3D9\uBC18)").option("--url <url>", "Dooray Wiki URL").option("--project <code>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (--id \uBAA8\uB4DC\uC6A9)").action(async (project, pageIdArg, opts) => {
4623
+ const globalOpts = wikiPageCommentLatestCommand.optsWithGlobals();
4624
+ const config = await getConfigOrThrow();
4625
+ const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4626
+ const { wikiId, pageId } = await resolveWikiPageInput(client, {
4627
+ projectArg: project,
4628
+ pageIdArg,
4629
+ idOpt: opts.id,
4630
+ urlOpt: opts.url,
4631
+ project: opts.project
4632
+ });
4633
+ startSpinner("\uCD5C\uC2E0 \uB313\uAE00 \uC870\uD68C \uC911...");
4634
+ try {
4635
+ const res = await client.getWikiPageComments(wikiId, pageId, { size: 1, page: 0 });
4636
+ stopSpinner(true, res.result.length > 0 ? "\uCD5C\uC2E0 \uB313\uAE00" : "\uB313\uAE00 \uC5C6\uC74C");
4637
+ if (res.result.length === 0) {
4638
+ process.stdout.write("\uB313\uAE00\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n");
4639
+ return;
4640
+ }
4641
+ formatWikiCommentDetail(res.result[0], globalOpts);
4642
+ } catch (e) {
4643
+ stopSpinner(false);
4644
+ throw e;
4645
+ }
4646
+ });
4647
+
4648
+ // src/commands/wiki/page-comment/get.ts
4649
+ var import_commander47 = require("commander");
4650
+
4651
+ // src/commands/wiki/page-comment/parse-args.ts
4652
+ function parseWikiCommentArgs(arg1, arg2, arg3, opts) {
4653
+ const hasPositional = arg1 !== void 0 || arg2 !== void 0 || arg3 !== void 0;
4654
+ const hasIdUrl = !!(opts.id || opts.url);
4655
+ if (hasPositional && hasIdUrl) {
4656
+ throw new DoorayCliError(
4657
+ "positional \uC778\uC790\uC640 --id/--url \uC635\uC158\uC740 \uB3D9\uC2DC\uC5D0 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
4658
+ EXIT_PARAM_ERROR
4659
+ );
4660
+ }
4661
+ if (hasIdUrl) {
4662
+ if (!opts.commentId) {
4663
+ throw new DoorayCliError(
4664
+ "--id/--url \uBAA8\uB4DC\uC5D0\uC11C\uB294 --comment-id \uC635\uC158\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.",
4665
+ EXIT_PARAM_ERROR
4666
+ );
4667
+ }
4668
+ return {
4669
+ commentId: opts.commentId,
4670
+ idOpt: opts.id,
4671
+ urlOpt: opts.url,
4672
+ projectOpt: opts.project
4673
+ };
4674
+ }
4675
+ if (arg3) {
4676
+ if (opts.commentId) {
4677
+ throw new DoorayCliError(
4678
+ "positional \uB313\uAE00 ID \uC640 --comment-id \uC635\uC158\uC740 \uB3D9\uC2DC\uC5D0 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
4679
+ EXIT_PARAM_ERROR
4680
+ );
4681
+ }
4682
+ return {
4683
+ projectArg: arg1,
4684
+ pageIdArg: arg2,
4685
+ commentId: arg3
4686
+ };
4687
+ }
4688
+ if (arg1 && arg2 && opts.commentId) {
4689
+ return {
4690
+ projectArg: arg1,
4691
+ pageIdArg: arg2,
4692
+ commentId: opts.commentId
4693
+ };
4694
+ }
4695
+ throw new DoorayCliError(
4696
+ "<comment-id>\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. positional 3\uBC88\uC9F8 \uB610\uB294 --comment-id \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.",
4697
+ EXIT_PARAM_ERROR
4698
+ );
4699
+ }
4700
+
4701
+ // src/commands/wiki/page-comment/get.ts
4702
+ var wikiPageCommentGetCommand = new import_commander47.Command("get").description("\uB2E8\uC77C \uB313\uAE00 \uC870\uD68C").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC / Dooray Wiki URL (\uBAA8\uB4DC\uBCC4)").argument("[arg2]", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID (\uBAA8\uB4DC\uBCC4)").argument("[arg3]", "\uB313\uAE00 ID (positional 3\uAC1C \uBAA8\uB4DC)").option("--id <pageId>", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID (positional \uB300\uC2E0)").option("--url <url>", "Dooray Wiki URL (positional \uB300\uC2E0)").option("--project <code>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (--id \uBAA8\uB4DC\uC6A9)").option("--comment-id <id>", "\uB313\uAE00 ID (arg3 \uB300\uC2E0)").action(async (arg1, arg2, arg3, opts) => {
4703
+ const parsed = parseWikiCommentArgs(arg1, arg2, arg3, opts);
4704
+ const config = await getConfigOrThrow();
4705
+ const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4706
+ const globalOpts = wikiPageCommentGetCommand.optsWithGlobals();
4707
+ const { wikiId, pageId } = await resolveWikiPageInput(client, {
4708
+ projectArg: parsed.projectArg,
4709
+ pageIdArg: parsed.pageIdArg,
4710
+ idOpt: parsed.idOpt,
4711
+ urlOpt: parsed.urlOpt,
4712
+ project: parsed.projectOpt
4713
+ });
4714
+ startSpinner("\uB313\uAE00 \uC870\uD68C \uC911...");
4715
+ try {
4716
+ const detail = await client.getWikiPageComment(wikiId, pageId, parsed.commentId);
4717
+ stopSpinner(true, "\uB313\uAE00 \uC870\uD68C \uC644\uB8CC");
4718
+ formatWikiCommentDetail(detail.result, globalOpts);
4719
+ } catch (e) {
4720
+ stopSpinner(false);
4721
+ throw e;
4722
+ }
4723
+ });
4724
+
4725
+ // src/commands/wiki/page-comment/add.ts
4726
+ var import_commander48 = require("commander");
4727
+ var wikiPageCommentAddCommand = new import_commander48.Command("add").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uB313\uAE00 \uCD94\uAC00 (--body \uC5C6\uC73C\uBA74 $EDITOR)").argument("[project]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (\uB610\uB294 \uCCAB \uC778\uC790\uC5D0 Dooray Wiki URL)").argument("[page-id]", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID").option("--id <pageId>", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID (--project \uB3D9\uBC18)").option("--url <url>", "Dooray Wiki URL").option("--project <code>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (--id \uBAA8\uB4DC\uC6A9)").option("--body <text>", "\uB313\uAE00 \uBCF8\uBB38 (- \uC785\uB825 \uC2DC stdin\uC5D0\uC11C \uC77D\uAE30)").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C (- \uC785\uB825 \uC2DC stdin\uC5D0\uC11C \uC77D\uAE30)").action(async (project, pageIdArg, opts) => {
4728
+ if ((opts.id || opts.url) && (project || pageIdArg)) {
4729
+ throw new DoorayCliError(
4730
+ "positional \uC778\uC790\uC640 --id/--url \uC635\uC158\uC740 \uB3D9\uC2DC\uC5D0 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.",
4731
+ EXIT_PARAM_ERROR
4732
+ );
4733
+ }
4734
+ const globalOpts = wikiPageCommentAddCommand.optsWithGlobals();
4735
+ const config = await getConfigOrThrow();
4736
+ const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4737
+ const { wikiId, pageId } = await resolveWikiPageInput(client, {
4738
+ projectArg: project,
4739
+ pageIdArg,
4740
+ idOpt: opts.id,
4741
+ urlOpt: opts.url,
4742
+ project: opts.project
4743
+ });
4744
+ let bodyContent = await readBodyInputOrNull(opts);
4745
+ if (bodyContent == null) {
4746
+ bodyContent = await openInEditor("");
4747
+ if (!bodyContent.trim()) {
4748
+ process.stdout.write("\uBE48 \uB313\uAE00\uC740 \uC791\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.\n");
4749
+ return;
4750
+ }
4751
+ }
4752
+ startSpinner("\uB313\uAE00 \uCD94\uAC00 \uC911...");
4753
+ try {
4754
+ const res = await client.addWikiPageComment(wikiId, pageId, {
4755
+ body: { content: bodyContent }
4756
+ });
4757
+ stopSpinner(true, `\uB313\uAE00 \uCD94\uAC00 \uC644\uB8CC (id: ${res.result.id})`);
4758
+ if (globalOpts.json) {
4759
+ printJson({ id: res.result.id });
4760
+ } else if (globalOpts.quiet) {
4761
+ printQuiet([res.result.id]);
4762
+ } else {
4763
+ process.stdout.write(`\uB313\uAE00\uC774 \uCD94\uAC00\uB418\uC5C8\uC2B5\uB2C8\uB2E4: ${res.result.id}
4764
+ `);
4765
+ }
4766
+ } catch (e) {
4767
+ stopSpinner(false);
4768
+ throw e;
4769
+ }
4770
+ });
4771
+
4772
+ // src/commands/wiki/page-comment/edit.ts
4773
+ var import_commander49 = require("commander");
4774
+ var wikiPageCommentEditCommand = new import_commander49.Command("edit").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uB313\uAE00 \uC218\uC815 ($EDITOR \uB610\uB294 --body \uC635\uC158)").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC / Dooray Wiki URL (\uBAA8\uB4DC\uBCC4)").argument("[arg2]", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID (\uBAA8\uB4DC\uBCC4)").argument("[arg3]", "\uB313\uAE00 ID (positional 3\uAC1C \uBAA8\uB4DC)").option("--id <pageId>", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID (positional \uB300\uC2E0)").option("--url <url>", "Dooray Wiki URL (positional \uB300\uC2E0)").option("--project <code>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (--id \uBAA8\uB4DC\uC6A9)").option("--comment-id <commentId>", "\uB313\uAE00 ID (positional \uB300\uCCB4)").option("--body <text>", "\uB313\uAE00 \uBCF8\uBB38 \uBCC0\uACBD (- \uC785\uB825 \uC2DC stdin, non-interactive)").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C (- \uC785\uB825 \uC2DC stdin, non-interactive)").action(async (arg1, arg2, arg3, opts) => {
4775
+ const parsed = parseWikiCommentArgs(arg1, arg2, arg3, opts);
4776
+ const config = await getConfigOrThrow();
4777
+ const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4778
+ const { wikiId, pageId } = await resolveWikiPageInput(client, {
4779
+ projectArg: parsed.projectArg,
4780
+ pageIdArg: parsed.pageIdArg,
4781
+ idOpt: parsed.idOpt,
4782
+ urlOpt: parsed.urlOpt,
4783
+ project: parsed.projectOpt
4784
+ });
4785
+ startSpinner("\uB313\uAE00 \uC870\uD68C \uC911...");
4786
+ let existing;
4787
+ try {
4788
+ const detail = await client.getWikiPageComment(wikiId, pageId, parsed.commentId);
4789
+ existing = detail.result;
4790
+ stopSpinner(true, "\uB313\uAE00 \uC870\uD68C \uC644\uB8CC");
4791
+ } catch (e) {
4792
+ stopSpinner(false);
4793
+ throw e;
4794
+ }
4795
+ let newBody = await readBodyInputOrNull(opts);
4796
+ if (newBody == null) {
4797
+ newBody = await openInEditor(existing.body.content);
4798
+ if (!newBody.trim() || newBody === existing.body.content) {
4799
+ process.stdout.write("\uBCC0\uACBD \uC0AC\uD56D\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n");
4800
+ return;
4801
+ }
4802
+ }
4803
+ startSpinner("\uB313\uAE00 \uC218\uC815 \uC911...");
4804
+ try {
4805
+ await client.updateWikiPageComment(wikiId, pageId, parsed.commentId, {
4806
+ body: { content: newBody }
4807
+ });
4808
+ stopSpinner(true, "\uB313\uAE00 \uC218\uC815 \uC644\uB8CC");
4809
+ process.stdout.write(`\uB313\uAE00\uC774 \uC218\uC815\uB418\uC5C8\uC2B5\uB2C8\uB2E4: ${parsed.commentId}
4810
+ `);
4811
+ } catch (e) {
4812
+ stopSpinner(false);
4813
+ throw e;
4814
+ }
4815
+ });
4816
+
4817
+ // src/commands/wiki/page-comment/delete.ts
4818
+ var import_commander50 = require("commander");
4819
+ var wikiPageCommentDeleteCommand = new import_commander50.Command("delete").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uB313\uAE00 \uC0AD\uC81C (confirm \uC5C6\uC774 \uC989\uC2DC)").argument("[arg1]", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC / Dooray Wiki URL (\uBAA8\uB4DC\uBCC4)").argument("[arg2]", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID (\uBAA8\uB4DC\uBCC4)").argument("[arg3]", "\uB313\uAE00 ID (positional 3\uAC1C \uBAA8\uB4DC)").option("--id <pageId>", "\uC704\uD0A4 \uD398\uC774\uC9C0 ID (positional \uB300\uC2E0)").option("--url <url>", "Dooray Wiki URL (positional \uB300\uC2E0)").option("--project <code>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC (--id \uBAA8\uB4DC\uC6A9)").option("--comment-id <commentId>", "\uB313\uAE00 ID (positional \uB300\uCCB4)").action(async (arg1, arg2, arg3, opts) => {
4820
+ const parsed = parseWikiCommentArgs(arg1, arg2, arg3, opts);
4821
+ const config = await getConfigOrThrow();
4822
+ const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4823
+ const { wikiId, pageId } = await resolveWikiPageInput(client, {
4824
+ projectArg: parsed.projectArg,
4825
+ pageIdArg: parsed.pageIdArg,
4826
+ idOpt: parsed.idOpt,
4827
+ urlOpt: parsed.urlOpt,
4828
+ project: parsed.projectOpt
4829
+ });
4830
+ startSpinner("\uB313\uAE00 \uC0AD\uC81C \uC911...");
4831
+ try {
4832
+ await client.deleteWikiPageComment(wikiId, pageId, parsed.commentId);
4833
+ stopSpinner(true, "\uC0AD\uC81C \uC644\uB8CC");
4834
+ process.stdout.write(`\uB313\uAE00(${parsed.commentId})\uC774 \uC0AD\uC81C\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
4835
+ `);
4836
+ } catch (e) {
4837
+ stopSpinner(false);
4838
+ throw e;
4839
+ }
4840
+ });
4841
+
4842
+ // src/commands/wiki/page-comment/index.ts
4843
+ var wikiPageCommentCommand = new import_commander51.Command("comment").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uB313\uAE00 \uAD00\uB828 \uBA85\uB839");
4844
+ wikiPageCommentCommand.addCommand(wikiPageCommentListCommand);
4845
+ wikiPageCommentCommand.addCommand(wikiPageCommentLatestCommand);
4846
+ wikiPageCommentCommand.addCommand(wikiPageCommentGetCommand);
4847
+ wikiPageCommentCommand.addCommand(wikiPageCommentAddCommand);
4848
+ wikiPageCommentCommand.addCommand(wikiPageCommentEditCommand);
4849
+ wikiPageCommentCommand.addCommand(wikiPageCommentDeleteCommand);
4850
+
4851
+ // src/commands/member/index.ts
4852
+ var import_commander55 = require("commander");
4853
+
4854
+ // src/commands/member/get.ts
4855
+ var import_commander52 = require("commander");
4856
+
4857
+ // src/formatters/member.ts
4858
+ function formatMemberDetail(member, opts) {
4859
+ if (opts.json) {
4860
+ printJson(member);
4861
+ return;
4862
+ }
4863
+ if (opts.quiet) {
4864
+ process.stdout.write(member.id + "\n");
4865
+ return;
4866
+ }
4867
+ const lines = [
4868
+ `\uC774\uB984: ${member.name}`,
4869
+ ...member.englishName ? [`\uC601\uBB38\uBA85: ${member.englishName}`] : [],
4870
+ ...member.nickname ? [`\uBCC4\uBA85: ${member.nickname}`] : [],
4871
+ ...member.userCode ? [`\uC0AC\uBC88/ID: ${member.userCode}`] : [],
4872
+ ...member.externalEmailAddress ? [`\uC678\uBD80 \uC774\uBA54\uC77C: ${member.externalEmailAddress}`] : [],
4873
+ `member-id: ${member.id}`
4874
+ ];
4875
+ process.stdout.write(lines.join("\n") + "\n");
4876
+ }
4877
+ function formatMemberList(rows, opts) {
4878
+ output(opts, {
4879
+ headers: ["ID", "Name", "Role"],
4880
+ rows: rows.map((r) => [r.id, r.name, r.role ?? ""]),
4881
+ raw: rows,
4882
+ ids: rows.map((r) => r.id)
4883
+ });
4884
+ }
4885
+ function formatMemberSearchResults(members, opts) {
4886
+ output(opts, {
4887
+ headers: ["ID", "Name", "UserCode", "Nickname", "Email"],
4888
+ rows: members.map((m) => [
4889
+ m.id,
4890
+ m.name,
4891
+ m.userCode ?? "",
4892
+ m.nickname ?? "",
4893
+ m.externalEmailAddress ?? ""
4894
+ ]),
4895
+ raw: members,
4896
+ ids: members.map((m) => m.id)
4897
+ });
4898
+ }
4899
+
4900
+ // src/commands/member/get.ts
4901
+ var memberGetCommand = new import_commander52.Command("get").description("\uBA64\uBC84 \uC0C1\uC138 \uC815\uBCF4 \uC870\uD68C (organizationMemberId)").argument("<member-id>", "\uC870\uD68C\uD560 organization member ID").action(async (memberId) => {
4902
+ const globalOpts = memberGetCommand.optsWithGlobals();
4903
+ const config = await getConfigOrThrow();
4904
+ const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4905
+ const res = await client.getMemberDetail(memberId);
4906
+ formatMemberDetail(res.result, globalOpts);
4907
+ });
4908
+
4909
+ // src/commands/member/list.ts
4910
+ var import_commander53 = require("commander");
4911
+ var memberListCommand = new import_commander53.Command("list").description("\uD504\uB85C\uC81D\uD2B8 \uBA64\uBC84 \uBAA9\uB85D").argument("<project>", "\uD504\uB85C\uC81D\uD2B8 \uCF54\uB4DC \uB610\uB294 ID").action(async (project) => {
4912
+ const globalOpts = memberListCommand.optsWithGlobals();
4913
+ const config = await getConfigOrThrow();
4914
+ const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4915
+ startSpinner("\uBA64\uBC84 \uBAA9\uB85D \uC870\uD68C \uC911...");
4916
+ const projectId = await resolveProject(client, project);
4917
+ const members = await ensureMembers(client, projectId);
4918
+ stopSpinner(true, `${members.length}\uBA85`);
4919
+ formatMemberList(
4920
+ members.map((m) => ({ id: m.organizationMemberId, name: m.name })),
4921
+ globalOpts
4922
+ );
4923
+ });
4924
+
4925
+ // src/commands/member/search.ts
4926
+ var import_commander54 = require("commander");
4927
+ var memberSearchCommand = new import_commander54.Command("search").description("organization \uC804\uCCB4\uC5D0\uC11C \uBA64\uBC84 \uAC80\uC0C9").argument("[keyword]", "\uC774\uB984 \uAC80\uC0C9\uC5B4 (--email/--user-code \uBBF8\uC9C0\uC815 \uC2DC name\uC73C\uB85C \uAC80\uC0C9)").option("--email <email>", "\uC678\uBD80 \uC774\uBA54\uC77C (\uCF64\uB9C8 \uAD6C\uBD84 \uAC00\uB2A5, exact match)").option("--user-code <code>", "\uC0AC\uBC88 like \uAC80\uC0C9").option("--user-code-exact <code>", "\uC0AC\uBC88 exact match").option("--page <n>", "\uD398\uC774\uC9C0 (\uAE30\uBCF8 0)", "0").option("--size <n>", "\uD398\uC774\uC9C0 \uD06C\uAE30 (\uAE30\uBCF8 20, max 100)", "20").action(async (keyword, opts) => {
4928
+ const globalOpts = memberSearchCommand.optsWithGlobals();
4929
+ const filterCount = [keyword, opts.email, opts.userCode, opts.userCodeExact].filter(Boolean).length;
4930
+ if (filterCount === 0) {
4931
+ throw new DoorayCliError(
4932
+ "\uAC80\uC0C9 \uC870\uAC74\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. positional <keyword>(=name) \uB610\uB294 --email/--user-code/--user-code-exact \uC911 \uD558\uB098 \uC774\uC0C1.",
4933
+ EXIT_PARAM_ERROR
4934
+ );
4935
+ }
4936
+ if (keyword && (opts.email || opts.userCode || opts.userCodeExact)) {
4937
+ throw new DoorayCliError(
4938
+ "positional <keyword>(name)\uC640 --email/--user-code/--user-code-exact \uC635\uC158\uC740 \uB3D9\uC2DC \uC0AC\uC6A9 \uBD88\uAC00.",
4939
+ EXIT_PARAM_ERROR
4940
+ );
4941
+ }
4942
+ const config = await getConfigOrThrow();
4943
+ const client = new DoorayApiClient(config.apiKey, config.baseUrl);
4944
+ const size = Math.min(Math.max(1, Number(opts.size) || 20), 100);
4945
+ const page = Math.max(0, Number(opts.page) || 0);
4946
+ startSpinner("\uBA64\uBC84 \uAC80\uC0C9 \uC911...");
4947
+ const res = await client.searchMembers({
4948
+ ...keyword && { name: keyword },
4949
+ ...opts.email && { externalEmailAddresses: opts.email },
4950
+ ...opts.userCode && { userCode: opts.userCode },
4951
+ ...opts.userCodeExact && { userCodeExact: opts.userCodeExact },
4952
+ page,
4953
+ size
4954
+ });
4955
+ stopSpinner(true, `${res.totalCount}\uAC74 (\uC774 \uD398\uC774\uC9C0 ${res.result.length})`);
4956
+ formatMemberSearchResults(res.result, globalOpts);
4957
+ });
4144
4958
 
4145
4959
  // src/commands/member/index.ts
4146
- var memberCommand = new import_commander42.Command("member").description("Dooray \uBA64\uBC84 \uC870\uD68C");
4960
+ var memberCommand = new import_commander55.Command("member").description("Dooray \uBA64\uBC84 \uC870\uD68C");
4147
4961
  memberCommand.addCommand(memberGetCommand);
4148
4962
  memberCommand.addCommand(memberListCommand);
4149
4963
  memberCommand.addCommand(memberSearchCommand);
4150
4964
 
4151
4965
  // src/commands/mail/list.ts
4152
- var import_commander43 = require("commander");
4966
+ var import_commander56 = require("commander");
4153
4967
 
4154
4968
  // src/api/imapClient.ts
4155
4969
  var import_imapflow = require("imapflow");
@@ -4266,7 +5080,7 @@ async function getMail(config, uid) {
4266
5080
 
4267
5081
  // src/commands/mail/list.ts
4268
5082
  var import_chalk5 = __toESM(require("chalk"));
4269
- var mailListCommand = new import_commander43.Command("list").description("\uBA54\uC77C \uBAA9\uB85D \uC870\uD68C").option("--unread", "\uC548\uC77D\uC740 \uBA54\uC77C\uB9CC").option("--search <keyword>", "\uC81C\uBAA9 \uAC80\uC0C9").option("--size <number>", "\uC870\uD68C \uAC1C\uC218", "20").action(async (opts) => {
5083
+ var mailListCommand = new import_commander56.Command("list").description("\uBA54\uC77C \uBAA9\uB85D \uC870\uD68C").option("--unread", "\uC548\uC77D\uC740 \uBA54\uC77C\uB9CC").option("--search <keyword>", "\uC81C\uBAA9 \uAC80\uC0C9").option("--size <number>", "\uC870\uD68C \uAC1C\uC218", "20").action(async (opts) => {
4270
5084
  const globalOpts = mailListCommand.optsWithGlobals();
4271
5085
  const config = await getConfigOrThrow();
4272
5086
  startSpinner("\uBA54\uC77C \uC870\uD68C \uC911...");
@@ -4298,9 +5112,9 @@ var mailListCommand = new import_commander43.Command("list").description("\uBA54
4298
5112
  });
4299
5113
 
4300
5114
  // src/commands/mail/get.ts
4301
- var import_commander44 = require("commander");
5115
+ var import_commander57 = require("commander");
4302
5116
  var import_chalk6 = __toESM(require("chalk"));
4303
- var mailGetCommand = new import_commander44.Command("get").description("\uBA54\uC77C \uC0C1\uC138 \uC870\uD68C").argument("<uid>", "\uBA54\uC77C UID").action(async (uid) => {
5117
+ var mailGetCommand = new import_commander57.Command("get").description("\uBA54\uC77C \uC0C1\uC138 \uC870\uD68C").argument("<uid>", "\uBA54\uC77C UID").action(async (uid) => {
4304
5118
  const globalOpts = mailGetCommand.optsWithGlobals();
4305
5119
  const config = await getConfigOrThrow();
4306
5120
  startSpinner("\uBA54\uC77C \uC870\uD68C \uC911...");
@@ -4331,8 +5145,8 @@ ${mail.body}
4331
5145
  });
4332
5146
 
4333
5147
  // src/commands/mail/send.ts
4334
- var import_commander45 = require("commander");
4335
- var import_promises11 = require("fs/promises");
5148
+ var import_commander58 = require("commander");
5149
+ var import_promises13 = require("fs/promises");
4336
5150
 
4337
5151
  // src/api/smtpClient.ts
4338
5152
  var import_nodemailer = __toESM(require("nodemailer"));
@@ -4381,12 +5195,12 @@ async function sendMail(config, opts) {
4381
5195
  }
4382
5196
 
4383
5197
  // src/commands/mail/send.ts
4384
- var mailSendCommand = new import_commander45.Command("send").description("\uBA54\uC77C \uBC1C\uC1A1").requiredOption("--to <addresses...>", "\uBC1B\uB294\uC0AC\uB78C \uC774\uBA54\uC77C (\uBCF5\uC218 \uAC00\uB2A5)").requiredOption("--subject <title>", "\uC81C\uBAA9").option("--body <text>", "\uBCF8\uBB38").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C").option("--cc <addresses...>", "\uCC38\uC870").option("--bcc <addresses...>", "\uC228\uC740\uCC38\uC870").option("--html", "\uBCF8\uBB38\uC744 HTML\uB85C \uC804\uC1A1").action(async (opts) => {
5198
+ var mailSendCommand = new import_commander58.Command("send").description("\uBA54\uC77C \uBC1C\uC1A1").requiredOption("--to <addresses...>", "\uBC1B\uB294\uC0AC\uB78C \uC774\uBA54\uC77C (\uBCF5\uC218 \uAC00\uB2A5)").requiredOption("--subject <title>", "\uC81C\uBAA9").option("--body <text>", "\uBCF8\uBB38").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C").option("--cc <addresses...>", "\uCC38\uC870").option("--bcc <addresses...>", "\uC228\uC740\uCC38\uC870").option("--html", "\uBCF8\uBB38\uC744 HTML\uB85C \uC804\uC1A1").action(async (opts) => {
4385
5199
  const globalOpts = mailSendCommand.optsWithGlobals();
4386
5200
  const config = await getConfigOrThrow();
4387
5201
  let body = opts.body ?? "";
4388
5202
  if (opts.bodyFile) {
4389
- body = await (0, import_promises11.readFile)(opts.bodyFile, "utf-8");
5203
+ body = await (0, import_promises13.readFile)(opts.bodyFile, "utf-8");
4390
5204
  }
4391
5205
  if (!body) {
4392
5206
  process.stderr.write("\uC624\uB958: --body \uB610\uB294 --body-file\uC744 \uC9C0\uC815\uD558\uC138\uC694\n");
@@ -4416,8 +5230,8 @@ var mailSendCommand = new import_commander45.Command("send").description("\uBA54
4416
5230
  });
4417
5231
 
4418
5232
  // src/commands/mail/reply.ts
4419
- var import_commander46 = require("commander");
4420
- var import_promises12 = require("fs/promises");
5233
+ var import_commander59 = require("commander");
5234
+ var import_promises14 = require("fs/promises");
4421
5235
  var import_imapflow2 = require("imapflow");
4422
5236
  async function getMessageId(config, uid) {
4423
5237
  const imap = getImapConfigOrThrow(config);
@@ -4445,12 +5259,12 @@ async function getMessageId(config, uid) {
4445
5259
  await client.logout();
4446
5260
  }
4447
5261
  }
4448
- var mailReplyCommand = new import_commander46.Command("reply").description("\uBA54\uC77C \uB2F5\uC7A5").argument("<uid>", "\uC6D0\uBCF8 \uBA54\uC77C UID").option("--body <text>", "\uB2F5\uC7A5 \uBCF8\uBB38").option("--body-file <path>", "\uB2F5\uC7A5 \uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C").option("--cc <addresses...>", "\uCC38\uC870").option("--html", "\uBCF8\uBB38\uC744 HTML\uB85C \uC804\uC1A1").action(async (uid, opts) => {
5262
+ var mailReplyCommand = new import_commander59.Command("reply").description("\uBA54\uC77C \uB2F5\uC7A5").argument("<uid>", "\uC6D0\uBCF8 \uBA54\uC77C UID").option("--body <text>", "\uB2F5\uC7A5 \uBCF8\uBB38").option("--body-file <path>", "\uB2F5\uC7A5 \uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C").option("--cc <addresses...>", "\uCC38\uC870").option("--html", "\uBCF8\uBB38\uC744 HTML\uB85C \uC804\uC1A1").action(async (uid, opts) => {
4449
5263
  const globalOpts = mailReplyCommand.optsWithGlobals();
4450
5264
  const config = await getConfigOrThrow();
4451
5265
  let body = opts.body ?? "";
4452
5266
  if (opts.bodyFile) {
4453
- body = await (0, import_promises12.readFile)(opts.bodyFile, "utf-8");
5267
+ body = await (0, import_promises14.readFile)(opts.bodyFile, "utf-8");
4454
5268
  }
4455
5269
  if (!body) {
4456
5270
  process.stderr.write("\uC624\uB958: --body \uB610\uB294 --body-file\uC744 \uC9C0\uC815\uD558\uC138\uC694\n");
@@ -4486,29 +5300,29 @@ var mailReplyCommand = new import_commander46.Command("reply").description("\uBA
4486
5300
  });
4487
5301
 
4488
5302
  // src/commands/feedback.ts
4489
- var import_commander47 = require("commander");
5303
+ var import_commander60 = require("commander");
4490
5304
  var import_node_child_process2 = require("child_process");
4491
5305
  var import_node_util = require("util");
4492
- var import_promises15 = require("fs/promises");
5306
+ var import_promises17 = require("fs/promises");
4493
5307
  var import_node_os4 = require("os");
4494
- var import_node_path11 = require("path");
5308
+ var import_node_path13 = require("path");
4495
5309
  var import_node_crypto = require("crypto");
4496
5310
  var import_prompts = require("@inquirer/prompts");
4497
5311
 
4498
5312
  // src/utils/feedback-meta.ts
4499
- var import_promises13 = require("fs/promises");
4500
- var import_node_path9 = require("path");
5313
+ var import_promises15 = require("fs/promises");
5314
+ var import_node_path11 = require("path");
4501
5315
  async function readCliVersion() {
4502
5316
  const entry = process.argv[1];
4503
- const here = entry ? (0, import_node_path9.dirname)(entry) : process.cwd();
5317
+ const here = entry ? (0, import_node_path11.dirname)(entry) : process.cwd();
4504
5318
  const candidates = [
4505
- (0, import_node_path9.join)(here, "package.json"),
4506
- (0, import_node_path9.join)(here, "..", "package.json"),
4507
- (0, import_node_path9.join)(here, "..", "..", "package.json")
5319
+ (0, import_node_path11.join)(here, "package.json"),
5320
+ (0, import_node_path11.join)(here, "..", "package.json"),
5321
+ (0, import_node_path11.join)(here, "..", "..", "package.json")
4508
5322
  ];
4509
5323
  for (const p of candidates) {
4510
5324
  try {
4511
- const raw = await (0, import_promises13.readFile)(p, "utf-8");
5325
+ const raw = await (0, import_promises15.readFile)(p, "utf-8");
4512
5326
  const pkg = JSON.parse(raw);
4513
5327
  if (pkg.name === "@bifos/dooray-cli" && typeof pkg.version === "string") {
4514
5328
  return pkg.version;
@@ -4554,10 +5368,10 @@ function buildIssueBody(userBody, meta) {
4554
5368
  }
4555
5369
 
4556
5370
  // src/cache/last-run.ts
4557
- var import_promises14 = require("fs/promises");
4558
- var import_node_path10 = require("path");
5371
+ var import_promises16 = require("fs/promises");
5372
+ var import_node_path12 = require("path");
4559
5373
  var import_node_os3 = require("os");
4560
- var LAST_RUN_PATH = (0, import_node_path10.join)((0, import_node_os3.homedir)(), ".dooray", "last-run.json");
5374
+ var LAST_RUN_PATH = (0, import_node_path12.join)((0, import_node_os3.homedir)(), ".dooray", "last-run.json");
4561
5375
  function isLastRun(obj) {
4562
5376
  if (typeof obj !== "object" || obj === null) return false;
4563
5377
  const o = obj;
@@ -4565,7 +5379,7 @@ function isLastRun(obj) {
4565
5379
  }
4566
5380
  async function readLastRun() {
4567
5381
  try {
4568
- const raw = await (0, import_promises14.readFile)(LAST_RUN_PATH, "utf-8");
5382
+ const raw = await (0, import_promises16.readFile)(LAST_RUN_PATH, "utf-8");
4569
5383
  const parsed = JSON.parse(raw);
4570
5384
  return isLastRun(parsed) ? parsed : null;
4571
5385
  } catch {
@@ -4573,10 +5387,10 @@ async function readLastRun() {
4573
5387
  }
4574
5388
  }
4575
5389
  async function writeLastRun(data) {
4576
- await (0, import_promises14.mkdir)((0, import_node_path10.join)((0, import_node_os3.homedir)(), ".dooray"), { recursive: true });
5390
+ await (0, import_promises16.mkdir)((0, import_node_path12.join)((0, import_node_os3.homedir)(), ".dooray"), { recursive: true });
4577
5391
  const tmp2 = LAST_RUN_PATH + ".tmp";
4578
- await (0, import_promises14.writeFile)(tmp2, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
4579
- await (0, import_promises14.rename)(tmp2, LAST_RUN_PATH);
5392
+ await (0, import_promises16.writeFile)(tmp2, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
5393
+ await (0, import_promises16.rename)(tmp2, LAST_RUN_PATH);
4580
5394
  }
4581
5395
 
4582
5396
  // src/commands/feedback.ts
@@ -4594,10 +5408,10 @@ async function ensureGhInstalled() {
4594
5408
  }
4595
5409
  async function readBody(opts) {
4596
5410
  if (opts.body) return opts.body;
4597
- if (opts.bodyFile) return await (0, import_promises15.readFile)(opts.bodyFile, "utf-8");
5411
+ if (opts.bodyFile) return await (0, import_promises17.readFile)(opts.bodyFile, "utf-8");
4598
5412
  return void 0;
4599
5413
  }
4600
- var feedbackCommand = new import_commander47.Command("feedback").description("dooray-cli\uC5D0 \uB300\uD55C GitHub issue \uB4F1\uB85D (gh CLI \uC704\uC784)").option("--title <text>", "\uC774\uC288 \uC81C\uBAA9 (\uC5C6\uC73C\uBA74 \uC778\uD130\uB799\uD2F0\uBE0C)").option("--body <text>", "\uC774\uC288 \uBCF8\uBB38").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C").option(
5414
+ var feedbackCommand = new import_commander60.Command("feedback").description("dooray-cli\uC5D0 \uB300\uD55C GitHub issue \uB4F1\uB85D (gh CLI \uC704\uC784)").option("--title <text>", "\uC774\uC288 \uC81C\uBAA9 (\uC5C6\uC73C\uBA74 \uC778\uD130\uB799\uD2F0\uBE0C)").option("--body <text>", "\uC774\uC288 \uBCF8\uBB38").option("--body-file <path>", "\uBCF8\uBB38 \uD30C\uC77C \uACBD\uB85C").option(
4601
5415
  "--label <name>",
4602
5416
  "\uB77C\uBCA8 (\uBC18\uBCF5 \uAC00\uB2A5)",
4603
5417
  (value, prev) => [...prev, value],
@@ -4688,8 +5502,8 @@ var feedbackCommand = new import_commander47.Command("feedback").description("do
4688
5502
  }
4689
5503
  }
4690
5504
  await ensureGhInstalled();
4691
- const bodyFile = (0, import_node_path11.join)((0, import_node_os4.tmpdir)(), `dooray-feedback-${(0, import_node_crypto.randomUUID)()}.md`);
4692
- await (0, import_promises15.writeFile)(bodyFile, issueBody);
5505
+ const bodyFile = (0, import_node_path13.join)((0, import_node_os4.tmpdir)(), `dooray-feedback-${(0, import_node_crypto.randomUUID)()}.md`);
5506
+ await (0, import_promises17.writeFile)(bodyFile, issueBody);
4693
5507
  try {
4694
5508
  const args = [
4695
5509
  "issue",
@@ -4716,7 +5530,7 @@ gh \uC778\uC99D \uC548 \uB418\uC5B4 \uC788\uC73C\uBA74: gh auth login`,
4716
5530
  EXIT_PARAM_ERROR
4717
5531
  );
4718
5532
  } finally {
4719
- await (0, import_promises15.unlink)(bodyFile).catch(() => {
5533
+ await (0, import_promises17.unlink)(bodyFile).catch(() => {
4720
5534
  });
4721
5535
  }
4722
5536
  });
@@ -4760,8 +5574,8 @@ function sanitizeArgv(argv) {
4760
5574
  }
4761
5575
 
4762
5576
  // src/index.ts
4763
- var program = new import_commander48.Command();
4764
- program.name("dooray").description("Dooray REST API CLI").version("0.9.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");
5577
+ var program = new import_commander61.Command();
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");
4765
5579
  program.hook("preAction", () => {
4766
5580
  const opts = program.opts();
4767
5581
  if (opts.color === false || process.env.NO_COLOR) {
@@ -4771,14 +5585,14 @@ program.hook("preAction", () => {
4771
5585
  setQuiet(true);
4772
5586
  }
4773
5587
  });
4774
- var projectCommand = new import_commander48.Command("project").description("\uD504\uB85C\uC81D\uD2B8 \uAD00\uB828 \uBA85\uB839");
5588
+ var projectCommand = new import_commander61.Command("project").description("\uD504\uB85C\uC81D\uD2B8 \uAD00\uB828 \uBA85\uB839");
4775
5589
  projectCommand.addCommand(projectListCommand);
4776
5590
  projectCommand.addCommand(projectMembersCommand);
4777
5591
  projectCommand.addCommand(projectWorkflowsCommand);
4778
5592
  projectCommand.addCommand(projectGroupsCommand);
4779
5593
  projectCommand.addCommand(projectTagsCommand);
4780
5594
  projectCommand.addCommand(projectTemplatesCommand);
4781
- var postCommand = new import_commander48.Command("post").description("\uC5C5\uBB34 \uAD00\uB828 \uBA85\uB839");
5595
+ var postCommand = new import_commander61.Command("post").description("\uC5C5\uBB34 \uAD00\uB828 \uBA85\uB839");
4782
5596
  postCommand.addCommand(postListCommand);
4783
5597
  postCommand.addCommand(postSearchCommand);
4784
5598
  postCommand.addCommand(postGetCommand);
@@ -4786,7 +5600,7 @@ postCommand.addCommand(postEditCommand);
4786
5600
  postCommand.addCommand(postCreateCommand);
4787
5601
  postCommand.addCommand(postDoneCommand);
4788
5602
  postCommand.addCommand(postWorkflowCommand);
4789
- var commentCommand = new import_commander48.Command("comment").description("\uB313\uAE00 \uAD00\uB828 \uBA85\uB839");
5603
+ var commentCommand = new import_commander61.Command("comment").description("\uB313\uAE00 \uAD00\uB828 \uBA85\uB839");
4790
5604
  commentCommand.addCommand(commentListCommand);
4791
5605
  commentCommand.addCommand(commentLatestCommand);
4792
5606
  commentCommand.addCommand(commentGetCommand);
@@ -4795,22 +5609,24 @@ commentCommand.addCommand(commentEditCommand);
4795
5609
  commentCommand.addCommand(commentDeleteCommand);
4796
5610
  commentCommand.addCommand(commentFileCommand);
4797
5611
  postCommand.addCommand(commentCommand);
4798
- var fileCommand = new import_commander48.Command("file").description("\uCCA8\uBD80\uD30C\uC77C \uAD00\uB828 \uBA85\uB839");
5612
+ var fileCommand = new import_commander61.Command("file").description("\uCCA8\uBD80\uD30C\uC77C \uAD00\uB828 \uBA85\uB839");
4799
5613
  fileCommand.addCommand(fileListCommand);
4800
5614
  fileCommand.addCommand(fileDownloadCommand);
4801
5615
  fileCommand.addCommand(fileDownloadAllCommand);
4802
5616
  fileCommand.addCommand(fileUploadCommand);
4803
5617
  fileCommand.addCommand(fileDeleteCommand);
4804
5618
  postCommand.addCommand(fileCommand);
4805
- var wikiCommand = new import_commander48.Command("wiki").description("\uC704\uD0A4 \uAD00\uB828 \uBA85\uB839");
5619
+ var wikiCommand = new import_commander61.Command("wiki").description("\uC704\uD0A4 \uAD00\uB828 \uBA85\uB839");
4806
5620
  wikiCommand.addCommand(wikiListCommand);
4807
5621
  wikiCommand.addCommand(wikiPagesCommand);
4808
- var wikiPageCommand = new import_commander48.Command("page").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uAD00\uB828 \uBA85\uB839");
5622
+ var wikiPageCommand = new import_commander61.Command("page").description("\uC704\uD0A4 \uD398\uC774\uC9C0 \uAD00\uB828 \uBA85\uB839");
4809
5623
  wikiPageCommand.addCommand(wikiPageGetCommand);
4810
5624
  wikiPageCommand.addCommand(wikiPageCreateCommand);
4811
5625
  wikiPageCommand.addCommand(wikiPageEditCommand);
5626
+ wikiPageCommand.addCommand(wikiPageFileCommand);
5627
+ wikiPageCommand.addCommand(wikiPageCommentCommand);
4812
5628
  wikiCommand.addCommand(wikiPageCommand);
4813
- var mailCommand = new import_commander48.Command("mail").description("\uBA54\uC77C \uAD00\uB828 \uBA85\uB839");
5629
+ var mailCommand = new import_commander61.Command("mail").description("\uBA54\uC77C \uAD00\uB828 \uBA85\uB839");
4814
5630
  mailCommand.addCommand(mailListCommand);
4815
5631
  mailCommand.addCommand(mailGetCommand);
4816
5632
  mailCommand.addCommand(mailSendCommand);