feishu-docs-cli 0.1.0-beta.10

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.
Files changed (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +403 -0
  3. package/README.zh.md +402 -0
  4. package/bin/feishu-docs.js +8 -0
  5. package/dist/auth.d.ts +76 -0
  6. package/dist/auth.js +512 -0
  7. package/dist/auth.js.map +1 -0
  8. package/dist/cli.d.ts +5 -0
  9. package/dist/cli.js +197 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/client.d.ts +28 -0
  12. package/dist/client.js +256 -0
  13. package/dist/client.js.map +1 -0
  14. package/dist/commands/authorize.d.ts +12 -0
  15. package/dist/commands/authorize.js +73 -0
  16. package/dist/commands/authorize.js.map +1 -0
  17. package/dist/commands/cat.d.ts +6 -0
  18. package/dist/commands/cat.js +159 -0
  19. package/dist/commands/cat.js.map +1 -0
  20. package/dist/commands/cp.d.ts +9 -0
  21. package/dist/commands/cp.js +70 -0
  22. package/dist/commands/cp.js.map +1 -0
  23. package/dist/commands/create.d.ts +6 -0
  24. package/dist/commands/create.js +120 -0
  25. package/dist/commands/create.js.map +1 -0
  26. package/dist/commands/delete.d.ts +6 -0
  27. package/dist/commands/delete.js +91 -0
  28. package/dist/commands/delete.js.map +1 -0
  29. package/dist/commands/info.d.ts +6 -0
  30. package/dist/commands/info.js +69 -0
  31. package/dist/commands/info.js.map +1 -0
  32. package/dist/commands/install-skill.d.ts +5 -0
  33. package/dist/commands/install-skill.js +28 -0
  34. package/dist/commands/install-skill.js.map +1 -0
  35. package/dist/commands/login.d.ts +10 -0
  36. package/dist/commands/login.js +93 -0
  37. package/dist/commands/login.js.map +1 -0
  38. package/dist/commands/ls.d.ts +6 -0
  39. package/dist/commands/ls.js +79 -0
  40. package/dist/commands/ls.js.map +1 -0
  41. package/dist/commands/mkdir.d.ts +6 -0
  42. package/dist/commands/mkdir.js +49 -0
  43. package/dist/commands/mkdir.js.map +1 -0
  44. package/dist/commands/mv.d.ts +9 -0
  45. package/dist/commands/mv.js +72 -0
  46. package/dist/commands/mv.js.map +1 -0
  47. package/dist/commands/read.d.ts +6 -0
  48. package/dist/commands/read.js +439 -0
  49. package/dist/commands/read.js.map +1 -0
  50. package/dist/commands/search.d.ts +7 -0
  51. package/dist/commands/search.js +92 -0
  52. package/dist/commands/search.js.map +1 -0
  53. package/dist/commands/share.d.ts +13 -0
  54. package/dist/commands/share.js +266 -0
  55. package/dist/commands/share.js.map +1 -0
  56. package/dist/commands/spaces.d.ts +6 -0
  57. package/dist/commands/spaces.js +43 -0
  58. package/dist/commands/spaces.js.map +1 -0
  59. package/dist/commands/tree.d.ts +6 -0
  60. package/dist/commands/tree.js +101 -0
  61. package/dist/commands/tree.js.map +1 -0
  62. package/dist/commands/update.d.ts +9 -0
  63. package/dist/commands/update.js +217 -0
  64. package/dist/commands/update.js.map +1 -0
  65. package/dist/commands/wiki.d.ts +6 -0
  66. package/dist/commands/wiki.js +286 -0
  67. package/dist/commands/wiki.js.map +1 -0
  68. package/dist/parser/block-types.d.ts +141 -0
  69. package/dist/parser/block-types.js +167 -0
  70. package/dist/parser/block-types.js.map +1 -0
  71. package/dist/parser/blocks-to-md.d.ts +26 -0
  72. package/dist/parser/blocks-to-md.js +666 -0
  73. package/dist/parser/blocks-to-md.js.map +1 -0
  74. package/dist/parser/text-elements.d.ts +13 -0
  75. package/dist/parser/text-elements.js +91 -0
  76. package/dist/parser/text-elements.js.map +1 -0
  77. package/dist/scopes.d.ts +21 -0
  78. package/dist/scopes.js +48 -0
  79. package/dist/scopes.js.map +1 -0
  80. package/dist/services/block-writer.d.ts +29 -0
  81. package/dist/services/block-writer.js +131 -0
  82. package/dist/services/block-writer.js.map +1 -0
  83. package/dist/services/doc-blocks.d.ts +8 -0
  84. package/dist/services/doc-blocks.js +26 -0
  85. package/dist/services/doc-blocks.js.map +1 -0
  86. package/dist/services/markdown-convert.d.ts +68 -0
  87. package/dist/services/markdown-convert.js +217 -0
  88. package/dist/services/markdown-convert.js.map +1 -0
  89. package/dist/services/wiki-nodes.d.ts +20 -0
  90. package/dist/services/wiki-nodes.js +46 -0
  91. package/dist/services/wiki-nodes.js.map +1 -0
  92. package/dist/types/index.d.ts +236 -0
  93. package/dist/types/index.js +5 -0
  94. package/dist/types/index.js.map +1 -0
  95. package/dist/utils/document-resolver.d.ts +26 -0
  96. package/dist/utils/document-resolver.js +46 -0
  97. package/dist/utils/document-resolver.js.map +1 -0
  98. package/dist/utils/drive-types.d.ts +4 -0
  99. package/dist/utils/drive-types.js +16 -0
  100. package/dist/utils/drive-types.js.map +1 -0
  101. package/dist/utils/errors.d.ts +23 -0
  102. package/dist/utils/errors.js +114 -0
  103. package/dist/utils/errors.js.map +1 -0
  104. package/dist/utils/member.d.ts +11 -0
  105. package/dist/utils/member.js +30 -0
  106. package/dist/utils/member.js.map +1 -0
  107. package/dist/utils/scope-prompt.d.ts +39 -0
  108. package/dist/utils/scope-prompt.js +134 -0
  109. package/dist/utils/scope-prompt.js.map +1 -0
  110. package/dist/utils/url-parser.d.ts +5 -0
  111. package/dist/utils/url-parser.js +55 -0
  112. package/dist/utils/url-parser.js.map +1 -0
  113. package/dist/utils/validate.d.ts +8 -0
  114. package/dist/utils/validate.js +15 -0
  115. package/dist/utils/validate.js.map +1 -0
  116. package/dist/utils/version.d.ts +12 -0
  117. package/dist/utils/version.js +128 -0
  118. package/dist/utils/version.js.map +1 -0
  119. package/package.json +53 -0
  120. package/skills/feishu-docs/SKILL.md +194 -0
@@ -0,0 +1,159 @@
1
+ /**
2
+ * cat command: Recursively read all documents under a knowledge base node.
3
+ */
4
+ import { createClient } from "../client.js";
5
+ import { blocksToMarkdown } from "../parser/blocks-to-md.js";
6
+ import { fetchChildren } from "../services/wiki-nodes.js";
7
+ import { fetchAllBlocks } from "../services/doc-blocks.js";
8
+ import { CliError } from "../utils/errors.js";
9
+ import { validateToken } from "../utils/validate.js";
10
+ /**
11
+ * Parse size string like "500k", "1m" to bytes.
12
+ */
13
+ function parseSize(sizeStr) {
14
+ if (typeof sizeStr === "number")
15
+ return sizeStr;
16
+ const match = String(sizeStr).match(/^(\d+(?:\.\d+)?)\s*([km]?)$/i);
17
+ if (!match)
18
+ return Number(sizeStr) || Infinity;
19
+ const num = parseFloat(match[1]);
20
+ const unit = match[2].toLowerCase();
21
+ if (unit === "k")
22
+ return num * 1024;
23
+ if (unit === "m")
24
+ return num * 1024 * 1024;
25
+ return num;
26
+ }
27
+ /**
28
+ * Recursively collect and output documents.
29
+ */
30
+ async function walkNodes(authInfo, spaceId, parentNodeToken, path, ctx) {
31
+ if (ctx.stopped)
32
+ return;
33
+ if (ctx.maxDepth !== undefined && ctx.currentDepth >= ctx.maxDepth)
34
+ return;
35
+ const children = await fetchChildren(authInfo, spaceId, parentNodeToken);
36
+ for (const node of children) {
37
+ if (ctx.stopped)
38
+ return;
39
+ const nodePath = path
40
+ ? `${path}/${node.title || "(无标题)"}`
41
+ : node.title || "(无标题)";
42
+ const objType = node.obj_type || "unknown";
43
+ // Filter by type
44
+ if (ctx.typeFilter && objType !== ctx.typeFilter) {
45
+ // Still recurse into non-matching nodes that have children
46
+ if (node.has_child) {
47
+ ctx.currentDepth++;
48
+ try {
49
+ await walkNodes(authInfo, spaceId, node.node_token, nodePath, ctx);
50
+ }
51
+ finally {
52
+ ctx.currentDepth--;
53
+ }
54
+ }
55
+ continue;
56
+ }
57
+ // Check limits
58
+ if (ctx.docsRead >= ctx.maxDocs) {
59
+ ctx.skipped++;
60
+ ctx.stopped = true;
61
+ process.stderr.write(`feishu-docs: warning: 已达到 --max-docs 上限 (${ctx.maxDocs}),共跳过 ${ctx.skipped} 篇文档\n`);
62
+ return;
63
+ }
64
+ if (ctx.bytesWritten >= ctx.maxBytes) {
65
+ ctx.skipped++;
66
+ ctx.stopped = true;
67
+ process.stderr.write(`feishu-docs: warning: 已达到 --max-bytes 上限,共跳过 ${ctx.skipped} 篇文档\n`);
68
+ return;
69
+ }
70
+ // Output document
71
+ const header = `---\npath: ${nodePath}\ntoken: ${node.node_token}\ntype: ${objType}\n---\n\n`;
72
+ if (ctx.titleOnly) {
73
+ process.stdout.write(header);
74
+ ctx.bytesWritten += Buffer.byteLength(header);
75
+ ctx.docsRead++;
76
+ }
77
+ else if (objType === "docx") {
78
+ try {
79
+ const blocks = await fetchAllBlocks(authInfo, node.obj_token);
80
+ const md = blocksToMarkdown(blocks);
81
+ const output = header + md + "\n";
82
+ // Check byte limit before writing
83
+ const outputBytes = Buffer.byteLength(output);
84
+ if (ctx.bytesWritten + outputBytes > ctx.maxBytes) {
85
+ ctx.skipped++;
86
+ ctx.stopped = true;
87
+ process.stderr.write(`feishu-docs: warning: 已达到 --max-bytes 上限,共跳过 ${ctx.skipped} 篇文档\n`);
88
+ return;
89
+ }
90
+ process.stdout.write(output);
91
+ ctx.bytesWritten += outputBytes;
92
+ ctx.docsRead++;
93
+ }
94
+ catch (err) {
95
+ process.stderr.write(`feishu-docs: warning: 读取 ${nodePath} 失败: ${err.message}\n`);
96
+ ctx.docsRead++;
97
+ }
98
+ }
99
+ else {
100
+ // Non-docx types: output header only with type info
101
+ const output = header + `[${objType}: ${node.obj_token}]\n\n`;
102
+ process.stdout.write(output);
103
+ ctx.bytesWritten += Buffer.byteLength(output);
104
+ ctx.docsRead++;
105
+ }
106
+ // Recurse into children
107
+ if (node.has_child) {
108
+ ctx.currentDepth++;
109
+ try {
110
+ await walkNodes(authInfo, spaceId, node.node_token, nodePath, ctx);
111
+ }
112
+ finally {
113
+ ctx.currentDepth--;
114
+ }
115
+ }
116
+ }
117
+ }
118
+ export const meta = {
119
+ options: {
120
+ node: { type: "string" },
121
+ depth: { type: "string" },
122
+ "max-docs": { type: "string" },
123
+ "max-bytes": { type: "string" },
124
+ "title-only": { type: "boolean", default: false },
125
+ type: { type: "string" },
126
+ },
127
+ positionals: true,
128
+ handler: cat,
129
+ };
130
+ export async function cat(args, globalOpts) {
131
+ const spaceId = args.positionals[0];
132
+ if (!spaceId) {
133
+ throw new CliError("INVALID_ARGS", "缺少知识库 ID。用法: feishu-docs cat <space_id> [--node <token>]");
134
+ }
135
+ validateToken(spaceId, "space_id");
136
+ const { authInfo } = await createClient(globalOpts);
137
+ const parentNode = args.node || undefined;
138
+ if (parentNode)
139
+ validateToken(parentNode, "node_token");
140
+ const ctx = {
141
+ maxDocs: args.maxDocs !== undefined ? Number(args.maxDocs) : 50,
142
+ maxBytes: args.maxBytes !== undefined
143
+ ? parseSize(args.maxBytes)
144
+ : parseSize("1m"),
145
+ maxDepth: args.depth !== undefined ? Number(args.depth) : undefined,
146
+ typeFilter: args.type || undefined,
147
+ titleOnly: args.titleOnly || false,
148
+ docsRead: 0,
149
+ bytesWritten: 0,
150
+ skipped: 0,
151
+ stopped: false,
152
+ currentDepth: 0,
153
+ };
154
+ await walkNodes(authInfo, spaceId, parentNode, "", ctx);
155
+ if (ctx.docsRead === 0) {
156
+ process.stderr.write("feishu-docs: info: 未找到任何文档\n");
157
+ }
158
+ }
159
+ //# sourceMappingURL=cat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cat.js","sourceRoot":"","sources":["../../src/commands/cat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * cp command: Copy a file to a different folder in cloud drive.
3
+ *
4
+ * The copy API requires a name. If --name is not provided,
5
+ * the original document title is fetched and " - 副本" is appended.
6
+ */
7
+ import { CommandMeta, CommandArgs, GlobalOpts } from "../types/index.js";
8
+ export declare const meta: CommandMeta;
9
+ export declare function cp(args: CommandArgs, globalOpts: GlobalOpts): Promise<void>;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * cp command: Copy a file to a different folder in cloud drive.
3
+ *
4
+ * The copy API requires a name. If --name is not provided,
5
+ * the original document title is fetched and " - 副本" is appended.
6
+ */
7
+ import { createClient, fetchWithAuth } from "../client.js";
8
+ import { CliError } from "../utils/errors.js";
9
+ import { withScopeRecovery } from "../utils/scope-prompt.js";
10
+ import { resolveDocument } from "../utils/document-resolver.js";
11
+ import { validateToken } from "../utils/validate.js";
12
+ export const meta = {
13
+ options: {
14
+ name: { type: "string" },
15
+ },
16
+ positionals: true,
17
+ handler: cp,
18
+ };
19
+ export async function cp(args, globalOpts) {
20
+ const input = args.positionals[0];
21
+ const targetFolder = args.positionals[1];
22
+ if (!input || !targetFolder) {
23
+ throw new CliError("INVALID_ARGS", '用法: feishu-docs cp <url|token> <target_folder_token> [--name "副本名称"]');
24
+ }
25
+ validateToken(targetFolder, "target_folder_token");
26
+ return withScopeRecovery(async () => {
27
+ const { authInfo } = await createClient(globalOpts);
28
+ const doc = await resolveDocument(authInfo, input);
29
+ const fileToken = doc.objToken;
30
+ const type = doc.objType;
31
+ // Determine copy name: use --name if provided, otherwise fetch original title
32
+ let copyName = args.name;
33
+ if (!copyName) {
34
+ let title = doc.title;
35
+ if (!title) {
36
+ // Fetch title via document API for non-wiki documents
37
+ try {
38
+ const docRes = await fetchWithAuth(authInfo, `/open-apis/docx/v1/documents/${encodeURIComponent(fileToken)}`);
39
+ title = docRes?.data?.document
40
+ ? docRes.data.document
41
+ .title
42
+ : undefined;
43
+ }
44
+ catch {
45
+ // Non-critical: fall back to token-based name
46
+ }
47
+ }
48
+ copyName = title ? `${title} - 副本` : `${fileToken} - 副本`;
49
+ }
50
+ const res = await fetchWithAuth(authInfo, `/open-apis/drive/v1/files/${encodeURIComponent(fileToken)}/copy`, {
51
+ method: "POST",
52
+ body: { type, name: copyName, folder_token: targetFolder },
53
+ });
54
+ const resData = res?.data;
55
+ const newFile = resData?.file;
56
+ const newToken = newFile?.token || "";
57
+ if (globalOpts.json) {
58
+ process.stdout.write(JSON.stringify({
59
+ success: true,
60
+ file_token: newToken,
61
+ name: copyName,
62
+ folder_token: targetFolder,
63
+ }) + "\n");
64
+ }
65
+ else {
66
+ process.stdout.write(`已复制为 "${copyName}" (${newToken}) 到文件夹 ${targetFolder}\n`);
67
+ }
68
+ }, globalOpts);
69
+ }
70
+ //# sourceMappingURL=cp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cp.js","sourceRoot":"","sources":["../../src/commands/cp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * create command: Create new documents in wiki or drive.
3
+ */
4
+ import { CommandMeta, CommandArgs, GlobalOpts } from "../types/index.js";
5
+ export declare const meta: CommandMeta;
6
+ export declare function create(args: CommandArgs, globalOpts: GlobalOpts): Promise<void>;
@@ -0,0 +1,120 @@
1
+ /**
2
+ * create command: Create new documents in wiki or drive.
3
+ */
4
+ import { createClient, fetchWithAuth } from "../client.js";
5
+ import { CliError } from "../utils/errors.js";
6
+ import { convertAndWrite } from "../services/markdown-convert.js";
7
+ import { readBody, getDocumentInfo } from "../services/block-writer.js";
8
+ import { validateToken } from "../utils/validate.js";
9
+ export const meta = {
10
+ options: {
11
+ wiki: { type: "string" },
12
+ folder: { type: "string" },
13
+ parent: { type: "string" },
14
+ body: { type: "string" },
15
+ },
16
+ positionals: true,
17
+ handler: create,
18
+ };
19
+ export async function create(args, globalOpts) {
20
+ const title = args.positionals[0];
21
+ if (!title) {
22
+ throw new CliError("INVALID_ARGS", "缺少文档标题。用法: feishu-docs create <title> [--wiki <space_id>] [--body <file>]");
23
+ }
24
+ const { authInfo } = await createClient(globalOpts);
25
+ let bodyContent;
26
+ if (args.body) {
27
+ bodyContent = await readBody(args.body);
28
+ if (!bodyContent.trim()) {
29
+ throw new CliError("INVALID_ARGS", "文档内容为空,至少需要一行内容");
30
+ }
31
+ }
32
+ if (args.wiki) {
33
+ validateToken(args.wiki, "space_id");
34
+ if (args.parent)
35
+ validateToken(args.parent, "parent_node_token");
36
+ return createInWiki(authInfo, title, args.wiki, args.parent, bodyContent, globalOpts);
37
+ }
38
+ if (args.folder) {
39
+ validateToken(args.folder, "folder_token");
40
+ }
41
+ return createDoc(authInfo, title, args.folder, bodyContent, globalOpts);
42
+ }
43
+ async function createInWiki(authInfo, title, spaceId, parentNodeToken, bodyContent, globalOpts) {
44
+ const nodeRes = await fetchWithAuth(authInfo, `/open-apis/wiki/v2/spaces/${encodeURIComponent(spaceId)}/nodes`, {
45
+ method: "POST",
46
+ body: {
47
+ obj_type: "docx",
48
+ node_type: "origin",
49
+ title,
50
+ ...(parentNodeToken && { parent_node_token: parentNodeToken }),
51
+ },
52
+ });
53
+ const nodeData = nodeRes?.data;
54
+ const node = (nodeData?.node || {});
55
+ const objToken = node.obj_token;
56
+ const nodeToken = node.node_token;
57
+ if (!objToken) {
58
+ throw new CliError("API_ERROR", "创建知识库节点成功但未返回 obj_token");
59
+ }
60
+ if (bodyContent) {
61
+ const docInfo = await getDocumentInfo(authInfo, objToken);
62
+ await convertAndWrite(authInfo, objToken, bodyContent, docInfo.revisionId);
63
+ }
64
+ const domain = globalOpts.lark ? "larksuite.com" : "feishu.cn";
65
+ const wikiUrl = `https://${domain}/wiki/${nodeToken}`;
66
+ const docUrl = `https://${domain}/docx/${objToken}`;
67
+ const output = {
68
+ document_id: objToken,
69
+ ...(nodeToken && { node_token: nodeToken }),
70
+ space_id: spaceId,
71
+ title,
72
+ wiki_url: wikiUrl,
73
+ doc_url: docUrl,
74
+ };
75
+ if (globalOpts.json) {
76
+ process.stdout.write(JSON.stringify({ success: true, ...output }, null, 2) + "\n");
77
+ }
78
+ else {
79
+ process.stdout.write(`文档已创建\n`);
80
+ process.stdout.write(` 标题: ${title}\n`);
81
+ process.stdout.write(` document_id: ${objToken}\n`);
82
+ if (nodeToken) {
83
+ process.stdout.write(` node_token: ${nodeToken}\n`);
84
+ }
85
+ process.stdout.write(` URL: ${wikiUrl}\n`);
86
+ }
87
+ }
88
+ async function createDoc(authInfo, title, folderToken, bodyContent, globalOpts) {
89
+ const body = {
90
+ title,
91
+ ...(folderToken && { folder_token: folderToken }),
92
+ };
93
+ const res = await fetchWithAuth(authInfo, `/open-apis/docx/v1/documents`, {
94
+ method: "POST",
95
+ body,
96
+ });
97
+ const resData = res?.data;
98
+ const doc = (resData?.document || {});
99
+ const documentId = doc.document_id;
100
+ if (!documentId) {
101
+ throw new CliError("API_ERROR", "创建文档成功但未返回 document_id");
102
+ }
103
+ if (bodyContent) {
104
+ const docInfo = await getDocumentInfo(authInfo, documentId);
105
+ await convertAndWrite(authInfo, documentId, bodyContent, docInfo.revisionId);
106
+ }
107
+ const domain = globalOpts.lark ? "larksuite.com" : "feishu.cn";
108
+ const url = `https://${domain}/docx/${documentId}`;
109
+ const output = { document_id: documentId, title: doc.title, url };
110
+ if (globalOpts.json) {
111
+ process.stdout.write(JSON.stringify({ success: true, ...output }, null, 2) + "\n");
112
+ }
113
+ else {
114
+ process.stdout.write(`文档已创建\n`);
115
+ process.stdout.write(` 标题: ${doc.title}\n`);
116
+ process.stdout.write(` document_id: ${documentId}\n`);
117
+ process.stdout.write(` URL: ${url}\n`);
118
+ }
119
+ }
120
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * delete command: Move document to recycle bin.
3
+ */
4
+ import { CommandMeta, CommandArgs, GlobalOpts } from "../types/index.js";
5
+ export declare const meta: CommandMeta;
6
+ export declare function del(args: CommandArgs, globalOpts: GlobalOpts): Promise<void>;
@@ -0,0 +1,91 @@
1
+ /**
2
+ * delete command: Move document to recycle bin.
3
+ */
4
+ import { createClient, fetchWithAuth } from "../client.js";
5
+ import { CliError } from "../utils/errors.js";
6
+ import { withScopeRecovery } from "../utils/scope-prompt.js";
7
+ import { resolveDocument } from "../utils/document-resolver.js";
8
+ import { mapToDriveType } from "../utils/drive-types.js";
9
+ /**
10
+ * Check if a node has children in the knowledge base.
11
+ */
12
+ async function checkChildren(authInfo, spaceId, nodeToken) {
13
+ try {
14
+ const res = await fetchWithAuth(authInfo, `/open-apis/wiki/v2/spaces/${encodeURIComponent(spaceId)}/nodes`, { params: { parent_node_token: nodeToken, page_size: 1 } });
15
+ const data = res?.data;
16
+ return (data?.items?.length || 0) > 0;
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
22
+ export const meta = {
23
+ options: {
24
+ confirm: { type: "boolean", default: false },
25
+ recursive: { type: "boolean", default: false },
26
+ },
27
+ positionals: true,
28
+ handler: del,
29
+ };
30
+ export async function del(args, globalOpts) {
31
+ const input = args.positionals[0];
32
+ if (!input) {
33
+ throw new CliError("INVALID_ARGS", "缺少文档 URL 或 token。用法: feishu-docs delete <url|token>");
34
+ }
35
+ return withScopeRecovery(async () => {
36
+ const { authInfo } = await createClient(globalOpts);
37
+ const doc = await resolveDocument(authInfo, input);
38
+ if (doc.objType === "doc") {
39
+ throw new CliError("NOT_SUPPORTED", "旧版 doc 类型不支持此操作,请在飞书客户端中将文档升级为 docx 格式");
40
+ }
41
+ // Check for children — refuse unless --recursive
42
+ if (doc.hasChild && doc.spaceId && doc.nodeToken) {
43
+ const hasChildren = await checkChildren(authInfo, doc.spaceId, doc.nodeToken);
44
+ if (hasChildren && !args.recursive) {
45
+ throw new CliError("INVALID_ARGS", "该节点下有子文档,删除将同时删除所有子节点。如需继续,请添加 --recursive 参数");
46
+ }
47
+ }
48
+ // Confirmation prompt (unless --confirm)
49
+ if (!args.confirm) {
50
+ const titleStr = doc.title || doc.objToken;
51
+ process.stderr.write(`\n即将删除文档:\n`);
52
+ process.stderr.write(` 标题: ${titleStr}\n`);
53
+ process.stderr.write(` 类型: ${doc.objType}\n`);
54
+ process.stderr.write(` token: ${doc.objToken}\n`);
55
+ if (doc.spaceId) {
56
+ process.stderr.write(` 知识库: ${doc.spaceId}\n`);
57
+ }
58
+ process.stderr.write(`\n 文档将移入回收站,30 天后永久删除。\n`);
59
+ process.stderr.write(` 如需跳过此确认,请添加 --confirm 参数。\n\n`);
60
+ // In non-interactive mode (Agent), just output the prompt and exit
61
+ // Agent should use --confirm
62
+ throw new CliError("INVALID_ARGS", "操作已取消。Agent 调用请添加 --confirm 参数");
63
+ }
64
+ // Wiki documents cannot be deleted via Open API
65
+ if (doc.spaceId) {
66
+ throw new CliError("NOT_SUPPORTED", `知识库文档不支持通过 API 删除。飞书开放平台未提供删除知识库节点的 API。\n` +
67
+ ` 请在飞书客户端中手动删除: ${doc.title || doc.objToken}\n` +
68
+ ` 知识库: ${doc.spaceId}, 节点: ${doc.nodeToken}`);
69
+ }
70
+ // Map doc type to drive file type (personal space files only)
71
+ const driveType = mapToDriveType(doc.objType);
72
+ // Execute delete
73
+ await fetchWithAuth(authInfo, `/open-apis/drive/v1/files/${encodeURIComponent(doc.objToken)}`, {
74
+ method: "DELETE",
75
+ params: { type: driveType },
76
+ });
77
+ if (globalOpts.json) {
78
+ process.stdout.write(JSON.stringify({
79
+ success: true,
80
+ deleted: doc.objToken,
81
+ title: doc.title,
82
+ type: doc.objType,
83
+ }) + "\n");
84
+ }
85
+ else {
86
+ const titleStr = doc.title || doc.objToken;
87
+ process.stdout.write(`已将 "${titleStr}" 移入回收站\n`);
88
+ }
89
+ }, globalOpts);
90
+ }
91
+ //# sourceMappingURL=delete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * info command: Display document metadata.
3
+ */
4
+ import { CommandMeta, CommandArgs, GlobalOpts } from "../types/index.js";
5
+ export declare const meta: CommandMeta;
6
+ export declare function info(args: CommandArgs, globalOpts: GlobalOpts): Promise<void>;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * info command: Display document metadata.
3
+ */
4
+ import { createClient } from "../client.js";
5
+ import { CliError } from "../utils/errors.js";
6
+ import { resolveDocument } from "../utils/document-resolver.js";
7
+ import { getDocumentInfo } from "../services/block-writer.js";
8
+ export const meta = {
9
+ options: {},
10
+ positionals: true,
11
+ handler: info,
12
+ };
13
+ export async function info(args, globalOpts) {
14
+ const input = args.positionals[0];
15
+ if (!input) {
16
+ throw new CliError("INVALID_ARGS", "缺少文档 URL 或 token。用法: feishu-docs info <url|token>");
17
+ }
18
+ const { authInfo } = await createClient(globalOpts);
19
+ const doc = await resolveDocument(authInfo, input);
20
+ if (doc.objType === "doc") {
21
+ throw new CliError("NOT_SUPPORTED", "旧版 doc 类型不支持此操作,请在飞书客户端中将文档升级为 docx 格式");
22
+ }
23
+ // Fetch additional document info for docx type
24
+ let revisionId;
25
+ let docTitle = doc.title;
26
+ if (doc.objType === "docx") {
27
+ try {
28
+ const docInfo = await getDocumentInfo(authInfo, doc.objToken);
29
+ docTitle = docTitle || docInfo.title;
30
+ revisionId = docInfo.revisionId;
31
+ }
32
+ catch (err) {
33
+ process.stderr.write(`feishu-docs: warning: 获取文档详情失败: ${err.message}\n`);
34
+ }
35
+ }
36
+ const domain = globalOpts.lark ? "larksuite.com" : "feishu.cn";
37
+ const url = doc.spaceId
38
+ ? `https://${domain}/wiki/${doc.parsed.token}`
39
+ : `https://${domain}/${doc.objType}/${doc.objToken}`;
40
+ const output = {
41
+ title: docTitle,
42
+ type: doc.objType,
43
+ token: doc.objToken,
44
+ url,
45
+ ...(doc.nodeToken && { node_token: doc.nodeToken }),
46
+ ...(doc.spaceId && { space_id: doc.spaceId }),
47
+ ...(revisionId !== undefined && { revision: revisionId }),
48
+ };
49
+ if (globalOpts.json) {
50
+ process.stdout.write(JSON.stringify({ success: true, ...output }, null, 2) + "\n");
51
+ }
52
+ else {
53
+ if (docTitle)
54
+ process.stdout.write(`标题: ${docTitle}\n`);
55
+ process.stdout.write(`类型: ${doc.objType}\n`);
56
+ process.stdout.write(`URL: ${url}\n`);
57
+ process.stdout.write(`token: ${doc.objToken}\n`);
58
+ if (doc.spaceId) {
59
+ process.stdout.write(`知识库: ${doc.spaceId}\n`);
60
+ }
61
+ if (doc.nodeToken) {
62
+ process.stdout.write(`node_token: ${doc.nodeToken}\n`);
63
+ }
64
+ if (revisionId !== undefined) {
65
+ process.stdout.write(`版本: ${revisionId}\n`);
66
+ }
67
+ }
68
+ }
69
+ //# sourceMappingURL=info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"info.js","sourceRoot":"","sources":["../../src/commands/info.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * install-skill command: Install the feishu-docs skill to Claude Code's commands directory.
3
+ */
4
+ import { CommandMeta } from "../types/index.js";
5
+ export declare const meta: CommandMeta;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * install-skill command: Install the feishu-docs skill to Claude Code's commands directory.
3
+ */
4
+ import { readFileSync, mkdirSync, writeFileSync, existsSync } from "node:fs";
5
+ import { resolve, dirname } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import { homedir } from "node:os";
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ async function handler() {
10
+ // Resolve SKILL.md from the package's skills/feishu-docs/ directory
11
+ const skillSrc = resolve(__dirname, "../../skills/feishu-docs/SKILL.md");
12
+ if (!existsSync(skillSrc)) {
13
+ process.stderr.write("feishu-docs: error: SKILL.md not found in package\n");
14
+ process.exit(1);
15
+ }
16
+ const targetDir = resolve(homedir(), ".claude", "commands");
17
+ mkdirSync(targetDir, { recursive: true });
18
+ const targetPath = resolve(targetDir, "feishu-docs.md");
19
+ const content = readFileSync(skillSrc, "utf-8");
20
+ writeFileSync(targetPath, content, "utf-8");
21
+ process.stdout.write(`Skill installed to ${targetPath}\n`);
22
+ process.stdout.write("You can now use /feishu-docs in Claude Code to access Feishu document operations.\n");
23
+ }
24
+ export const meta = {
25
+ handler,
26
+ options: {},
27
+ };
28
+ //# sourceMappingURL=install-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-skill.js","sourceRoot":"","sources":["../../src/commands/install-skill.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGlC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,KAAK,UAAU,OAAO;IACpB,oEAAoE;IACpE,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,mCAAmC,CAAC,CAAC;IACzE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAC5D,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAChD,aAAa,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAE5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,UAAU,IAAI,CAAC,CAAC;IAC3D,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qFAAqF,CACtF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,IAAI,GAAgB;IAC/B,OAAO;IACP,OAAO,EAAE,EAAE;CACZ,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * login / logout / whoami commands.
3
+ */
4
+ import { CommandMeta, CommandArgs, GlobalOpts } from "../types/index.js";
5
+ export declare const loginMeta: CommandMeta;
6
+ export declare const logoutMeta: CommandMeta;
7
+ export declare const whoamiMeta: CommandMeta;
8
+ export declare function login(args: CommandArgs, globalOpts: GlobalOpts): Promise<void>;
9
+ export declare function logout(_args: CommandArgs, globalOpts: GlobalOpts): Promise<void>;
10
+ export declare function whoami(_args: CommandArgs, globalOpts: GlobalOpts): Promise<void>;