nworks 0.3.1 → 0.3.3

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/mcp.js CHANGED
@@ -14230,6 +14230,51 @@ Content-Type: application/octet-stream\r
14230
14230
  if (!uploadRes.ok) return handleError(uploadRes);
14231
14231
  return await uploadRes.json();
14232
14232
  }
14233
+ async function uploadBuffer(fileBuffer, fileName, userId = "me", folderId, overwrite = false, profile = "default") {
14234
+ const fileSize = fileBuffer.length;
14235
+ const base = `${BASE_URL3}/users/${userId}/drive/files`;
14236
+ const createUrl = folderId ? `${base}/${folderId}` : base;
14237
+ if (process.env["NWORKS_VERBOSE"] === "1") {
14238
+ console.error(`[nworks] POST ${createUrl} (create upload URL for buffer)`);
14239
+ }
14240
+ const createRes = await authedFetch(
14241
+ createUrl,
14242
+ {
14243
+ method: "POST",
14244
+ headers: { "Content-Type": "application/json" },
14245
+ body: JSON.stringify({ fileName, fileSize, overwrite })
14246
+ },
14247
+ profile
14248
+ );
14249
+ if (!createRes.ok) return handleError(createRes);
14250
+ const { uploadUrl } = await createRes.json();
14251
+ const boundary = `----nworks${Date.now()}`;
14252
+ const header = Buffer.from(
14253
+ `--${boundary}\r
14254
+ Content-Disposition: form-data; name="Filedata"; filename="${fileName}"\r
14255
+ Content-Type: application/octet-stream\r
14256
+ \r
14257
+ `
14258
+ );
14259
+ const footer = Buffer.from(`\r
14260
+ --${boundary}--\r
14261
+ `);
14262
+ const body = Buffer.concat([header, fileBuffer, footer]);
14263
+ if (process.env["NWORKS_VERBOSE"] === "1") {
14264
+ console.error(`[nworks] POST ${uploadUrl} (upload buffer, ${fileSize} bytes)`);
14265
+ }
14266
+ const uploadRes = await authedFetch(
14267
+ uploadUrl,
14268
+ {
14269
+ method: "POST",
14270
+ headers: { "Content-Type": `multipart/form-data; boundary=${boundary}` },
14271
+ body
14272
+ },
14273
+ profile
14274
+ );
14275
+ if (!uploadRes.ok) return handleError(uploadRes);
14276
+ return await uploadRes.json();
14277
+ }
14233
14278
  async function downloadFile(fileId, userId = "me", profile = "default") {
14234
14279
  const url2 = `${BASE_URL3}/users/${userId}/drive/files/${fileId}/download`;
14235
14280
  if (process.env["NWORKS_VERBOSE"] === "1") {
@@ -14415,28 +14460,54 @@ function registerTools(server) {
14415
14460
  );
14416
14461
  server.tool(
14417
14462
  "nworks_drive_upload",
14418
- "\uB85C\uCEEC \uD30C\uC77C\uC744 \uB4DC\uB77C\uC774\uBE0C\uC5D0 \uC5C5\uB85C\uB4DC\uD569\uB2C8\uB2E4 (User OAuth file scope \uD544\uC694)",
14463
+ "\uD30C\uC77C\uC744 \uB4DC\uB77C\uC774\uBE0C\uC5D0 \uC5C5\uB85C\uB4DC\uD569\uB2C8\uB2E4 (User OAuth file scope \uD544\uC694). content(base64)\uC640 fileName\uC73C\uB85C \uC804\uB2EC\uD558\uAC70\uB098, filePath\uB85C \uB85C\uCEEC \uD30C\uC77C \uACBD\uB85C\uB97C \uC9C0\uC815\uD569\uB2C8\uB2E4. MCP \uD074\uB77C\uC774\uC5B8\uD2B8\uC5D0\uC11C\uB294 content+fileName \uBC29\uC2DD\uC744 \uAD8C\uC7A5\uD569\uB2C8\uB2E4.",
14419
14464
  {
14420
- filePath: external_exports.string().describe("\uC5C5\uB85C\uB4DC\uD560 \uB85C\uCEEC \uD30C\uC77C \uACBD\uB85C"),
14465
+ content: external_exports.string().optional().describe("\uC5C5\uB85C\uB4DC\uD560 \uD30C\uC77C \uB0B4\uC6A9 (base64 \uC778\uCF54\uB529). filePath \uB300\uC2E0 \uC0AC\uC6A9"),
14466
+ fileName: external_exports.string().optional().describe("\uD30C\uC77C\uBA85 (content \uC0AC\uC6A9 \uC2DC \uD544\uC218)"),
14467
+ filePath: external_exports.string().optional().describe("\uC5C5\uB85C\uB4DC\uD560 \uB85C\uCEEC \uD30C\uC77C \uACBD\uB85C (content \uB300\uC2E0 \uC0AC\uC6A9, \uB85C\uCEEC \uD658\uACBD\uC5D0\uC11C\uB9CC \uB3D9\uC791)"),
14421
14468
  userId: external_exports.string().optional().describe("\uB300\uC0C1 \uC0AC\uC6A9\uC790 ID (\uBBF8\uC9C0\uC815 \uC2DC me)"),
14422
14469
  folderId: external_exports.string().optional().describe("\uC5C5\uB85C\uB4DC\uD560 \uD3F4\uB354 ID (\uBBF8\uC9C0\uC815 \uC2DC \uB8E8\uD2B8)"),
14423
14470
  overwrite: external_exports.boolean().optional().describe("\uB3D9\uC77C \uD30C\uC77C\uBA85 \uB36E\uC5B4\uC4F0\uAE30 (\uAE30\uBCF8: false)")
14424
14471
  },
14425
- async ({ filePath, userId, folderId, overwrite }) => {
14472
+ async ({ content, fileName, filePath, userId, folderId, overwrite }) => {
14426
14473
  try {
14427
- const result = await uploadFile(
14428
- filePath,
14429
- userId ?? "me",
14430
- folderId,
14431
- overwrite ?? false
14432
- );
14474
+ let result;
14475
+ if (content && fileName) {
14476
+ const buffer = Buffer.from(content, "base64");
14477
+ if (process.env["NWORKS_VERBOSE"] === "1") {
14478
+ console.error(`[nworks] MCP upload: fileName=${fileName}, bufferSize=${buffer.length}`);
14479
+ }
14480
+ result = await uploadBuffer(
14481
+ buffer,
14482
+ fileName,
14483
+ userId ?? "me",
14484
+ folderId,
14485
+ overwrite ?? false
14486
+ );
14487
+ } else if (filePath) {
14488
+ if (process.env["NWORKS_VERBOSE"] === "1") {
14489
+ console.error(`[nworks] MCP upload: filePath=${filePath}`);
14490
+ }
14491
+ result = await uploadFile(
14492
+ filePath,
14493
+ userId ?? "me",
14494
+ folderId,
14495
+ overwrite ?? false
14496
+ );
14497
+ } else {
14498
+ return {
14499
+ content: [{ type: "text", text: "Error: content+fileName \uB610\uB294 filePath \uC911 \uD558\uB098\uB97C \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4. MCP \uD074\uB77C\uC774\uC5B8\uD2B8\uC5D0\uC11C\uB294 \uD30C\uC77C \uB0B4\uC6A9\uC744 base64\uB85C \uC778\uCF54\uB529\uD558\uC5EC content \uD30C\uB77C\uBBF8\uD130\uC5D0 \uC804\uB2EC\uD558\uACE0, fileName\uC5D0 \uD30C\uC77C\uBA85\uC744 \uC9C0\uC815\uD558\uC138\uC694." }],
14500
+ isError: true
14501
+ };
14502
+ }
14433
14503
  return {
14434
14504
  content: [{ type: "text", text: JSON.stringify({ success: true, ...result }) }]
14435
14505
  };
14436
14506
  } catch (err) {
14437
14507
  const error48 = err;
14508
+ const detail = process.env["NWORKS_VERBOSE"] === "1" ? ` | stack: ${error48.stack}` : "";
14438
14509
  return {
14439
- content: [{ type: "text", text: `Error: ${error48.message}` }],
14510
+ content: [{ type: "text", text: `Error: ${error48.message}${detail}` }],
14440
14511
  isError: true
14441
14512
  };
14442
14513
  }
@@ -14444,27 +14515,40 @@ function registerTools(server) {
14444
14515
  );
14445
14516
  server.tool(
14446
14517
  "nworks_drive_download",
14447
- "\uB4DC\uB77C\uC774\uBE0C \uD30C\uC77C\uC744 \uB2E4\uC6B4\uB85C\uB4DC\uD569\uB2C8\uB2E4 (User OAuth file \uB610\uB294 file.read scope \uD544\uC694)",
14518
+ "\uB4DC\uB77C\uC774\uBE0C \uD30C\uC77C\uC744 \uB2E4\uC6B4\uB85C\uB4DC\uD569\uB2C8\uB2E4 (User OAuth file \uB610\uB294 file.read scope \uD544\uC694). outputDir\uC744 \uC9C0\uC815\uD558\uBA74 \uB85C\uCEEC\uC5D0 \uD30C\uC77C\uB85C \uC800\uC7A5\uD558\uACE0, \uBBF8\uC9C0\uC815 \uC2DC \uD30C\uC77C \uB0B4\uC6A9\uC744 \uC9C1\uC811 \uBC18\uD658\uD569\uB2C8\uB2E4 (\uD14D\uC2A4\uD2B8 \uD30C\uC77C\uC740 text, \uBC14\uC774\uB108\uB9AC\uB294 base64).",
14448
14519
  {
14449
14520
  fileId: external_exports.string().describe("\uB2E4\uC6B4\uB85C\uB4DC\uD560 \uD30C\uC77C ID"),
14450
- outputDir: external_exports.string().optional().describe("\uC800\uC7A5 \uB514\uB809\uD1A0\uB9AC (\uBBF8\uC9C0\uC815 \uC2DC \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC)"),
14521
+ outputDir: external_exports.string().optional().describe("\uC800\uC7A5 \uB514\uB809\uD1A0\uB9AC (\uC9C0\uC815 \uC2DC \uD30C\uC77C\uB85C \uC800\uC7A5, \uBBF8\uC9C0\uC815 \uC2DC \uB0B4\uC6A9\uC744 \uC9C1\uC811 \uBC18\uD658)"),
14451
14522
  outputName: external_exports.string().optional().describe("\uC800\uC7A5 \uD30C\uC77C\uBA85 (\uBBF8\uC9C0\uC815 \uC2DC \uC6D0\uBCF8 \uD30C\uC77C\uBA85)"),
14452
14523
  userId: external_exports.string().optional().describe("\uB300\uC0C1 \uC0AC\uC6A9\uC790 ID (\uBBF8\uC9C0\uC815 \uC2DC me)")
14453
14524
  },
14454
14525
  async ({ fileId, outputDir, outputName, userId }) => {
14455
14526
  try {
14456
- const { writeFile: writeFile2 } = await import("fs/promises");
14457
- const { join: join2 } = await import("path");
14458
14527
  const result = await downloadFile(
14459
14528
  fileId,
14460
14529
  userId ?? "me"
14461
14530
  );
14462
14531
  const fileName = outputName ?? result.fileName ?? fileId;
14463
- const dir = outputDir ?? process.cwd();
14464
- const outPath = join2(dir, fileName);
14465
- await writeFile2(outPath, result.buffer);
14532
+ if (outputDir) {
14533
+ const { writeFile: writeFile2 } = await import("fs/promises");
14534
+ const { join: join2 } = await import("path");
14535
+ const outPath = join2(outputDir, fileName);
14536
+ await writeFile2(outPath, result.buffer);
14537
+ return {
14538
+ content: [{ type: "text", text: JSON.stringify({ success: true, fileName, path: outPath, size: result.buffer.length }) }]
14539
+ };
14540
+ }
14541
+ const textExtensions = /\.(txt|md|csv|json|xml|html|htm|css|js|ts|jsx|tsx|yaml|yml|toml|ini|cfg|conf|log|sh|bash|zsh|py|rb|java|go|rs|c|cpp|h|hpp|sql|graphql|env|gitignore|dockerignore|editorconfig)$/i;
14542
+ const isText = textExtensions.test(fileName);
14543
+ if (isText) {
14544
+ const text = result.buffer.toString("utf-8");
14545
+ return {
14546
+ content: [{ type: "text", text: JSON.stringify({ success: true, fileName, size: result.buffer.length, encoding: "text", content: text }) }]
14547
+ };
14548
+ }
14549
+ const base643 = result.buffer.toString("base64");
14466
14550
  return {
14467
- content: [{ type: "text", text: JSON.stringify({ success: true, fileName, path: outPath, size: result.buffer.length }) }]
14551
+ content: [{ type: "text", text: JSON.stringify({ success: true, fileName, size: result.buffer.length, encoding: "base64", content: base643 }) }]
14468
14552
  };
14469
14553
  } catch (err) {
14470
14554
  const error48 = err;