nworks 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -2
- package/dist/index.js +412 -4
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +281 -0
- package/dist/mcp.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ nworks login \
|
|
|
26
26
|
--bot-id <BOT_ID>
|
|
27
27
|
|
|
28
28
|
# User OAuth 로그인 (캘린더, 드라이브 등 사용자 API용)
|
|
29
|
-
nworks login --user --scope calendar.read,file,mail
|
|
29
|
+
nworks login --user --scope "calendar.read,file,mail,task,user.read"
|
|
30
30
|
|
|
31
31
|
# 인증 확인
|
|
32
32
|
nworks whoami
|
|
@@ -51,6 +51,12 @@ nworks mail send --to "user@example.com" --subject "제목" --body "내용"
|
|
|
51
51
|
|
|
52
52
|
# 받은편지함 조회
|
|
53
53
|
nworks mail list
|
|
54
|
+
|
|
55
|
+
# 할 일 목록
|
|
56
|
+
nworks task list
|
|
57
|
+
|
|
58
|
+
# 할 일 생성
|
|
59
|
+
nworks task create --title "코드 리뷰" --body "PR #382 리뷰"
|
|
54
60
|
```
|
|
55
61
|
|
|
56
62
|
## CLI Commands
|
|
@@ -158,6 +164,33 @@ nworks mail read --id <mailId>
|
|
|
158
164
|
|
|
159
165
|
> **Note**: 메일 API는 User OAuth가 필요합니다. 먼저 `nworks login --user --scope mail`을 실행하세요. 읽기만 필요하면 `mail.read` scope로 충분합니다.
|
|
160
166
|
|
|
167
|
+
### 할 일 (User OAuth 필요)
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# 할 일 목록 (기본 카테고리)
|
|
171
|
+
nworks task list
|
|
172
|
+
|
|
173
|
+
# 미완료만 조회
|
|
174
|
+
nworks task list --status TODO
|
|
175
|
+
|
|
176
|
+
# 할 일 생성
|
|
177
|
+
nworks task create --title "코드 리뷰" --body "PR #382 리뷰"
|
|
178
|
+
|
|
179
|
+
# 마감일 지정
|
|
180
|
+
nworks task create --title "배포" --due 2026-03-20
|
|
181
|
+
|
|
182
|
+
# 할 일 완료 처리
|
|
183
|
+
nworks task update --id <taskId> --status done
|
|
184
|
+
|
|
185
|
+
# 할 일 미완료로 되돌리기
|
|
186
|
+
nworks task update --id <taskId> --status todo
|
|
187
|
+
|
|
188
|
+
# 할 일 삭제
|
|
189
|
+
nworks task delete --id <taskId>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
> **Note**: 할 일 API는 User OAuth가 필요합니다. 먼저 `nworks login --user --scope "task user.read"`를 실행하세요. (`user.read`는 사용자 ID 조회에 필요) 읽기만 필요하면 `nworks login --user --scope "task.read user.read"`로 충분합니다.
|
|
193
|
+
|
|
161
194
|
### MCP 서버
|
|
162
195
|
|
|
163
196
|
```bash
|
|
@@ -201,6 +234,8 @@ nworks mcp --list-tools # 등록된 tool 목록
|
|
|
201
234
|
| `file.read` | 드라이브 읽기 전용 | User OAuth | `drive list/download` |
|
|
202
235
|
| `mail` | 메일 읽기/쓰기 | User OAuth | `mail send/list/read` |
|
|
203
236
|
| `mail.read` | 메일 읽기 전용 | User OAuth | `mail list/read` |
|
|
237
|
+
| `task` | 할 일 읽기/쓰기 | User OAuth | `task list/create/update/delete` (+ `user.read` 필요) |
|
|
238
|
+
| `task.read` | 할 일 읽기 전용 | User OAuth | `task list` (+ `user.read` 필요) |
|
|
204
239
|
|
|
205
240
|
> **Tip**: scope를 변경한 후에는 토큰을 재발급해야 합니다.
|
|
206
241
|
> ```bash
|
|
@@ -255,7 +290,7 @@ NWORKS_VERBOSE=1 # optional, 디버그 로깅
|
|
|
255
290
|
- ~~**v0.2** — 캘린더 일정 조회 + User OAuth~~
|
|
256
291
|
- ~~**v0.3** — 드라이브 파일 조회/업로드/다운로드 (`nworks drive`)~~
|
|
257
292
|
- ~~**v0.4** — 메일 (`nworks mail send/list/read`)~~
|
|
258
|
-
-
|
|
293
|
+
- ~~**v0.5** — 할 일 (`nworks task list/create/update/delete`)~~
|
|
259
294
|
- **v0.6** — 캘린더 쓰기 (`nworks calendar create/update/delete`)
|
|
260
295
|
- **v0.7** — 게시판 (`nworks board list/post/read`)
|
|
261
296
|
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ var __export = (target, all) => {
|
|
|
7
7
|
|
|
8
8
|
// src/index.ts
|
|
9
9
|
import { createRequire } from "module";
|
|
10
|
-
import { Command as
|
|
10
|
+
import { Command as Command11 } from "commander";
|
|
11
11
|
|
|
12
12
|
// src/commands/login.ts
|
|
13
13
|
import { Command } from "commander";
|
|
@@ -1276,9 +1276,280 @@ var readCommand = new Command8("read").description("Read a specific mail (requir
|
|
|
1276
1276
|
});
|
|
1277
1277
|
var mailCommand = new Command8("mail").description("Mail operations (requires User OAuth with mail scope)").addCommand(sendCommand2).addCommand(listCommand3).addCommand(readCommand);
|
|
1278
1278
|
|
|
1279
|
-
// src/commands/
|
|
1279
|
+
// src/commands/task.ts
|
|
1280
1280
|
import { Command as Command9 } from "commander";
|
|
1281
1281
|
|
|
1282
|
+
// src/api/task.ts
|
|
1283
|
+
var BASE_URL5 = "https://www.worksapis.com/v1.0";
|
|
1284
|
+
async function authedFetch3(url2, init, profile) {
|
|
1285
|
+
const token = await getValidUserToken(profile);
|
|
1286
|
+
const headers = new Headers(init.headers);
|
|
1287
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
1288
|
+
return fetch(url2, { ...init, headers });
|
|
1289
|
+
}
|
|
1290
|
+
async function handleError3(res) {
|
|
1291
|
+
if (res.status === 401) {
|
|
1292
|
+
throw new AuthError("User token expired. Run `nworks login --user --scope task` again.");
|
|
1293
|
+
}
|
|
1294
|
+
let code = "UNKNOWN";
|
|
1295
|
+
let description = `HTTP ${res.status}`;
|
|
1296
|
+
try {
|
|
1297
|
+
const body = await res.json();
|
|
1298
|
+
code = body.code ?? code;
|
|
1299
|
+
description = body.description ?? description;
|
|
1300
|
+
} catch {
|
|
1301
|
+
}
|
|
1302
|
+
throw new ApiError(code, description, res.status);
|
|
1303
|
+
}
|
|
1304
|
+
async function resolveUserId(userId, profile) {
|
|
1305
|
+
if (userId !== "me") return userId;
|
|
1306
|
+
const url2 = `${BASE_URL5}/users/me`;
|
|
1307
|
+
const res = await authedFetch3(url2, { method: "GET" }, profile);
|
|
1308
|
+
if (!res.ok) return handleError3(res);
|
|
1309
|
+
const data = await res.json();
|
|
1310
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
1311
|
+
console.error(`[nworks] Resolved "me" \u2192 ${data.userId}`);
|
|
1312
|
+
}
|
|
1313
|
+
return data.userId;
|
|
1314
|
+
}
|
|
1315
|
+
async function listTasks(categoryId = "default", userId = "me", count = 50, cursor, status = "ALL", profile = "default") {
|
|
1316
|
+
const params = new URLSearchParams();
|
|
1317
|
+
params.set("categoryId", categoryId);
|
|
1318
|
+
params.set("count", String(count));
|
|
1319
|
+
params.set("status", status);
|
|
1320
|
+
if (cursor) params.set("cursor", cursor);
|
|
1321
|
+
const url2 = `${BASE_URL5}/users/${userId}/tasks?${params.toString()}`;
|
|
1322
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
1323
|
+
console.error(`[nworks] GET ${url2}`);
|
|
1324
|
+
}
|
|
1325
|
+
const res = await authedFetch3(url2, { method: "GET" }, profile);
|
|
1326
|
+
if (!res.ok) return handleError3(res);
|
|
1327
|
+
const data = await res.json();
|
|
1328
|
+
return { tasks: data.tasks ?? [], responseMetaData: data.responseMetaData };
|
|
1329
|
+
}
|
|
1330
|
+
async function createTask(opts) {
|
|
1331
|
+
const userId = opts.userId ?? "me";
|
|
1332
|
+
const profile = opts.profile ?? "default";
|
|
1333
|
+
const resolvedUserId = await resolveUserId(userId, profile);
|
|
1334
|
+
const assignorId = opts.assignorId ?? resolvedUserId;
|
|
1335
|
+
const assigneeIds = opts.assigneeIds ?? [resolvedUserId];
|
|
1336
|
+
const body = {
|
|
1337
|
+
assignorId,
|
|
1338
|
+
assignees: assigneeIds.map((id) => ({ assigneeId: id, status: "TODO" })),
|
|
1339
|
+
title: opts.title,
|
|
1340
|
+
content: opts.content ?? "",
|
|
1341
|
+
completionCondition: "ANY_ONE"
|
|
1342
|
+
};
|
|
1343
|
+
if (opts.dueDate) body.dueDate = opts.dueDate;
|
|
1344
|
+
if (opts.categoryId) body.categoryId = opts.categoryId;
|
|
1345
|
+
const url2 = `${BASE_URL5}/users/${userId}/tasks`;
|
|
1346
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
1347
|
+
console.error(`[nworks] POST ${url2}`);
|
|
1348
|
+
console.error(`[nworks] Body: ${JSON.stringify(body, null, 2)}`);
|
|
1349
|
+
}
|
|
1350
|
+
const res = await authedFetch3(
|
|
1351
|
+
url2,
|
|
1352
|
+
{
|
|
1353
|
+
method: "POST",
|
|
1354
|
+
headers: { "Content-Type": "application/json" },
|
|
1355
|
+
body: JSON.stringify(body)
|
|
1356
|
+
},
|
|
1357
|
+
profile
|
|
1358
|
+
);
|
|
1359
|
+
if (res.status === 201) {
|
|
1360
|
+
return await res.json();
|
|
1361
|
+
}
|
|
1362
|
+
if (!res.ok) return handleError3(res);
|
|
1363
|
+
return await res.json();
|
|
1364
|
+
}
|
|
1365
|
+
async function updateTask(opts) {
|
|
1366
|
+
const profile = opts.profile ?? "default";
|
|
1367
|
+
const body = {};
|
|
1368
|
+
if (opts.title !== void 0) body.title = opts.title;
|
|
1369
|
+
if (opts.content !== void 0) body.content = opts.content;
|
|
1370
|
+
if (opts.dueDate !== void 0) body.dueDate = opts.dueDate;
|
|
1371
|
+
const url2 = `${BASE_URL5}/tasks/${opts.taskId}`;
|
|
1372
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
1373
|
+
console.error(`[nworks] PATCH ${url2}`);
|
|
1374
|
+
}
|
|
1375
|
+
const res = await authedFetch3(
|
|
1376
|
+
url2,
|
|
1377
|
+
{
|
|
1378
|
+
method: "PATCH",
|
|
1379
|
+
headers: { "Content-Type": "application/json" },
|
|
1380
|
+
body: JSON.stringify(body)
|
|
1381
|
+
},
|
|
1382
|
+
profile
|
|
1383
|
+
);
|
|
1384
|
+
if (!res.ok) return handleError3(res);
|
|
1385
|
+
return await res.json();
|
|
1386
|
+
}
|
|
1387
|
+
async function completeTask(taskId, profile = "default") {
|
|
1388
|
+
const url2 = `${BASE_URL5}/tasks/${taskId}/complete`;
|
|
1389
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
1390
|
+
console.error(`[nworks] POST ${url2}`);
|
|
1391
|
+
}
|
|
1392
|
+
const res = await authedFetch3(
|
|
1393
|
+
url2,
|
|
1394
|
+
{ method: "POST" },
|
|
1395
|
+
profile
|
|
1396
|
+
);
|
|
1397
|
+
if (res.status === 204) return;
|
|
1398
|
+
if (!res.ok) return handleError3(res);
|
|
1399
|
+
}
|
|
1400
|
+
async function incompleteTask(taskId, profile = "default") {
|
|
1401
|
+
const url2 = `${BASE_URL5}/tasks/${taskId}/incomplete`;
|
|
1402
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
1403
|
+
console.error(`[nworks] POST ${url2}`);
|
|
1404
|
+
}
|
|
1405
|
+
const res = await authedFetch3(
|
|
1406
|
+
url2,
|
|
1407
|
+
{ method: "POST" },
|
|
1408
|
+
profile
|
|
1409
|
+
);
|
|
1410
|
+
if (res.status === 204) return;
|
|
1411
|
+
if (!res.ok) return handleError3(res);
|
|
1412
|
+
}
|
|
1413
|
+
async function deleteTask(taskId, profile = "default") {
|
|
1414
|
+
const url2 = `${BASE_URL5}/tasks/${taskId}`;
|
|
1415
|
+
if (process.env["NWORKS_VERBOSE"] === "1") {
|
|
1416
|
+
console.error(`[nworks] DELETE ${url2}`);
|
|
1417
|
+
}
|
|
1418
|
+
const res = await authedFetch3(
|
|
1419
|
+
url2,
|
|
1420
|
+
{ method: "DELETE" },
|
|
1421
|
+
profile
|
|
1422
|
+
);
|
|
1423
|
+
if (res.status === 204) return;
|
|
1424
|
+
if (!res.ok) return handleError3(res);
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
// src/commands/task.ts
|
|
1428
|
+
var listCommand4 = new Command9("list").description("List tasks (requires User OAuth with task or task.read scope)").option("--category <categoryId>", "Category ID (default: default)", "default").option("--status <status>", "Filter: TODO or ALL (default: ALL)", "ALL").option("--count <n>", "Items per page (default: 50)", "50").option("--cursor <cursor>", "Pagination cursor").option("--user <userId>", "Target user ID (default: me)").option("--profile <name>", "Profile name", "default").option("--json", "JSON output").action(async (opts) => {
|
|
1429
|
+
try {
|
|
1430
|
+
const result = await listTasks(
|
|
1431
|
+
opts.category,
|
|
1432
|
+
opts.user ?? "me",
|
|
1433
|
+
parseInt(opts.count, 10),
|
|
1434
|
+
opts.cursor,
|
|
1435
|
+
opts.status,
|
|
1436
|
+
opts.profile
|
|
1437
|
+
);
|
|
1438
|
+
const tasks = result.tasks.map((t) => ({
|
|
1439
|
+
taskId: t.taskId,
|
|
1440
|
+
title: t.title,
|
|
1441
|
+
status: t.status,
|
|
1442
|
+
dueDate: t.dueDate ?? "",
|
|
1443
|
+
assignor: t.assignorName ?? t.assignorId,
|
|
1444
|
+
created: t.createdTime
|
|
1445
|
+
}));
|
|
1446
|
+
output(
|
|
1447
|
+
{
|
|
1448
|
+
tasks,
|
|
1449
|
+
count: tasks.length,
|
|
1450
|
+
nextCursor: result.responseMetaData?.nextCursor ?? null
|
|
1451
|
+
},
|
|
1452
|
+
opts
|
|
1453
|
+
);
|
|
1454
|
+
} catch (err) {
|
|
1455
|
+
const error48 = err;
|
|
1456
|
+
errorOutput({ code: error48.code, message: error48.message }, opts);
|
|
1457
|
+
process.exitCode = 1;
|
|
1458
|
+
}
|
|
1459
|
+
});
|
|
1460
|
+
var createCommand = new Command9("create").description("Create a task (requires User OAuth with task scope)").requiredOption("--title <title>", "Task title").option("--body <content>", "Task content/description").option("--due <date>", "Due date (YYYY-MM-DD)").option("--category <categoryId>", "Category ID").option("--assignee <userIds>", "Assignee user IDs (comma-separated)").option("--user <userId>", "Creator user ID (default: me)").option("--profile <name>", "Profile name", "default").option("--json", "JSON output").action(async (opts) => {
|
|
1461
|
+
try {
|
|
1462
|
+
const assigneeIds = opts.assignee ? opts.assignee.split(",").map((s) => s.trim()) : void 0;
|
|
1463
|
+
const result = await createTask({
|
|
1464
|
+
title: opts.title,
|
|
1465
|
+
content: opts.body,
|
|
1466
|
+
dueDate: opts.due,
|
|
1467
|
+
categoryId: opts.category,
|
|
1468
|
+
assigneeIds,
|
|
1469
|
+
userId: opts.user ?? "me",
|
|
1470
|
+
profile: opts.profile
|
|
1471
|
+
});
|
|
1472
|
+
output(
|
|
1473
|
+
{
|
|
1474
|
+
success: true,
|
|
1475
|
+
taskId: result.taskId,
|
|
1476
|
+
title: result.title,
|
|
1477
|
+
status: result.status,
|
|
1478
|
+
dueDate: result.dueDate
|
|
1479
|
+
},
|
|
1480
|
+
opts
|
|
1481
|
+
);
|
|
1482
|
+
} catch (err) {
|
|
1483
|
+
const error48 = err;
|
|
1484
|
+
errorOutput({ code: error48.code, message: error48.message }, opts);
|
|
1485
|
+
process.exitCode = 1;
|
|
1486
|
+
}
|
|
1487
|
+
});
|
|
1488
|
+
var updateCommand = new Command9("update").description("Update a task (requires User OAuth with task scope)").requiredOption("--id <taskId>", "Task ID").option("--title <title>", "New title").option("--body <content>", "New content").option("--due <date>", "New due date (YYYY-MM-DD)").option("--status <status>", "Set status: done or todo").option("--profile <name>", "Profile name", "default").option("--json", "JSON output").action(async (opts) => {
|
|
1489
|
+
try {
|
|
1490
|
+
const profile = opts.profile;
|
|
1491
|
+
const taskId = opts.id;
|
|
1492
|
+
const status = opts.status;
|
|
1493
|
+
if (status) {
|
|
1494
|
+
if (status.toLowerCase() === "done") {
|
|
1495
|
+
await completeTask(taskId, profile);
|
|
1496
|
+
} else if (status.toLowerCase() === "todo") {
|
|
1497
|
+
await incompleteTask(taskId, profile);
|
|
1498
|
+
} else {
|
|
1499
|
+
throw new Error("Invalid status. Use 'done' or 'todo'.");
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
const hasFieldUpdate = opts.title || opts.body || opts.due;
|
|
1503
|
+
if (hasFieldUpdate) {
|
|
1504
|
+
const result = await updateTask({
|
|
1505
|
+
taskId,
|
|
1506
|
+
title: opts.title,
|
|
1507
|
+
content: opts.body,
|
|
1508
|
+
dueDate: opts.due,
|
|
1509
|
+
profile
|
|
1510
|
+
});
|
|
1511
|
+
output(
|
|
1512
|
+
{
|
|
1513
|
+
success: true,
|
|
1514
|
+
taskId: result.taskId,
|
|
1515
|
+
title: result.title,
|
|
1516
|
+
status: result.status,
|
|
1517
|
+
dueDate: result.dueDate
|
|
1518
|
+
},
|
|
1519
|
+
opts
|
|
1520
|
+
);
|
|
1521
|
+
} else if (status) {
|
|
1522
|
+
output(
|
|
1523
|
+
{ success: true, taskId, status: status.toLowerCase() === "done" ? "DONE" : "TODO" },
|
|
1524
|
+
opts
|
|
1525
|
+
);
|
|
1526
|
+
} else {
|
|
1527
|
+
throw new Error("Specify at least one of: --title, --body, --due, --status");
|
|
1528
|
+
}
|
|
1529
|
+
} catch (err) {
|
|
1530
|
+
const error48 = err;
|
|
1531
|
+
errorOutput({ code: error48.code, message: error48.message }, opts);
|
|
1532
|
+
process.exitCode = 1;
|
|
1533
|
+
}
|
|
1534
|
+
});
|
|
1535
|
+
var deleteCommand = new Command9("delete").description("Delete a task (requires User OAuth with task scope)").requiredOption("--id <taskId>", "Task ID").option("--profile <name>", "Profile name", "default").option("--json", "JSON output").action(async (opts) => {
|
|
1536
|
+
try {
|
|
1537
|
+
await deleteTask(
|
|
1538
|
+
opts.id,
|
|
1539
|
+
opts.profile
|
|
1540
|
+
);
|
|
1541
|
+
output({ success: true, taskId: opts.id, message: "Task deleted" }, opts);
|
|
1542
|
+
} catch (err) {
|
|
1543
|
+
const error48 = err;
|
|
1544
|
+
errorOutput({ code: error48.code, message: error48.message }, opts);
|
|
1545
|
+
process.exitCode = 1;
|
|
1546
|
+
}
|
|
1547
|
+
});
|
|
1548
|
+
var taskCommand = new Command9("task").description("Task operations (requires User OAuth with task scope)").addCommand(listCommand4).addCommand(createCommand).addCommand(updateCommand).addCommand(deleteCommand);
|
|
1549
|
+
|
|
1550
|
+
// src/commands/mcp-cmd.ts
|
|
1551
|
+
import { Command as Command10 } from "commander";
|
|
1552
|
+
|
|
1282
1553
|
// src/mcp/server.ts
|
|
1283
1554
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
1284
1555
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -15413,6 +15684,142 @@ function registerTools(server) {
|
|
|
15413
15684
|
}
|
|
15414
15685
|
}
|
|
15415
15686
|
);
|
|
15687
|
+
server.tool(
|
|
15688
|
+
"nworks_task_list",
|
|
15689
|
+
"\uD560 \uC77C \uBAA9\uB85D\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4 (User OAuth task \uB610\uB294 task.read scope \uD544\uC694)",
|
|
15690
|
+
{
|
|
15691
|
+
categoryId: external_exports.string().optional().describe("\uCE74\uD14C\uACE0\uB9AC ID (\uAE30\uBCF8: default)"),
|
|
15692
|
+
status: external_exports.enum(["TODO", "ALL"]).optional().describe("\uD544\uD130: TODO \uB610\uB294 ALL (\uAE30\uBCF8: ALL)"),
|
|
15693
|
+
count: external_exports.number().optional().describe("\uD398\uC774\uC9C0\uB2F9 \uD56D\uBAA9 \uC218 (\uAE30\uBCF8: 50, \uCD5C\uB300: 100)"),
|
|
15694
|
+
cursor: external_exports.string().optional().describe("\uD398\uC774\uC9C0\uB124\uC774\uC158 \uCEE4\uC11C"),
|
|
15695
|
+
userId: external_exports.string().optional().describe("\uB300\uC0C1 \uC0AC\uC6A9\uC790 ID (\uBBF8\uC9C0\uC815 \uC2DC me)")
|
|
15696
|
+
},
|
|
15697
|
+
async ({ categoryId, status, count, cursor, userId }) => {
|
|
15698
|
+
try {
|
|
15699
|
+
const result = await listTasks(
|
|
15700
|
+
categoryId ?? "default",
|
|
15701
|
+
userId ?? "me",
|
|
15702
|
+
count ?? 50,
|
|
15703
|
+
cursor,
|
|
15704
|
+
status ?? "ALL"
|
|
15705
|
+
);
|
|
15706
|
+
const tasks = result.tasks.map((t) => ({
|
|
15707
|
+
taskId: t.taskId,
|
|
15708
|
+
title: t.title,
|
|
15709
|
+
status: t.status,
|
|
15710
|
+
dueDate: t.dueDate,
|
|
15711
|
+
assignor: t.assignorName ?? t.assignorId,
|
|
15712
|
+
created: t.createdTime
|
|
15713
|
+
}));
|
|
15714
|
+
return {
|
|
15715
|
+
content: [{ type: "text", text: JSON.stringify({ tasks, count: tasks.length, nextCursor: result.responseMetaData?.nextCursor ?? null }) }]
|
|
15716
|
+
};
|
|
15717
|
+
} catch (err) {
|
|
15718
|
+
const error48 = err;
|
|
15719
|
+
return {
|
|
15720
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15721
|
+
isError: true
|
|
15722
|
+
};
|
|
15723
|
+
}
|
|
15724
|
+
}
|
|
15725
|
+
);
|
|
15726
|
+
server.tool(
|
|
15727
|
+
"nworks_task_create",
|
|
15728
|
+
"\uD560 \uC77C\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4 (User OAuth task scope \uD544\uC694). \uAE30\uBCF8\uC801\uC73C\uB85C \uC790\uAE30 \uC790\uC2E0\uC5D0\uAC8C \uD560\uB2F9\uB429\uB2C8\uB2E4.",
|
|
15729
|
+
{
|
|
15730
|
+
title: external_exports.string().describe("\uD560 \uC77C \uC81C\uBAA9"),
|
|
15731
|
+
content: external_exports.string().optional().describe("\uD560 \uC77C \uB0B4\uC6A9"),
|
|
15732
|
+
dueDate: external_exports.string().optional().describe("\uB9C8\uAC10\uC77C (YYYY-MM-DD)"),
|
|
15733
|
+
categoryId: external_exports.string().optional().describe("\uCE74\uD14C\uACE0\uB9AC ID"),
|
|
15734
|
+
assigneeIds: external_exports.array(external_exports.string()).optional().describe("\uB2F4\uB2F9\uC790 user ID \uBAA9\uB85D (\uBBF8\uC9C0\uC815 \uC2DC \uC790\uAE30 \uC790\uC2E0)"),
|
|
15735
|
+
userId: external_exports.string().optional().describe("\uC0DD\uC131\uC790 user ID (\uBBF8\uC9C0\uC815 \uC2DC me)")
|
|
15736
|
+
},
|
|
15737
|
+
async ({ title, content, dueDate, categoryId, assigneeIds, userId }) => {
|
|
15738
|
+
try {
|
|
15739
|
+
const result = await createTask({
|
|
15740
|
+
title,
|
|
15741
|
+
content,
|
|
15742
|
+
dueDate,
|
|
15743
|
+
categoryId,
|
|
15744
|
+
assigneeIds,
|
|
15745
|
+
userId: userId ?? "me"
|
|
15746
|
+
});
|
|
15747
|
+
return {
|
|
15748
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, taskId: result.taskId, title: result.title, status: result.status, dueDate: result.dueDate }) }]
|
|
15749
|
+
};
|
|
15750
|
+
} catch (err) {
|
|
15751
|
+
const error48 = err;
|
|
15752
|
+
return {
|
|
15753
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15754
|
+
isError: true
|
|
15755
|
+
};
|
|
15756
|
+
}
|
|
15757
|
+
}
|
|
15758
|
+
);
|
|
15759
|
+
server.tool(
|
|
15760
|
+
"nworks_task_update",
|
|
15761
|
+
"\uD560 \uC77C\uC744 \uC218\uC815\uD569\uB2C8\uB2E4 (User OAuth task scope \uD544\uC694). \uC0C1\uD0DC \uBCC0\uACBD(done/todo)\uACFC \uD544\uB4DC \uC218\uC815\uC744 \uBAA8\uB450 \uC9C0\uC6D0\uD569\uB2C8\uB2E4.",
|
|
15762
|
+
{
|
|
15763
|
+
taskId: external_exports.string().describe("\uD560 \uC77C ID"),
|
|
15764
|
+
status: external_exports.enum(["done", "todo"]).optional().describe("\uC0C1\uD0DC \uBCC0\uACBD: done \uB610\uB294 todo"),
|
|
15765
|
+
title: external_exports.string().optional().describe("\uC0C8 \uC81C\uBAA9"),
|
|
15766
|
+
content: external_exports.string().optional().describe("\uC0C8 \uB0B4\uC6A9"),
|
|
15767
|
+
dueDate: external_exports.string().optional().describe("\uC0C8 \uB9C8\uAC10\uC77C (YYYY-MM-DD)")
|
|
15768
|
+
},
|
|
15769
|
+
async ({ taskId, status, title, content, dueDate }) => {
|
|
15770
|
+
try {
|
|
15771
|
+
if (status) {
|
|
15772
|
+
if (status === "done") {
|
|
15773
|
+
await completeTask(taskId);
|
|
15774
|
+
} else {
|
|
15775
|
+
await incompleteTask(taskId);
|
|
15776
|
+
}
|
|
15777
|
+
}
|
|
15778
|
+
if (title !== void 0 || content !== void 0 || dueDate !== void 0) {
|
|
15779
|
+
const result = await updateTask({ taskId, title, content, dueDate });
|
|
15780
|
+
return {
|
|
15781
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, taskId: result.taskId, title: result.title, status: result.status, dueDate: result.dueDate }) }]
|
|
15782
|
+
};
|
|
15783
|
+
}
|
|
15784
|
+
if (status) {
|
|
15785
|
+
return {
|
|
15786
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, taskId, status: status === "done" ? "DONE" : "TODO" }) }]
|
|
15787
|
+
};
|
|
15788
|
+
}
|
|
15789
|
+
return {
|
|
15790
|
+
content: [{ type: "text", text: "Error: status, title, content, dueDate \uC911 \uD558\uB098 \uC774\uC0C1\uC744 \uC9C0\uC815\uD558\uC138\uC694." }],
|
|
15791
|
+
isError: true
|
|
15792
|
+
};
|
|
15793
|
+
} catch (err) {
|
|
15794
|
+
const error48 = err;
|
|
15795
|
+
return {
|
|
15796
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15797
|
+
isError: true
|
|
15798
|
+
};
|
|
15799
|
+
}
|
|
15800
|
+
}
|
|
15801
|
+
);
|
|
15802
|
+
server.tool(
|
|
15803
|
+
"nworks_task_delete",
|
|
15804
|
+
"\uD560 \uC77C\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4 (User OAuth task scope \uD544\uC694)",
|
|
15805
|
+
{
|
|
15806
|
+
taskId: external_exports.string().describe("\uC0AD\uC81C\uD560 \uD560 \uC77C ID")
|
|
15807
|
+
},
|
|
15808
|
+
async ({ taskId }) => {
|
|
15809
|
+
try {
|
|
15810
|
+
await deleteTask(taskId);
|
|
15811
|
+
return {
|
|
15812
|
+
content: [{ type: "text", text: JSON.stringify({ success: true, taskId, message: "Task deleted" }) }]
|
|
15813
|
+
};
|
|
15814
|
+
} catch (err) {
|
|
15815
|
+
const error48 = err;
|
|
15816
|
+
return {
|
|
15817
|
+
content: [{ type: "text", text: `Error: ${error48.message}` }],
|
|
15818
|
+
isError: true
|
|
15819
|
+
};
|
|
15820
|
+
}
|
|
15821
|
+
}
|
|
15822
|
+
);
|
|
15416
15823
|
server.tool(
|
|
15417
15824
|
"nworks_whoami",
|
|
15418
15825
|
"\uD604\uC7AC \uC778\uC99D\uB41C NAVER WORKS \uACC4\uC815 \uC815\uBCF4\uB97C \uD655\uC778\uD569\uB2C8\uB2E4",
|
|
@@ -15454,7 +15861,7 @@ async function startMcpServer() {
|
|
|
15454
15861
|
}
|
|
15455
15862
|
|
|
15456
15863
|
// src/commands/mcp-cmd.ts
|
|
15457
|
-
var mcpCommand = new
|
|
15864
|
+
var mcpCommand = new Command10("mcp").description("Start MCP server (stdio transport)").option("--list-tools", "List available MCP tools").action(async (opts) => {
|
|
15458
15865
|
if (opts.listTools) {
|
|
15459
15866
|
console.log("nworks_message_send \u2014 Send message to user or channel");
|
|
15460
15867
|
console.log("nworks_message_members \u2014 List channel members");
|
|
@@ -15469,7 +15876,7 @@ var mcpCommand = new Command9("mcp").description("Start MCP server (stdio transp
|
|
|
15469
15876
|
// src/index.ts
|
|
15470
15877
|
var require2 = createRequire(import.meta.url);
|
|
15471
15878
|
var { version: version2 } = require2("../package.json");
|
|
15472
|
-
var program = new
|
|
15879
|
+
var program = new Command11().name("nworks").description("NAVER WORKS CLI \u2014 built for humans and AI agents").version(version2).option("--json", "Always output JSON").option("-v, --verbose", "Debug logging").option("--dry-run", "Print request without calling API").option("-p, --profile <name>", "Profile name", "default");
|
|
15473
15880
|
program.addCommand(loginCommand);
|
|
15474
15881
|
program.addCommand(logoutCommand);
|
|
15475
15882
|
program.addCommand(whoamiCommand);
|
|
@@ -15478,6 +15885,7 @@ program.addCommand(directoryCommand);
|
|
|
15478
15885
|
program.addCommand(calendarCommand);
|
|
15479
15886
|
program.addCommand(driveCommand);
|
|
15480
15887
|
program.addCommand(mailCommand);
|
|
15888
|
+
program.addCommand(taskCommand);
|
|
15481
15889
|
program.addCommand(mcpCommand);
|
|
15482
15890
|
program.parse();
|
|
15483
15891
|
//# sourceMappingURL=index.js.map
|