@lark-project/openclaw-lark-project 2026.3.172 → 2026.3.174
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/src/tools/mcp/project/tools.js +33 -4
- package/dist/src/tools/mcp/project/tools.js.map +2 -2
- package/dist/src/tools/oauth-cards.js +14 -2
- package/dist/src/tools/oauth-cards.js.map +2 -2
- package/dist/src/tools/project-oauth.js +87 -7
- package/dist/src/tools/project-oauth.js.map +2 -2
- package/package.json +1 -1
- package/skills/feishu-project/SKILL.md +121 -42
- package/skills/feishu-project/references/moql-syntax.md +187 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Type } from "@sinclair/typebox";
|
|
2
2
|
import { isRecord, unwrapJsonRpcResult } from "../shared.js";
|
|
3
3
|
import { createToolContext, formatToolResult } from "../../helpers.js";
|
|
4
|
-
import { getProjectStoredToken, projectTokenStatus, getProjectClientId } from "../../../core/project-token-store.js";
|
|
4
|
+
import { getProjectStoredToken, setProjectStoredToken, projectTokenStatus, getProjectClientId } from "../../../core/project-token-store.js";
|
|
5
|
+
import { refreshProjectToken } from "../../../core/project-auth.js";
|
|
5
6
|
import { getTicket } from "../../../core/lark-ticket.js";
|
|
6
7
|
import { larkLogger } from "../../../core/lark-logger.js";
|
|
7
8
|
const log = larkLogger("tools/mcp/project");
|
|
@@ -61,13 +62,41 @@ function registerProjectMcpTool(api, config) {
|
|
|
61
62
|
message: "\u98DE\u4E66\u9879\u76EE\u672A\u6388\u6743\u3002\u8BF7\u5148\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\u5B8C\u6210\u6388\u6743\u3002"
|
|
62
63
|
});
|
|
63
64
|
}
|
|
64
|
-
|
|
65
|
-
if (!token
|
|
65
|
+
let token = await getProjectStoredToken(clientId, senderOpenId);
|
|
66
|
+
if (!token) {
|
|
66
67
|
return formatToolResult({
|
|
67
68
|
error: "project_auth_required",
|
|
68
|
-
message: "\u98DE\u4E66\u9879\u76EE\u672A\u6388\u6743\
|
|
69
|
+
message: "\u98DE\u4E66\u9879\u76EE\u672A\u6388\u6743\u3002\u8BF7\u5148\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\u5B8C\u6210\u6388\u6743\u3002"
|
|
69
70
|
});
|
|
70
71
|
}
|
|
72
|
+
const status = projectTokenStatus(token);
|
|
73
|
+
if (status === "expired") {
|
|
74
|
+
return formatToolResult({
|
|
75
|
+
error: "project_auth_required",
|
|
76
|
+
message: "\u98DE\u4E66\u9879\u76EE\u6388\u6743\u5DF2\u8FC7\u671F\u3002\u8BF7\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\u7684 authorize \u64CD\u4F5C\u91CD\u65B0\u6388\u6743\u3002"
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (status === "needs_refresh") {
|
|
80
|
+
try {
|
|
81
|
+
const resolvedEp = typeof config.endpoint === "function" ? config.endpoint() : config.endpoint;
|
|
82
|
+
const refreshed = await refreshProjectToken(resolvedEp, token.refreshToken, clientId);
|
|
83
|
+
token = {
|
|
84
|
+
...token,
|
|
85
|
+
accessToken: refreshed.access_token,
|
|
86
|
+
refreshToken: refreshed.refresh_token ?? token.refreshToken,
|
|
87
|
+
expiresAt: Date.now() + (refreshed.expires_in ?? 7200) * 1e3,
|
|
88
|
+
scope: refreshed.scope ?? token.scope
|
|
89
|
+
};
|
|
90
|
+
await setProjectStoredToken(token);
|
|
91
|
+
toolLog.debug?.("project token refreshed");
|
|
92
|
+
} catch (refreshErr) {
|
|
93
|
+
toolLog.error(`project token refresh failed: ${refreshErr}`);
|
|
94
|
+
return formatToolResult({
|
|
95
|
+
error: "project_auth_required",
|
|
96
|
+
message: "\u98DE\u4E66\u9879\u76EE token \u5237\u65B0\u5931\u8D25\uFF0C\u8BF7\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\u7684 authorize \u64CD\u4F5C\u91CD\u65B0\u6388\u6743\u3002"
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
71
100
|
const resolvedEndpoint = typeof config.endpoint === "function" ? config.endpoint() : config.endpoint;
|
|
72
101
|
const result = await callProjectMcpTool(
|
|
73
102
|
config.mcpToolName,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/tools/mcp/project/tools.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * \u98DE\u4E66\u9879\u76EE MCP \u5DE5\u5177\u6CE8\u518C\n *\n * \u6BCF\u4E2A\u5DE5\u5177\u4F7F\u7528\u98DE\u4E66\u9879\u76EE\u4E13\u5C5E\u7684 MCP \u7AEF\u70B9\u548C\u72EC\u7ACB\u7684 OAuth token\u3002\n * \u4E0D\u901A\u8FC7 registerMcpTool\uFF08\u4F7F\u7528\u98DE\u4E66 Open API UAT\uFF09\uFF0C\u800C\u662F\u4F7F\u7528\n * registerProjectMcpTool \u5305\u88C5\u51FD\u6570\u3002\n *\n * \u5DE5\u5177\u53C2\u6570\u7B7E\u540D\u53C2\u7167\u98DE\u4E66\u9879\u76EE MCP Server \u7684\u5B9E\u9645\u5B9A\u4E49\u3002\n */\n\nimport type { OpenClawPluginApi } from 'openclaw/plugin-sdk';\nimport type { TSchema } from '@sinclair/typebox';\nimport { Type } from '@sinclair/typebox';\nimport type { McpRpcResponse } from '../shared';\nimport { isRecord, unwrapJsonRpcResult } from '../shared';\nimport { createToolContext, formatToolResult } from '../../helpers';\nimport { getProjectStoredToken, projectTokenStatus, getProjectClientId } from '../../../core/project-token-store';\nimport { getTicket } from '../../../core/lark-ticket';\nimport { larkLogger } from '../../../core/lark-logger';\n\nconst log = larkLogger('tools/mcp/project');\n\n// ---------------------------------------------------------------------------\n// \u98DE\u4E66\u9879\u76EE MCP \u4E13\u7528 JSON-RPC \u5BA2\u6237\u7AEF\uFF08\u4F7F\u7528\u6807\u51C6 OAuth Bearer \u8BA4\u8BC1\uFF09\n// ---------------------------------------------------------------------------\n\nasync function callProjectMcpTool(\n name: string,\n args: Record<string, unknown>,\n toolCallId: string,\n accessToken: string,\n endpoint: string,\n): Promise<unknown> {\n const body = {\n jsonrpc: '2.0',\n id: toolCallId,\n method: 'tools/call',\n params: { name, arguments: args },\n };\n\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n },\n body: JSON.stringify(body),\n });\n\n const text = await res.text();\n if (!res.ok) {\n throw new Error(`MCP HTTP ${res.status} ${res.statusText}: ${text.slice(0, 4000)}`);\n }\n\n let data: McpRpcResponse;\n try {\n data = JSON.parse(text) as McpRpcResponse;\n } catch {\n throw new Error(`MCP \u8FD4\u56DE\u975E JSON\uFF1A${text.slice(0, 4000)}`);\n }\n\n if ('error' in data) {\n throw new Error(`MCP error ${data.error.code}: ${data.error.message}`);\n }\n\n return unwrapJsonRpcResult(data.result);\n}\n\n// ---------------------------------------------------------------------------\n// \u98DE\u4E66\u9879\u76EE MCP \u5DE5\u5177\u901A\u7528\u6CE8\u518C\u51FD\u6570\n// ---------------------------------------------------------------------------\n\ninterface ProjectMcpToolConfig {\n name: string;\n mcpToolName: string;\n label: string;\n description: string;\n schema: TSchema;\n endpoint: string | (() => string);\n}\n\nexport function registerProjectMcpTool(\n api: OpenClawPluginApi,\n config: ProjectMcpToolConfig,\n): void {\n const { log: toolLog } = createToolContext(api, config.name);\n\n api.registerTool(\n {\n name: config.name,\n label: config.label,\n description: config.description,\n parameters: config.schema,\n async execute(toolCallId, params) {\n const p = params as Record<string, unknown>;\n try {\n const startTime = Date.now();\n\n const ticket = getTicket();\n const senderOpenId = ticket?.senderOpenId;\n if (!senderOpenId) {\n return formatToolResult({\n error: '\u65E0\u6CD5\u83B7\u53D6\u5F53\u524D\u7528\u6237\u8EAB\u4EFD\uFF0C\u8BF7\u5728\u98DE\u4E66\u5BF9\u8BDD\u4E2D\u4F7F\u7528\u6B64\u5DE5\u5177\u3002',\n });\n }\n\n const clientId = await getProjectClientId(senderOpenId);\n if (!clientId) {\n return formatToolResult({\n error: 'project_auth_required',\n message: '\u98DE\u4E66\u9879\u76EE\u672A\u6388\u6743\u3002\u8BF7\u5148\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\u5B8C\u6210\u6388\u6743\u3002',\n });\n }\n\n const token = await getProjectStoredToken(clientId, senderOpenId);\n if (!token || projectTokenStatus(token) === 'expired') {\n return formatToolResult({\n error: 'project_auth_required',\n message: '\u98DE\u4E66\u9879\u76EE\u672A\u6388\u6743\u6216\u6388\u6743\u5DF2\u8FC7\u671F\u3002\u8BF7\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\u7684 authorize \u64CD\u4F5C\u5B8C\u6210\u6388\u6743\u3002',\n });\n }\n\n const resolvedEndpoint = typeof config.endpoint === 'function' ? config.endpoint() : config.endpoint;\n\n const result = await callProjectMcpTool(\n config.mcpToolName,\n p,\n toolCallId,\n token.accessToken,\n resolvedEndpoint,\n );\n\n const duration = Date.now() - startTime;\n toolLog.debug?.(`${config.mcpToolName} succeeded in ${duration}ms`);\n\n // MCP \u8FD4\u56DE\u503C\u5904\u7406\uFF08\u540C registerMcpTool \u903B\u8F91\uFF09\n if (isRecord(result) && Array.isArray((result as Record<string, unknown>).content)) {\n const mcpContent = (result as Record<string, unknown>).content as Array<{\n type: string;\n text: string;\n }>;\n let details: unknown = result;\n if (mcpContent.length === 1 && mcpContent[0]?.type === 'text') {\n try {\n details = JSON.parse(mcpContent[0].text);\n } catch {\n // text is not JSON\n }\n }\n return {\n content: mcpContent.map((c) => ({\n type: 'text' as const,\n text: c.text,\n })),\n details,\n };\n }\n return formatToolResult(result);\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n toolLog.error(`${config.mcpToolName} failed: ${errMsg}`);\n return formatToolResult({\n error: errMsg,\n hint: '\u5982\u679C\u662F\u6388\u6743\u95EE\u9898\uFF0C\u8BF7\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\u91CD\u65B0\u6388\u6743\u3002',\n });\n }\n },\n },\n { name: config.name },\n );\n}\n\n// ---------------------------------------------------------------------------\n// \u5177\u4F53\u5DE5\u5177\u6CE8\u518C\uFF08\u53C2\u6570\u7B7E\u540D\u5339\u914D\u98DE\u4E66\u9879\u76EE MCP Server \u5B9E\u9645\u5B9A\u4E49\uFF09\n// ---------------------------------------------------------------------------\n\nexport function registerProjectTools(api: OpenClawPluginApi, endpoint: string | (() => string)) {\n let count = 0;\n\n // list_todo \u2014 \u5F85\u529E/\u5DF2\u529E/\u8D85\u671F/\u672C\u5468\u5230\u671F\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_todo',\n mcpToolName: 'list_todo',\n label: 'Feishu Project: \u5F85\u529E\u5217\u8868',\n description:\n '\u83B7\u53D6\u5F53\u524D\u7528\u6237\u7684\u98DE\u4E66\u9879\u76EE\u5DE5\u4F5C\u9879\u5217\u8868\u3002\u652F\u6301\u67E5\u8BE2\u7C7B\u578B\uFF1A' +\n 'todo(\u5F85\u529E)\u3001done(\u5DF2\u529E)\u3001overdue(\u5DF2\u8D85\u671F)\u3001this_week(\u672C\u5468\u5230\u671F)\u3002',\n schema: Type.Object({\n action: Type.String({\n description: '\u67E5\u8BE2\u7C7B\u578B\u3002todo \u4E3A\u5F85\u529E, done \u4E3A\u5DF2\u529E, overdue \u4E3A\u5DF2\u8D85\u671F, this_week \u4E3A\u672C\u5468\u5230\u671F',\n }),\n asset_key: Type.Optional(\n Type.String({ description: '\u5DE5\u4F5C\u533A key\uFF0C\u683C\u5F0F\u4E3A Asset_\uFF0C\u4EC5\u5728\u63A5\u53E3\u62A5\u9519\u9700\u8981\u9009\u62E9\u65F6\u4F20\u9012' }),\n ),\n page_num: Type.Optional(\n Type.Number({ description: '\u9875\u7801\uFF0C\u4ECE 1 \u5F00\u59CB\u9012\u589E\uFF0C\u6BCF\u9875 50 \u6761' }),\n ),\n }),\n endpoint,\n });\n count++;\n\n // search_by_mql \u2014 MQL \u67E5\u8BE2\n registerProjectMcpTool(api, {\n name: 'feishu_project_search_by_mql',\n mcpToolName: 'search_by_mql',\n label: 'Feishu Project: MQL \u641C\u7D22',\n description:\n '\u4F7F\u7528 MQL \u641C\u7D22\u98DE\u4E66\u9879\u76EE\u5DE5\u4F5C\u9879\u3002MQL \u57FA\u4E8E SQL \u8BED\u6CD5\u6269\u5C55\u3002' +\n '\u4F7F\u7528\u524D\u9700\u5148\u7528 get_workitem_info \u786E\u8BA4\u7A7A\u95F4\u548C\u5DE5\u4F5C\u9879\u7C7B\u578B\u3002' +\n 'select \u540E\u4F7F\u7528\u53EF\u8BFB\u6027\u5F3A\u7684\u5B57\u6BB5\u540D\u79F0\uFF08\u5982\"\u4EFB\u52A1\u540D\u79F0\"\u800C\u975E\"name\"\uFF09\u3002',\n schema: Type.Object({\n project_key: Type.String({\n description: '\u7A7A\u95F4 projectKey\u3001simpleName \u6216\u7A7A\u95F4\u540D',\n }),\n mql: Type.Optional(\n Type.String({\n description:\n 'MQL \u8BED\u53E5\u3002\u8BED\u6CD5\uFF1Aselect `\u5B57\u6BB5\u540D` from `\u7A7A\u95F4\u540D`.`\u5DE5\u4F5C\u9879\u540D` where `\u5B57\u6BB5\u540D` = \\'\u5B57\u6BB5\u503C\\'',\n }),\n ),\n helper: Type.Optional(\n Type.String({\n description: '\u5E2E\u52A9\u5DE5\u5177\u3002\u8F93\u5165 \"helper\" \u83B7\u53D6\u6240\u6709\u547D\u4EE4\u548C\u7528\u6CD5\u793A\u4F8B',\n }),\n ),\n session_id: Type.Optional(\n Type.String({ description: 'sessionID\uFF0C\u7528\u4E8E\u5206\u9875\u67E5\u8BE2\uFF0C\u4F20\u5165\u540E\u4E0D\u89E3\u6790 mql' }),\n ),\n group_pagination_list: Type.Optional(\n Type.Array(\n Type.Object({\n group_id: Type.Optional(Type.String({ description: '\u5206\u7EC4 ID' })),\n page_num: Type.Optional(Type.Number({ description: '\u9875\u7801\uFF0C\u4ECE 1 \u5F00\u59CB' })),\n }),\n ),\n ),\n }),\n endpoint,\n });\n count++;\n\n // get_workitem_info \u2014 \u83B7\u53D6\u5DE5\u4F5C\u9879\u7C7B\u578B\u7684\u5B57\u6BB5\u4E0E\u89D2\u8272\u4FE1\u606F\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_workitem_info',\n mcpToolName: 'get_workitem_info',\n label: 'Feishu Project: \u5DE5\u4F5C\u9879\u7C7B\u578B\u4FE1\u606F',\n description: '\u83B7\u53D6\u4E00\u4E2A\u5DE5\u4F5C\u9879\u7C7B\u578B\u5177\u5907\u7684\u53EF\u7528\u5B57\u6BB5\u4E0E\u89D2\u8272\u4FE1\u606F\u3002',\n schema: Type.Object({\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n ),\n work_item_type: Type.String({\n description: '\u5DE5\u4F5C\u9879\u7C7B\u578B\u7684\u7CFB\u7EDF\u6807\u8BC6\u6216\u540D\u79F0\uFF0C\u5982 story\u3001\u9700\u6C42\u3001issue\u3001\u7F3A\u9677\u7B49',\n }),\n }),\n endpoint,\n });\n count++;\n\n // get_workitem_brief \u2014 \u83B7\u53D6\u5DE5\u4F5C\u9879\u6982\u51B5\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_workitem_brief',\n mcpToolName: 'get_workitem_brief',\n label: 'Feishu Project: \u5DE5\u4F5C\u9879\u6982\u51B5',\n description: '\u83B7\u53D6\u4E00\u4E2A\u5DE5\u4F5C\u9879\u5B9E\u4F8B\u7684\u6982\u51B5\u4FE1\u606F\u3002',\n schema: Type.Object({\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey \u6216 simpleName' }),\n ),\n work_item_id: Type.String({\n description: '\u5DE5\u4F5C\u9879 ID \u6216\u540D\u79F0',\n }),\n fields: Type.Optional(\n Type.Array(Type.String({ description: '\u8981\u67E5\u8BE2\u7684 field_key \u6216 field_name' })),\n ),\n }),\n endpoint,\n });\n count++;\n\n // get_workitem_field_meta \u2014 \u83B7\u53D6\u521B\u5EFA\u5DE5\u4F5C\u9879\u5143\u4FE1\u606F\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_workitem_field_meta',\n mcpToolName: 'get_workitem_field_meta',\n label: 'Feishu Project: \u5B57\u6BB5\u5143\u4FE1\u606F',\n description: '\u83B7\u53D6\u521B\u5EFA\u5DE5\u4F5C\u9879\u65F6\u7684\u5B57\u6BB5\u5143\u4FE1\u606F\uFF08\u5B57\u6BB5\u540D\u3001\u7C7B\u578B\u3001\u9009\u9879\u7B49\uFF09\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n work_item_type_key: Type.String({ description: '\u5DE5\u4F5C\u9879\u7C7B\u578B key' }),\n }),\n endpoint,\n });\n count++;\n\n // create_workitem \u2014 \u521B\u5EFA\u5DE5\u4F5C\u9879\n registerProjectMcpTool(api, {\n name: 'feishu_project_create_workitem',\n mcpToolName: 'create_workitem',\n label: 'Feishu Project: \u521B\u5EFA\u5DE5\u4F5C\u9879',\n description: '\u521B\u5EFA\u4E00\u6761\u5DE5\u4F5C\u9879\u5B9E\u4F8B\u3002\u521B\u5EFA\u6210\u529F\u540E\u83B7\u5F97\u8BE6\u60C5\u9875 URL\u3002',\n schema: Type.Object({\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey \u6216 simpleName' }),\n ),\n work_item_type: Type.String({\n description: '\u5DE5\u4F5C\u9879\u7C7B\u578B',\n }),\n fields: Type.Optional(\n Type.Array(\n Type.Object({\n field_key: Type.String({ description: '\u5B57\u6BB5 key' }),\n field_value: Type.String({\n description: '\u5B57\u6BB5\u503C\u3002\u65F6\u95F4\u7C7B\u9700\u4F20 16 \u4F4D unix \u6BEB\u79D2\u65F6\u95F4\u6233\uFF0C\u4EBA\u5458\u7C7B\u9700\u7528\u82F1\u6587\u9017\u53F7\u533A\u9694',\n }),\n }),\n ),\n ),\n }),\n endpoint,\n });\n count++;\n\n // update_field \u2014 \u4FEE\u6539\u5DE5\u4F5C\u9879\u5B57\u6BB5\n registerProjectMcpTool(api, {\n name: 'feishu_project_update_field',\n mcpToolName: 'update_field',\n label: 'Feishu Project: \u4FEE\u6539\u5B57\u6BB5',\n description: '\u4FEE\u6539\u6307\u5B9A\u5DE5\u4F5C\u9879\u5B9E\u4F8B\u7684\u5B57\u6BB5\u503C\uFF0C\u652F\u6301\u4E00\u6B21\u4FEE\u6539\u591A\u4E2A\u5B57\u6BB5\u3002',\n schema: Type.Object({\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n ),\n work_item_id: Type.String({\n description: '\u5DE5\u4F5C\u9879 ID \u6216\u540D\u79F0',\n }),\n fields: Type.Optional(\n Type.Array(\n Type.Object({\n field_key: Type.String({ description: '\u5B57\u6BB5 key' }),\n field_value: Type.String({\n description: '\u5B57\u6BB5\u503C\u3002\u65F6\u95F4\u7C7B\u9700\u4F20 16 \u4F4D unix \u6BEB\u79D2\u65F6\u95F4\u6233\uFF0C\u4EBA\u5458\u7C7B\u9700\u7528\u82F1\u6587\u9017\u53F7\u533A\u9694',\n }),\n }),\n ),\n ),\n }),\n endpoint,\n });\n count++;\n\n // add_comment \u2014 \u6DFB\u52A0\u8BC4\u8BBA\n registerProjectMcpTool(api, {\n name: 'feishu_project_add_comment',\n mcpToolName: 'add_comment',\n label: 'Feishu Project: \u6DFB\u52A0\u8BC4\u8BBA',\n description: '\u5728\u6307\u5B9A\u5DE5\u4F5C\u9879\u7684\u8BC4\u8BBA/\u5907\u6CE8\u9875\u6DFB\u52A0\u4E00\u6761\u8BC4\u8BBA\uFF0C\u652F\u6301 markdown \u683C\u5F0F\u3002',\n schema: Type.Object({\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n ),\n work_item_id: Type.String({\n description: '\u5DE5\u4F5C\u9879 ID \u6216\u540D\u79F0',\n }),\n work_item_type: Type.Optional(\n Type.String({ description: '\u5DE5\u4F5C\u9879\u7C7B\u578B' }),\n ),\n comment_content: Type.String({\n description: '\u8BC4\u8BBA\u5185\u5BB9\uFF0C\u652F\u6301 markdown \u683C\u5F0F',\n }),\n url: Type.Optional(\n Type.String({ description: '\u5DE5\u4F5C\u9879 URL\uFF0C\u53EF\u4ECE\u4E2D\u89E3\u6790 project_key \u7B49\u4FE1\u606F' }),\n ),\n }),\n endpoint,\n });\n count++;\n\n // finish_node \u2014 \u5B8C\u6210\u8282\u70B9/\u6D41\u8F6C\u72B6\u6001\n registerProjectMcpTool(api, {\n name: 'feishu_project_finish_node',\n mcpToolName: 'finish_node',\n label: 'Feishu Project: \u6D41\u8F6C\u72B6\u6001',\n description: '\u5B8C\u6210\u67D0\u4E2A\u8282\u70B9\uFF0C\u6D41\u8F6C\u5DE5\u4F5C\u9879\u5230\u4E0B\u4E00\u4E2A\u72B6\u6001\u3002',\n schema: Type.Object({\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n ),\n work_item_id: Type.String({\n description: '\u5DE5\u4F5C\u9879 ID \u6216\u540D\u79F0',\n }),\n node_id: Type.String({\n description: '\u8981\u5B8C\u6210\u6D41\u8F6C\u7684\u8282\u70B9 ID \u6216\u8282\u70B9\u540D\u79F0',\n }),\n }),\n endpoint,\n });\n count++;\n\n // get_node_detail \u2014 \u83B7\u53D6\u8282\u70B9\u8BE6\u60C5\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_node_detail',\n mcpToolName: 'get_node_detail',\n label: 'Feishu Project: \u8282\u70B9\u8BE6\u60C5',\n description: '\u83B7\u53D6\u6307\u5B9A\u8282\u70B9\u7684\u5173\u952E\u4FE1\u606F\uFF0C\u5305\u62EC\u8282\u70B9\u4FE1\u606F\u3001\u5B50\u9879\u4FE1\u606F\u3001\u81EA\u5B9A\u4E49\u5B57\u6BB5\u4FE1\u606F\u3002',\n schema: Type.Object({\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n ),\n work_item_id: Type.String({ description: '\u5DE5\u4F5C\u9879 ID' }),\n node_id: Type.String({ description: '\u8282\u70B9\u540D\u79F0\u6216\u8282\u70B9 ID' }),\n node_ids: Type.Optional(\n Type.Array(Type.String({ description: '\u8282\u70B9\u540D\u79F0\u6216\u8282\u70B9 ID \u5217\u8868' })),\n ),\n }),\n endpoint,\n });\n count++;\n\n // get_transitable_statuses \u2014 \u83B7\u53D6\u53EF\u6D41\u8F6C\u72B6\u6001\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_transitable_statuses',\n mcpToolName: 'get_transitable_statuses',\n label: 'Feishu Project: \u53EF\u6D41\u8F6C\u72B6\u6001',\n description: '\u83B7\u53D6\u72B6\u6001\u6D41\u5DE5\u4F5C\u9879\u7684\u53EF\u6D41\u8F6C\u72B6\u6001\u5217\u8868\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n work_item_id: Type.String({ description: '\u5DE5\u4F5C\u9879 ID' }),\n work_item_type_key: Type.String({ description: '\u5DE5\u4F5C\u9879\u7C7B\u578B key' }),\n user_key: Type.String({ description: '\u7528\u6237 userKey' }),\n }),\n endpoint,\n });\n count++;\n\n // list_workitem_types \u2014 \u83B7\u53D6\u5DE5\u4F5C\u9879\u7C7B\u578B\u5217\u8868\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_workitem_types',\n mcpToolName: 'list_workitem_types',\n label: 'Feishu Project: \u5DE5\u4F5C\u9879\u7C7B\u578B\u5217\u8868',\n description: '\u83B7\u53D6\u7A7A\u95F4\u4E0B\u7684\u6240\u6709\u5DE5\u4F5C\u9879\u7C7B\u578B\u5217\u8868\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n }),\n endpoint,\n });\n count++;\n\n // search_project_info \u2014 \u67E5\u8BE2\u7A7A\u95F4\u4FE1\u606F\n registerProjectMcpTool(api, {\n name: 'feishu_project_search_project_info',\n mcpToolName: 'search_project_info',\n label: 'Feishu Project: \u67E5\u8BE2\u7A7A\u95F4',\n description: '\u67E5\u8BE2\u98DE\u4E66\u9879\u76EE\u7A7A\u95F4\u57FA\u7840\u4FE1\u606F\u3002',\n schema: Type.Object({\n project_key: Type.String({\n description: '\u7A7A\u95F4 projectKey\u3001simpleName \u6216\u7A7A\u95F4\u540D\u79F0',\n }),\n }),\n endpoint,\n });\n count++;\n\n // search_user_info \u2014 \u67E5\u8BE2\u7528\u6237\u4FE1\u606F\n registerProjectMcpTool(api, {\n name: 'feishu_project_search_user_info',\n mcpToolName: 'search_user_info',\n label: 'Feishu Project: \u67E5\u8BE2\u7528\u6237',\n description: '\u6279\u91CF\u67E5\u8BE2\u7528\u6237\u57FA\u7840\u4FE1\u606F\uFF0C\u6700\u591A 20 \u4E2A\u3002',\n schema: Type.Object({\n user_keys: Type.Array(\n Type.String({ description: 'userKey\u3001Email \u6216\u540D\u5B57' }),\n ),\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n ),\n }),\n endpoint,\n });\n count++;\n\n // list_workitem_comments \u2014 \u67E5\u8BE2\u8BC4\u8BBA\u5217\u8868\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_workitem_comments',\n mcpToolName: 'list_workitem_comments',\n label: 'Feishu Project: \u8BC4\u8BBA\u5217\u8868',\n description: '\u67E5\u8BE2\u5DE5\u4F5C\u9879\u8BC4\u8BBA\u5217\u8868\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n work_item_id: Type.String({ description: '\u5DE5\u4F5C\u9879 ID \u6216\u540D\u79F0' }),\n page_num: Type.Optional(Type.Number({ description: '\u9875\u7801\uFF0C\u9ED8\u8BA4 1' })),\n start_time: Type.Optional(Type.Number({ description: '\u5F00\u59CB\u65F6\u95F4\uFF0CUnix \u6BEB\u79D2\u65F6\u95F4\u6233' })),\n end_time: Type.Optional(Type.Number({ description: '\u7ED3\u675F\u65F6\u95F4\uFF0CUnix \u6BEB\u79D2\u65F6\u95F4\u6233' })),\n }),\n endpoint,\n });\n count++;\n\n // search_view_by_title \u2014 \u641C\u7D22\u89C6\u56FE\n registerProjectMcpTool(api, {\n name: 'feishu_project_search_view_by_title',\n mcpToolName: 'search_view_by_title',\n label: 'Feishu Project: \u641C\u7D22\u89C6\u56FE',\n description: '\u901A\u8FC7\u89C6\u56FE\u540D\u79F0\u6A21\u7CCA\u67E5\u8BE2\u89C6\u56FE ID\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n view_scope: Type.String({\n description: '\u5DE5\u4F5C\u9879\u7C7B\u578B\uFF1A\u9700\u6C42\u4E3A storyView\uFF0C\u7F3A\u9677\u4E3A issueView\uFF0C\u7248\u672C\u4E3A version\uFF0C\u81EA\u5B9A\u4E49\u7C7B\u578B\u4E3A\u5BF9\u5E94 key',\n }),\n key_word: Type.String({ description: '\u89C6\u56FE\u540D\u79F0\u5173\u952E\u5B57' }),\n }),\n endpoint,\n });\n count++;\n\n // get_view_detail \u2014 \u83B7\u53D6\u89C6\u56FE\u8BE6\u60C5\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_view_detail',\n mcpToolName: 'get_view_detail',\n label: 'Feishu Project: \u89C6\u56FE\u8BE6\u60C5',\n description: '\u83B7\u53D6\u6307\u5B9A\u89C6\u56FE\u7684\u5DE5\u4F5C\u9879\u5217\u8868\u3002',\n schema: Type.Object({\n view_id: Type.String({ description: '\u89C6\u56FE ID' }),\n project_key: Type.Optional(Type.String({ description: '\u7A7A\u95F4 projectKey' })),\n fields: Type.Optional(\n Type.Array(Type.String({ description: '\u8981\u67E5\u8BE2\u7684 field_key \u6216 field_name' })),\n ),\n page_num: Type.Optional(Type.Number({ description: '\u5206\u9875\u9875\u7801' })),\n }),\n endpoint,\n });\n count++;\n\n // get_workitem_man_hour_records \u2014 \u5DE5\u65F6\u8BB0\u5F55\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_workitem_man_hour_records',\n mcpToolName: 'get_workitem_man_hour_records',\n label: 'Feishu Project: \u5DE5\u65F6\u8BB0\u5F55',\n description: '\u83B7\u53D6\u5DE5\u4F5C\u9879\u7684\u5DE5\u65F6\u767B\u8BB0\u8BB0\u5F55\u5217\u8868\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n work_item_type_key: Type.String({ description: '\u5DE5\u4F5C\u9879\u7C7B\u578B key' }),\n work_item_id: Type.Number({ description: '\u5DE5\u4F5C\u9879\u5B9E\u4F8B ID' }),\n page_num: Type.Optional(Type.Number({ description: '\u5206\u9875\u9875\u7801\uFF0C\u6BCF\u9875\u9ED8\u8BA4 20' })),\n }),\n endpoint,\n });\n count++;\n\n // get_workitem_op_record \u2014 \u64CD\u4F5C\u8BB0\u5F55\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_workitem_op_record',\n mcpToolName: 'get_workitem_op_record',\n label: 'Feishu Project: \u64CD\u4F5C\u8BB0\u5F55',\n description: '\u83B7\u53D6\u6307\u5B9A\u7A7A\u95F4\u4E0B\u4E00\u4E2A\u5DE5\u4F5C\u9879\u5B9E\u4F8B\u7684\u64CD\u4F5C\u8BB0\u5F55\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n work_item_id: Type.Number({ description: '\u5DE5\u4F5C\u9879 ID' }),\n start: Type.Optional(Type.Number({ description: '\u5F00\u59CB\u65F6\u95F4\uFF0C\u6BEB\u79D2\u7EA7\u65F6\u95F4\u6233' })),\n end: Type.Optional(Type.Number({ description: '\u7ED3\u675F\u65F6\u95F4\uFF0C\u6BEB\u79D2\u7EA7\u65F6\u95F4\u6233\uFF0C\u4E0E start \u914D\u5408\u6700\u957F 7 \u5929' })),\n operation_type: Type.Optional(\n Type.Array(Type.String({ description: '\u64CD\u4F5C\u7C7B\u578B\uFF1Amodify/create/delete/terminate/restore/complete/rollback/add/remove' })),\n ),\n start_from: Type.Optional(Type.String({ description: '\u5206\u9875\u53C2\u6570\uFF0C\u4F7F\u7528\u4E0A\u6B21\u8FD4\u56DE\u7684 start_from' })),\n }),\n endpoint,\n });\n count++;\n\n // list_schedule \u2014 \u6392\u671F\u67E5\u8BE2\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_schedule',\n mcpToolName: 'list_schedule',\n label: 'Feishu Project: \u6392\u671F\u67E5\u8BE2',\n description: '\u6309\u7A7A\u95F4\u548C\u7528\u6237\u67E5\u8BE2\u6307\u5B9A\u65F6\u95F4\u8303\u56F4\u5185\u7684\u6392\u671F\u660E\u7EC6\uFF0C\u7528\u4E8E\u4EBA\u529B\u8D1F\u8377\u4E0E\u6392\u671F\u5206\u6790\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey\u3001\u540D\u79F0\u6216 simple_name' }),\n user_keys: Type.Array(\n Type.String({ description: '\u7528\u6237\u540D\u79F0\u3001\u90AE\u7BB1\u6216 userkey\uFF0C\u6700\u591A 20 \u4E2A' }),\n ),\n start_time: Type.String({ description: '\u5F00\u59CB\u65F6\u95F4\uFF0C\u683C\u5F0F 2006-01-01' }),\n end_time: Type.String({ description: '\u7ED3\u675F\u65F6\u95F4\uFF0C\u683C\u5F0F 2006-01-01\uFF0C\u6700\u5927\u4E0D\u8D85\u8FC7 3 \u4E2A\u6708' }),\n work_item_type_keys: Type.Optional(\n Type.Array(Type.String({ description: '\u5DE5\u4F5C\u9879\u7C7B\u578B key\uFF0C\u4F20 _all \u67E5\u8BE2\u6240\u6709\u7C7B\u578B' })),\n ),\n }),\n endpoint,\n });\n count++;\n\n // list_related_workitems \u2014 \u5173\u8054\u5DE5\u4F5C\u9879\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_related_workitems',\n mcpToolName: 'list_related_workitems',\n label: 'Feishu Project: \u5173\u8054\u5DE5\u4F5C\u9879',\n description: '\u67E5\u8BE2\u67D0\u4E2A\u5173\u8054\u5DE5\u4F5C\u9879\u5B57\u6BB5\u6240\u5173\u8054\u7684\u5DE5\u4F5C\u9879\u5B9E\u4F8B\u7B80\u8981\u4FE1\u606F\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n work_item_type_key: Type.String({ description: '\u6E90\u5DE5\u4F5C\u9879\u7C7B\u578B' }),\n work_item_id: Type.Number({ description: '\u6E90\u5DE5\u4F5C\u9879\u5B9E\u4F8B ID' }),\n relation_work_item_type_key: Type.String({ description: '\u5173\u8054\u7684\u76EE\u6807\u5DE5\u4F5C\u9879\u7C7B\u578B' }),\n relation_key: Type.String({ description: '\u5173\u8054\u5173\u7CFB key \u6216\u5BF9\u63A5\u6807\u8BC6' }),\n relation_type: Type.Optional(Type.Number({ description: '\u5173\u8054\u6807\u8BC6\u65B9\u5F0F\uFF1A0=\u5B57\u6BB5ID\uFF0C1=\u5BF9\u63A5\u6807\u8BC6\u3002\u9ED8\u8BA4 0' })),\n page_num: Type.Optional(Type.Number({ description: '\u9875\u7801\uFF0C\u4ECE 1 \u5F00\u59CB' })),\n page_size: Type.Optional(Type.Number({ description: '\u6BCF\u9875\u6570\u91CF\uFF0C\u6700\u5927 50' })),\n }),\n endpoint,\n });\n count++;\n\n // list_workitem_relations \u2014 \u7A7A\u95F4\u5173\u8054\u5173\u7CFB\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_workitem_relations',\n mcpToolName: 'list_workitem_relations',\n label: 'Feishu Project: \u5173\u8054\u5173\u7CFB\u5217\u8868',\n description: '\u67E5\u8BE2\u67D0\u4E2A\u7A7A\u95F4\u4E0B\u7684\u6240\u6709\u5DE5\u4F5C\u9879\u5173\u8054\u5173\u7CFB\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n }),\n endpoint,\n });\n count++;\n\n // list_team_members \u2014 \u56E2\u961F\u6210\u5458\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_team_members',\n mcpToolName: 'list_team_members',\n label: 'Feishu Project: \u56E2\u961F\u6210\u5458',\n description: '\u67E5\u8BE2\u56E2\u961F\u4FE1\u606F\u548C\u6210\u5458\u5217\u8868\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n team_id: Type.String({ description: '\u56E2\u961F ID' }),\n page_token: Type.Optional(Type.String({ description: '\u5206\u9875 token\uFF0C\u9996\u9875\u4E0D\u4F20' })),\n }),\n endpoint,\n });\n count++;\n\n // list_charts \u2014 \u5EA6\u91CF\u56FE\u8868\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_charts',\n mcpToolName: 'list_charts',\n label: 'Feishu Project: \u5EA6\u91CF\u56FE\u8868',\n description: '\u67E5\u8BE2\u6307\u5B9A\u7A7A\u95F4\u89C6\u56FE\u4E0B\u7684\u6240\u6709\u5EA6\u91CF\u56FE\u8868\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n view_id: Type.String({ description: '\u89C6\u56FE ID' }),\n page_num: Type.Optional(Type.Number({ description: '\u9875\u7801\uFF0C\u9ED8\u8BA4 1' })),\n page_size: Type.Optional(Type.Number({ description: '\u6BCF\u9875\u6761\u6570\uFF0C\u9ED8\u8BA4 50\uFF0C\u6700\u5927 200' })),\n }),\n endpoint,\n });\n count++;\n\n // create_fixed_view \u2014 \u521B\u5EFA\u56FA\u5B9A\u89C6\u56FE\n registerProjectMcpTool(api, {\n name: 'feishu_project_create_fixed_view',\n mcpToolName: 'create_fixed_view',\n label: 'Feishu Project: \u521B\u5EFA\u56FA\u5B9A\u89C6\u56FE',\n description: '\u5728\u6307\u5B9A\u7A7A\u95F4\u548C\u5DE5\u4F5C\u9879\u7C7B\u578B\u4E0B\u65B0\u589E\u4E00\u4E2A\u56FA\u5B9A\u89C6\u56FE\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n name: Type.String({ description: '\u56FA\u5B9A\u89C6\u56FE\u540D\u79F0' }),\n work_item_type_key: Type.String({ description: '\u5DE5\u4F5C\u9879\u7C7B\u578B key' }),\n work_item_id_list: Type.Array(\n Type.Number({ description: '\u5DE5\u4F5C\u9879 ID' }),\n { description: '\u9700\u8981\u6DFB\u52A0\u5165\u89C6\u56FE\u7684\u5DE5\u4F5C\u9879 ID \u5217\u8868\uFF0C\u4E0A\u9650 200 \u4E2A' },\n ),\n cooperation_mode: Type.Optional(\n Type.Number({ description: '\u534F\u4F5C\u6A21\u5F0F\uFF1A1=\u6307\u5B9A\u4EBA\u5458/\u56E2\u961F, 2=\u5168\u90E8\u7BA1\u7406\u5458, 3=\u5168\u90E8\u6210\u5458\u3002\u9ED8\u8BA4 1' }),\n ),\n }),\n endpoint,\n });\n count++;\n\n // update_fixed_view \u2014 \u66F4\u65B0\u56FA\u5B9A\u89C6\u56FE\n registerProjectMcpTool(api, {\n name: 'feishu_project_update_fixed_view',\n mcpToolName: 'update_fixed_view',\n label: 'Feishu Project: \u66F4\u65B0\u56FA\u5B9A\u89C6\u56FE',\n description: '\u66F4\u65B0\u56FA\u5B9A\u89C6\u56FE\u7684\u5DE5\u4F5C\u9879\u5217\u8868\uFF08\u65B0\u589E\u6216\u5220\u9664\uFF0C\u4E0D\u80FD\u540C\u65F6\u64CD\u4F5C\uFF09\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n view_id: Type.String({ description: '\u56FA\u5B9A\u89C6\u56FE ID' }),\n work_item_type_key: Type.String({ description: '\u5DE5\u4F5C\u9879\u7C7B\u578B key' }),\n add_work_item_ids: Type.Optional(\n Type.Array(Type.Number(), { description: '\u9700\u8981\u6DFB\u52A0\u7684\u5DE5\u4F5C\u9879 ID \u5217\u8868\uFF0C\u4E0A\u9650 200' }),\n ),\n remove_work_item_ids: Type.Optional(\n Type.Array(Type.Number(), { description: '\u9700\u8981\u5220\u9664\u7684\u5DE5\u4F5C\u9879 ID \u5217\u8868\uFF0C\u4E0A\u9650 200' }),\n ),\n }),\n endpoint,\n });\n count++;\n\n log.info(`registered ${count} project MCP tools with endpoint=${endpoint}`);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * \u98DE\u4E66\u9879\u76EE MCP \u5DE5\u5177\u6CE8\u518C\n *\n * \u6BCF\u4E2A\u5DE5\u5177\u4F7F\u7528\u98DE\u4E66\u9879\u76EE\u4E13\u5C5E\u7684 MCP \u7AEF\u70B9\u548C\u72EC\u7ACB\u7684 OAuth token\u3002\n * \u4E0D\u901A\u8FC7 registerMcpTool\uFF08\u4F7F\u7528\u98DE\u4E66 Open API UAT\uFF09\uFF0C\u800C\u662F\u4F7F\u7528\n * registerProjectMcpTool \u5305\u88C5\u51FD\u6570\u3002\n *\n * \u5DE5\u5177\u53C2\u6570\u7B7E\u540D\u53C2\u7167\u98DE\u4E66\u9879\u76EE MCP Server \u7684\u5B9E\u9645\u5B9A\u4E49\u3002\n */\n\nimport type { OpenClawPluginApi } from 'openclaw/plugin-sdk';\nimport type { TSchema } from '@sinclair/typebox';\nimport { Type } from '@sinclair/typebox';\nimport type { McpRpcResponse } from '../shared';\nimport { isRecord, unwrapJsonRpcResult } from '../shared';\nimport { createToolContext, formatToolResult } from '../../helpers';\nimport { getProjectStoredToken, setProjectStoredToken, projectTokenStatus, getProjectClientId } from '../../../core/project-token-store';\nimport { refreshProjectToken } from '../../../core/project-auth';\nimport { getProjectMcpEndpoint } from './endpoint';\nimport { getTicket } from '../../../core/lark-ticket';\nimport { larkLogger } from '../../../core/lark-logger';\n\nconst log = larkLogger('tools/mcp/project');\n\n// ---------------------------------------------------------------------------\n// \u98DE\u4E66\u9879\u76EE MCP \u4E13\u7528 JSON-RPC \u5BA2\u6237\u7AEF\uFF08\u4F7F\u7528\u6807\u51C6 OAuth Bearer \u8BA4\u8BC1\uFF09\n// ---------------------------------------------------------------------------\n\nasync function callProjectMcpTool(\n name: string,\n args: Record<string, unknown>,\n toolCallId: string,\n accessToken: string,\n endpoint: string,\n): Promise<unknown> {\n const body = {\n jsonrpc: '2.0',\n id: toolCallId,\n method: 'tools/call',\n params: { name, arguments: args },\n };\n\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${accessToken}`,\n },\n body: JSON.stringify(body),\n });\n\n const text = await res.text();\n if (!res.ok) {\n throw new Error(`MCP HTTP ${res.status} ${res.statusText}: ${text.slice(0, 4000)}`);\n }\n\n let data: McpRpcResponse;\n try {\n data = JSON.parse(text) as McpRpcResponse;\n } catch {\n throw new Error(`MCP \u8FD4\u56DE\u975E JSON\uFF1A${text.slice(0, 4000)}`);\n }\n\n if ('error' in data) {\n throw new Error(`MCP error ${data.error.code}: ${data.error.message}`);\n }\n\n return unwrapJsonRpcResult(data.result);\n}\n\n// ---------------------------------------------------------------------------\n// \u98DE\u4E66\u9879\u76EE MCP \u5DE5\u5177\u901A\u7528\u6CE8\u518C\u51FD\u6570\n// ---------------------------------------------------------------------------\n\ninterface ProjectMcpToolConfig {\n name: string;\n mcpToolName: string;\n label: string;\n description: string;\n schema: TSchema;\n endpoint: string | (() => string);\n}\n\nexport function registerProjectMcpTool(\n api: OpenClawPluginApi,\n config: ProjectMcpToolConfig,\n): void {\n const { log: toolLog } = createToolContext(api, config.name);\n\n api.registerTool(\n {\n name: config.name,\n label: config.label,\n description: config.description,\n parameters: config.schema,\n async execute(toolCallId, params) {\n const p = params as Record<string, unknown>;\n try {\n const startTime = Date.now();\n\n const ticket = getTicket();\n const senderOpenId = ticket?.senderOpenId;\n if (!senderOpenId) {\n return formatToolResult({\n error: '\u65E0\u6CD5\u83B7\u53D6\u5F53\u524D\u7528\u6237\u8EAB\u4EFD\uFF0C\u8BF7\u5728\u98DE\u4E66\u5BF9\u8BDD\u4E2D\u4F7F\u7528\u6B64\u5DE5\u5177\u3002',\n });\n }\n\n const clientId = await getProjectClientId(senderOpenId);\n if (!clientId) {\n return formatToolResult({\n error: 'project_auth_required',\n message: '\u98DE\u4E66\u9879\u76EE\u672A\u6388\u6743\u3002\u8BF7\u5148\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\u5B8C\u6210\u6388\u6743\u3002',\n });\n }\n\n let token = await getProjectStoredToken(clientId, senderOpenId);\n if (!token) {\n return formatToolResult({\n error: 'project_auth_required',\n message: '\u98DE\u4E66\u9879\u76EE\u672A\u6388\u6743\u3002\u8BF7\u5148\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\u5B8C\u6210\u6388\u6743\u3002',\n });\n }\n\n const status = projectTokenStatus(token);\n if (status === 'expired') {\n return formatToolResult({\n error: 'project_auth_required',\n message: '\u98DE\u4E66\u9879\u76EE\u6388\u6743\u5DF2\u8FC7\u671F\u3002\u8BF7\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\u7684 authorize \u64CD\u4F5C\u91CD\u65B0\u6388\u6743\u3002',\n });\n }\n\n // Token \u5373\u5C06\u8FC7\u671F\u6216\u5DF2\u8FC7\u671F\u4F46 refresh_token \u4ECD\u6709\u6548 \u2192 \u81EA\u52A8\u5237\u65B0\n if (status === 'needs_refresh') {\n try {\n const resolvedEp = typeof config.endpoint === 'function' ? config.endpoint() : config.endpoint;\n const refreshed = await refreshProjectToken(resolvedEp, token.refreshToken, clientId);\n token = {\n ...token,\n accessToken: refreshed.access_token,\n refreshToken: refreshed.refresh_token ?? token.refreshToken,\n expiresAt: Date.now() + (refreshed.expires_in ?? 7200) * 1000,\n scope: refreshed.scope ?? token.scope,\n };\n await setProjectStoredToken(token);\n toolLog.debug?.('project token refreshed');\n } catch (refreshErr) {\n toolLog.error(`project token refresh failed: ${refreshErr}`);\n return formatToolResult({\n error: 'project_auth_required',\n message: '\u98DE\u4E66\u9879\u76EE token \u5237\u65B0\u5931\u8D25\uFF0C\u8BF7\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\u7684 authorize \u64CD\u4F5C\u91CD\u65B0\u6388\u6743\u3002',\n });\n }\n }\n\n const resolvedEndpoint = typeof config.endpoint === 'function' ? config.endpoint() : config.endpoint;\n\n const result = await callProjectMcpTool(\n config.mcpToolName,\n p,\n toolCallId,\n token.accessToken,\n resolvedEndpoint,\n );\n\n const duration = Date.now() - startTime;\n toolLog.debug?.(`${config.mcpToolName} succeeded in ${duration}ms`);\n\n // MCP \u8FD4\u56DE\u503C\u5904\u7406\uFF08\u540C registerMcpTool \u903B\u8F91\uFF09\n if (isRecord(result) && Array.isArray((result as Record<string, unknown>).content)) {\n const mcpContent = (result as Record<string, unknown>).content as Array<{\n type: string;\n text: string;\n }>;\n let details: unknown = result;\n if (mcpContent.length === 1 && mcpContent[0]?.type === 'text') {\n try {\n details = JSON.parse(mcpContent[0].text);\n } catch {\n // text is not JSON\n }\n }\n return {\n content: mcpContent.map((c) => ({\n type: 'text' as const,\n text: c.text,\n })),\n details,\n };\n }\n return formatToolResult(result);\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n toolLog.error(`${config.mcpToolName} failed: ${errMsg}`);\n return formatToolResult({\n error: errMsg,\n hint: '\u5982\u679C\u662F\u6388\u6743\u95EE\u9898\uFF0C\u8BF7\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\u91CD\u65B0\u6388\u6743\u3002',\n });\n }\n },\n },\n { name: config.name },\n );\n}\n\n// ---------------------------------------------------------------------------\n// \u5177\u4F53\u5DE5\u5177\u6CE8\u518C\uFF08\u53C2\u6570\u7B7E\u540D\u5339\u914D\u98DE\u4E66\u9879\u76EE MCP Server \u5B9E\u9645\u5B9A\u4E49\uFF09\n// ---------------------------------------------------------------------------\n\nexport function registerProjectTools(api: OpenClawPluginApi, endpoint: string | (() => string)) {\n let count = 0;\n\n // list_todo \u2014 \u5F85\u529E/\u5DF2\u529E/\u8D85\u671F/\u672C\u5468\u5230\u671F\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_todo',\n mcpToolName: 'list_todo',\n label: 'Feishu Project: \u5F85\u529E\u5217\u8868',\n description:\n '\u83B7\u53D6\u5F53\u524D\u7528\u6237\u7684\u98DE\u4E66\u9879\u76EE\u5DE5\u4F5C\u9879\u5217\u8868\u3002\u652F\u6301\u67E5\u8BE2\u7C7B\u578B\uFF1A' +\n 'todo(\u5F85\u529E)\u3001done(\u5DF2\u529E)\u3001overdue(\u5DF2\u8D85\u671F)\u3001this_week(\u672C\u5468\u5230\u671F)\u3002',\n schema: Type.Object({\n action: Type.String({\n description: '\u67E5\u8BE2\u7C7B\u578B\u3002todo \u4E3A\u5F85\u529E, done \u4E3A\u5DF2\u529E, overdue \u4E3A\u5DF2\u8D85\u671F, this_week \u4E3A\u672C\u5468\u5230\u671F',\n }),\n asset_key: Type.Optional(\n Type.String({ description: '\u5DE5\u4F5C\u533A key\uFF0C\u683C\u5F0F\u4E3A Asset_\uFF0C\u4EC5\u5728\u63A5\u53E3\u62A5\u9519\u9700\u8981\u9009\u62E9\u65F6\u4F20\u9012' }),\n ),\n page_num: Type.Optional(\n Type.Number({ description: '\u9875\u7801\uFF0C\u4ECE 1 \u5F00\u59CB\u9012\u589E\uFF0C\u6BCF\u9875 50 \u6761' }),\n ),\n }),\n endpoint,\n });\n count++;\n\n // search_by_mql \u2014 MQL \u67E5\u8BE2\n registerProjectMcpTool(api, {\n name: 'feishu_project_search_by_mql',\n mcpToolName: 'search_by_mql',\n label: 'Feishu Project: MQL \u641C\u7D22',\n description:\n '\u4F7F\u7528 MQL \u641C\u7D22\u98DE\u4E66\u9879\u76EE\u5DE5\u4F5C\u9879\u3002MQL \u57FA\u4E8E SQL \u8BED\u6CD5\u6269\u5C55\u3002' +\n '\u4F7F\u7528\u524D\u9700\u5148\u7528 get_workitem_info \u786E\u8BA4\u7A7A\u95F4\u548C\u5DE5\u4F5C\u9879\u7C7B\u578B\u3002' +\n 'select \u540E\u4F7F\u7528\u53EF\u8BFB\u6027\u5F3A\u7684\u5B57\u6BB5\u540D\u79F0\uFF08\u5982\"\u4EFB\u52A1\u540D\u79F0\"\u800C\u975E\"name\"\uFF09\u3002',\n schema: Type.Object({\n project_key: Type.String({\n description: '\u7A7A\u95F4 projectKey\u3001simpleName \u6216\u7A7A\u95F4\u540D',\n }),\n mql: Type.Optional(\n Type.String({\n description:\n 'MQL \u8BED\u53E5\u3002\u8BED\u6CD5\uFF1Aselect `\u5B57\u6BB5\u540D` from `\u7A7A\u95F4\u540D`.`\u5DE5\u4F5C\u9879\u540D` where `\u5B57\u6BB5\u540D` = \\'\u5B57\u6BB5\u503C\\'',\n }),\n ),\n helper: Type.Optional(\n Type.String({\n description: '\u5E2E\u52A9\u5DE5\u5177\u3002\u8F93\u5165 \"helper\" \u83B7\u53D6\u6240\u6709\u547D\u4EE4\u548C\u7528\u6CD5\u793A\u4F8B',\n }),\n ),\n session_id: Type.Optional(\n Type.String({ description: 'sessionID\uFF0C\u7528\u4E8E\u5206\u9875\u67E5\u8BE2\uFF0C\u4F20\u5165\u540E\u4E0D\u89E3\u6790 mql' }),\n ),\n group_pagination_list: Type.Optional(\n Type.Array(\n Type.Object({\n group_id: Type.Optional(Type.String({ description: '\u5206\u7EC4 ID' })),\n page_num: Type.Optional(Type.Number({ description: '\u9875\u7801\uFF0C\u4ECE 1 \u5F00\u59CB' })),\n }),\n ),\n ),\n }),\n endpoint,\n });\n count++;\n\n // get_workitem_info \u2014 \u83B7\u53D6\u5DE5\u4F5C\u9879\u7C7B\u578B\u7684\u5B57\u6BB5\u4E0E\u89D2\u8272\u4FE1\u606F\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_workitem_info',\n mcpToolName: 'get_workitem_info',\n label: 'Feishu Project: \u5DE5\u4F5C\u9879\u7C7B\u578B\u4FE1\u606F',\n description: '\u83B7\u53D6\u4E00\u4E2A\u5DE5\u4F5C\u9879\u7C7B\u578B\u5177\u5907\u7684\u53EF\u7528\u5B57\u6BB5\u4E0E\u89D2\u8272\u4FE1\u606F\u3002',\n schema: Type.Object({\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n ),\n work_item_type: Type.String({\n description: '\u5DE5\u4F5C\u9879\u7C7B\u578B\u7684\u7CFB\u7EDF\u6807\u8BC6\u6216\u540D\u79F0\uFF0C\u5982 story\u3001\u9700\u6C42\u3001issue\u3001\u7F3A\u9677\u7B49',\n }),\n }),\n endpoint,\n });\n count++;\n\n // get_workitem_brief \u2014 \u83B7\u53D6\u5DE5\u4F5C\u9879\u6982\u51B5\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_workitem_brief',\n mcpToolName: 'get_workitem_brief',\n label: 'Feishu Project: \u5DE5\u4F5C\u9879\u6982\u51B5',\n description: '\u83B7\u53D6\u4E00\u4E2A\u5DE5\u4F5C\u9879\u5B9E\u4F8B\u7684\u6982\u51B5\u4FE1\u606F\u3002',\n schema: Type.Object({\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey \u6216 simpleName' }),\n ),\n work_item_id: Type.String({\n description: '\u5DE5\u4F5C\u9879 ID \u6216\u540D\u79F0',\n }),\n fields: Type.Optional(\n Type.Array(Type.String({ description: '\u8981\u67E5\u8BE2\u7684 field_key \u6216 field_name' })),\n ),\n }),\n endpoint,\n });\n count++;\n\n // get_workitem_field_meta \u2014 \u83B7\u53D6\u521B\u5EFA\u5DE5\u4F5C\u9879\u5143\u4FE1\u606F\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_workitem_field_meta',\n mcpToolName: 'get_workitem_field_meta',\n label: 'Feishu Project: \u5B57\u6BB5\u5143\u4FE1\u606F',\n description: '\u83B7\u53D6\u521B\u5EFA\u5DE5\u4F5C\u9879\u65F6\u7684\u5B57\u6BB5\u5143\u4FE1\u606F\uFF08\u5B57\u6BB5\u540D\u3001\u7C7B\u578B\u3001\u9009\u9879\u7B49\uFF09\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n work_item_type_key: Type.String({ description: '\u5DE5\u4F5C\u9879\u7C7B\u578B key' }),\n }),\n endpoint,\n });\n count++;\n\n // create_workitem \u2014 \u521B\u5EFA\u5DE5\u4F5C\u9879\n registerProjectMcpTool(api, {\n name: 'feishu_project_create_workitem',\n mcpToolName: 'create_workitem',\n label: 'Feishu Project: \u521B\u5EFA\u5DE5\u4F5C\u9879',\n description: '\u521B\u5EFA\u4E00\u6761\u5DE5\u4F5C\u9879\u5B9E\u4F8B\u3002\u521B\u5EFA\u6210\u529F\u540E\u83B7\u5F97\u8BE6\u60C5\u9875 URL\u3002',\n schema: Type.Object({\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey \u6216 simpleName' }),\n ),\n work_item_type: Type.String({\n description: '\u5DE5\u4F5C\u9879\u7C7B\u578B',\n }),\n fields: Type.Optional(\n Type.Array(\n Type.Object({\n field_key: Type.String({ description: '\u5B57\u6BB5 key' }),\n field_value: Type.String({\n description: '\u5B57\u6BB5\u503C\u3002\u65F6\u95F4\u7C7B\u9700\u4F20 16 \u4F4D unix \u6BEB\u79D2\u65F6\u95F4\u6233\uFF0C\u4EBA\u5458\u7C7B\u9700\u7528\u82F1\u6587\u9017\u53F7\u533A\u9694',\n }),\n }),\n ),\n ),\n }),\n endpoint,\n });\n count++;\n\n // update_field \u2014 \u4FEE\u6539\u5DE5\u4F5C\u9879\u5B57\u6BB5\n registerProjectMcpTool(api, {\n name: 'feishu_project_update_field',\n mcpToolName: 'update_field',\n label: 'Feishu Project: \u4FEE\u6539\u5B57\u6BB5',\n description: '\u4FEE\u6539\u6307\u5B9A\u5DE5\u4F5C\u9879\u5B9E\u4F8B\u7684\u5B57\u6BB5\u503C\uFF0C\u652F\u6301\u4E00\u6B21\u4FEE\u6539\u591A\u4E2A\u5B57\u6BB5\u3002',\n schema: Type.Object({\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n ),\n work_item_id: Type.String({\n description: '\u5DE5\u4F5C\u9879 ID \u6216\u540D\u79F0',\n }),\n fields: Type.Optional(\n Type.Array(\n Type.Object({\n field_key: Type.String({ description: '\u5B57\u6BB5 key' }),\n field_value: Type.String({\n description: '\u5B57\u6BB5\u503C\u3002\u65F6\u95F4\u7C7B\u9700\u4F20 16 \u4F4D unix \u6BEB\u79D2\u65F6\u95F4\u6233\uFF0C\u4EBA\u5458\u7C7B\u9700\u7528\u82F1\u6587\u9017\u53F7\u533A\u9694',\n }),\n }),\n ),\n ),\n }),\n endpoint,\n });\n count++;\n\n // add_comment \u2014 \u6DFB\u52A0\u8BC4\u8BBA\n registerProjectMcpTool(api, {\n name: 'feishu_project_add_comment',\n mcpToolName: 'add_comment',\n label: 'Feishu Project: \u6DFB\u52A0\u8BC4\u8BBA',\n description: '\u5728\u6307\u5B9A\u5DE5\u4F5C\u9879\u7684\u8BC4\u8BBA/\u5907\u6CE8\u9875\u6DFB\u52A0\u4E00\u6761\u8BC4\u8BBA\uFF0C\u652F\u6301 markdown \u683C\u5F0F\u3002',\n schema: Type.Object({\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n ),\n work_item_id: Type.String({\n description: '\u5DE5\u4F5C\u9879 ID \u6216\u540D\u79F0',\n }),\n work_item_type: Type.Optional(\n Type.String({ description: '\u5DE5\u4F5C\u9879\u7C7B\u578B' }),\n ),\n comment_content: Type.String({\n description: '\u8BC4\u8BBA\u5185\u5BB9\uFF0C\u652F\u6301 markdown \u683C\u5F0F',\n }),\n url: Type.Optional(\n Type.String({ description: '\u5DE5\u4F5C\u9879 URL\uFF0C\u53EF\u4ECE\u4E2D\u89E3\u6790 project_key \u7B49\u4FE1\u606F' }),\n ),\n }),\n endpoint,\n });\n count++;\n\n // finish_node \u2014 \u5B8C\u6210\u8282\u70B9/\u6D41\u8F6C\u72B6\u6001\n registerProjectMcpTool(api, {\n name: 'feishu_project_finish_node',\n mcpToolName: 'finish_node',\n label: 'Feishu Project: \u6D41\u8F6C\u72B6\u6001',\n description: '\u5B8C\u6210\u67D0\u4E2A\u8282\u70B9\uFF0C\u6D41\u8F6C\u5DE5\u4F5C\u9879\u5230\u4E0B\u4E00\u4E2A\u72B6\u6001\u3002',\n schema: Type.Object({\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n ),\n work_item_id: Type.String({\n description: '\u5DE5\u4F5C\u9879 ID \u6216\u540D\u79F0',\n }),\n node_id: Type.String({\n description: '\u8981\u5B8C\u6210\u6D41\u8F6C\u7684\u8282\u70B9 ID \u6216\u8282\u70B9\u540D\u79F0',\n }),\n }),\n endpoint,\n });\n count++;\n\n // get_node_detail \u2014 \u83B7\u53D6\u8282\u70B9\u8BE6\u60C5\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_node_detail',\n mcpToolName: 'get_node_detail',\n label: 'Feishu Project: \u8282\u70B9\u8BE6\u60C5',\n description: '\u83B7\u53D6\u6307\u5B9A\u8282\u70B9\u7684\u5173\u952E\u4FE1\u606F\uFF0C\u5305\u62EC\u8282\u70B9\u4FE1\u606F\u3001\u5B50\u9879\u4FE1\u606F\u3001\u81EA\u5B9A\u4E49\u5B57\u6BB5\u4FE1\u606F\u3002',\n schema: Type.Object({\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n ),\n work_item_id: Type.String({ description: '\u5DE5\u4F5C\u9879 ID' }),\n node_id: Type.String({ description: '\u8282\u70B9\u540D\u79F0\u6216\u8282\u70B9 ID' }),\n node_ids: Type.Optional(\n Type.Array(Type.String({ description: '\u8282\u70B9\u540D\u79F0\u6216\u8282\u70B9 ID \u5217\u8868' })),\n ),\n }),\n endpoint,\n });\n count++;\n\n // get_transitable_statuses \u2014 \u83B7\u53D6\u53EF\u6D41\u8F6C\u72B6\u6001\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_transitable_statuses',\n mcpToolName: 'get_transitable_statuses',\n label: 'Feishu Project: \u53EF\u6D41\u8F6C\u72B6\u6001',\n description: '\u83B7\u53D6\u72B6\u6001\u6D41\u5DE5\u4F5C\u9879\u7684\u53EF\u6D41\u8F6C\u72B6\u6001\u5217\u8868\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n work_item_id: Type.String({ description: '\u5DE5\u4F5C\u9879 ID' }),\n work_item_type_key: Type.String({ description: '\u5DE5\u4F5C\u9879\u7C7B\u578B key' }),\n user_key: Type.String({ description: '\u7528\u6237 userKey' }),\n }),\n endpoint,\n });\n count++;\n\n // list_workitem_types \u2014 \u83B7\u53D6\u5DE5\u4F5C\u9879\u7C7B\u578B\u5217\u8868\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_workitem_types',\n mcpToolName: 'list_workitem_types',\n label: 'Feishu Project: \u5DE5\u4F5C\u9879\u7C7B\u578B\u5217\u8868',\n description: '\u83B7\u53D6\u7A7A\u95F4\u4E0B\u7684\u6240\u6709\u5DE5\u4F5C\u9879\u7C7B\u578B\u5217\u8868\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n }),\n endpoint,\n });\n count++;\n\n // search_project_info \u2014 \u67E5\u8BE2\u7A7A\u95F4\u4FE1\u606F\n registerProjectMcpTool(api, {\n name: 'feishu_project_search_project_info',\n mcpToolName: 'search_project_info',\n label: 'Feishu Project: \u67E5\u8BE2\u7A7A\u95F4',\n description: '\u67E5\u8BE2\u98DE\u4E66\u9879\u76EE\u7A7A\u95F4\u57FA\u7840\u4FE1\u606F\u3002',\n schema: Type.Object({\n project_key: Type.String({\n description: '\u7A7A\u95F4 projectKey\u3001simpleName \u6216\u7A7A\u95F4\u540D\u79F0',\n }),\n }),\n endpoint,\n });\n count++;\n\n // search_user_info \u2014 \u67E5\u8BE2\u7528\u6237\u4FE1\u606F\n registerProjectMcpTool(api, {\n name: 'feishu_project_search_user_info',\n mcpToolName: 'search_user_info',\n label: 'Feishu Project: \u67E5\u8BE2\u7528\u6237',\n description: '\u6279\u91CF\u67E5\u8BE2\u7528\u6237\u57FA\u7840\u4FE1\u606F\uFF0C\u6700\u591A 20 \u4E2A\u3002',\n schema: Type.Object({\n user_keys: Type.Array(\n Type.String({ description: 'userKey\u3001Email \u6216\u540D\u5B57' }),\n ),\n project_key: Type.Optional(\n Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n ),\n }),\n endpoint,\n });\n count++;\n\n // list_workitem_comments \u2014 \u67E5\u8BE2\u8BC4\u8BBA\u5217\u8868\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_workitem_comments',\n mcpToolName: 'list_workitem_comments',\n label: 'Feishu Project: \u8BC4\u8BBA\u5217\u8868',\n description: '\u67E5\u8BE2\u5DE5\u4F5C\u9879\u8BC4\u8BBA\u5217\u8868\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n work_item_id: Type.String({ description: '\u5DE5\u4F5C\u9879 ID \u6216\u540D\u79F0' }),\n page_num: Type.Optional(Type.Number({ description: '\u9875\u7801\uFF0C\u9ED8\u8BA4 1' })),\n start_time: Type.Optional(Type.Number({ description: '\u5F00\u59CB\u65F6\u95F4\uFF0CUnix \u6BEB\u79D2\u65F6\u95F4\u6233' })),\n end_time: Type.Optional(Type.Number({ description: '\u7ED3\u675F\u65F6\u95F4\uFF0CUnix \u6BEB\u79D2\u65F6\u95F4\u6233' })),\n }),\n endpoint,\n });\n count++;\n\n // search_view_by_title \u2014 \u641C\u7D22\u89C6\u56FE\n registerProjectMcpTool(api, {\n name: 'feishu_project_search_view_by_title',\n mcpToolName: 'search_view_by_title',\n label: 'Feishu Project: \u641C\u7D22\u89C6\u56FE',\n description: '\u901A\u8FC7\u89C6\u56FE\u540D\u79F0\u6A21\u7CCA\u67E5\u8BE2\u89C6\u56FE ID\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n view_scope: Type.String({\n description: '\u5DE5\u4F5C\u9879\u7C7B\u578B\uFF1A\u9700\u6C42\u4E3A storyView\uFF0C\u7F3A\u9677\u4E3A issueView\uFF0C\u7248\u672C\u4E3A version\uFF0C\u81EA\u5B9A\u4E49\u7C7B\u578B\u4E3A\u5BF9\u5E94 key',\n }),\n key_word: Type.String({ description: '\u89C6\u56FE\u540D\u79F0\u5173\u952E\u5B57' }),\n }),\n endpoint,\n });\n count++;\n\n // get_view_detail \u2014 \u83B7\u53D6\u89C6\u56FE\u8BE6\u60C5\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_view_detail',\n mcpToolName: 'get_view_detail',\n label: 'Feishu Project: \u89C6\u56FE\u8BE6\u60C5',\n description: '\u83B7\u53D6\u6307\u5B9A\u89C6\u56FE\u7684\u5DE5\u4F5C\u9879\u5217\u8868\u3002',\n schema: Type.Object({\n view_id: Type.String({ description: '\u89C6\u56FE ID' }),\n project_key: Type.Optional(Type.String({ description: '\u7A7A\u95F4 projectKey' })),\n fields: Type.Optional(\n Type.Array(Type.String({ description: '\u8981\u67E5\u8BE2\u7684 field_key \u6216 field_name' })),\n ),\n page_num: Type.Optional(Type.Number({ description: '\u5206\u9875\u9875\u7801' })),\n }),\n endpoint,\n });\n count++;\n\n // get_workitem_man_hour_records \u2014 \u5DE5\u65F6\u8BB0\u5F55\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_workitem_man_hour_records',\n mcpToolName: 'get_workitem_man_hour_records',\n label: 'Feishu Project: \u5DE5\u65F6\u8BB0\u5F55',\n description: '\u83B7\u53D6\u5DE5\u4F5C\u9879\u7684\u5DE5\u65F6\u767B\u8BB0\u8BB0\u5F55\u5217\u8868\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n work_item_type_key: Type.String({ description: '\u5DE5\u4F5C\u9879\u7C7B\u578B key' }),\n work_item_id: Type.Number({ description: '\u5DE5\u4F5C\u9879\u5B9E\u4F8B ID' }),\n page_num: Type.Optional(Type.Number({ description: '\u5206\u9875\u9875\u7801\uFF0C\u6BCF\u9875\u9ED8\u8BA4 20' })),\n }),\n endpoint,\n });\n count++;\n\n // get_workitem_op_record \u2014 \u64CD\u4F5C\u8BB0\u5F55\n registerProjectMcpTool(api, {\n name: 'feishu_project_get_workitem_op_record',\n mcpToolName: 'get_workitem_op_record',\n label: 'Feishu Project: \u64CD\u4F5C\u8BB0\u5F55',\n description: '\u83B7\u53D6\u6307\u5B9A\u7A7A\u95F4\u4E0B\u4E00\u4E2A\u5DE5\u4F5C\u9879\u5B9E\u4F8B\u7684\u64CD\u4F5C\u8BB0\u5F55\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n work_item_id: Type.Number({ description: '\u5DE5\u4F5C\u9879 ID' }),\n start: Type.Optional(Type.Number({ description: '\u5F00\u59CB\u65F6\u95F4\uFF0C\u6BEB\u79D2\u7EA7\u65F6\u95F4\u6233' })),\n end: Type.Optional(Type.Number({ description: '\u7ED3\u675F\u65F6\u95F4\uFF0C\u6BEB\u79D2\u7EA7\u65F6\u95F4\u6233\uFF0C\u4E0E start \u914D\u5408\u6700\u957F 7 \u5929' })),\n operation_type: Type.Optional(\n Type.Array(Type.String({ description: '\u64CD\u4F5C\u7C7B\u578B\uFF1Amodify/create/delete/terminate/restore/complete/rollback/add/remove' })),\n ),\n start_from: Type.Optional(Type.String({ description: '\u5206\u9875\u53C2\u6570\uFF0C\u4F7F\u7528\u4E0A\u6B21\u8FD4\u56DE\u7684 start_from' })),\n }),\n endpoint,\n });\n count++;\n\n // list_schedule \u2014 \u6392\u671F\u67E5\u8BE2\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_schedule',\n mcpToolName: 'list_schedule',\n label: 'Feishu Project: \u6392\u671F\u67E5\u8BE2',\n description: '\u6309\u7A7A\u95F4\u548C\u7528\u6237\u67E5\u8BE2\u6307\u5B9A\u65F6\u95F4\u8303\u56F4\u5185\u7684\u6392\u671F\u660E\u7EC6\uFF0C\u7528\u4E8E\u4EBA\u529B\u8D1F\u8377\u4E0E\u6392\u671F\u5206\u6790\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey\u3001\u540D\u79F0\u6216 simple_name' }),\n user_keys: Type.Array(\n Type.String({ description: '\u7528\u6237\u540D\u79F0\u3001\u90AE\u7BB1\u6216 userkey\uFF0C\u6700\u591A 20 \u4E2A' }),\n ),\n start_time: Type.String({ description: '\u5F00\u59CB\u65F6\u95F4\uFF0C\u683C\u5F0F 2006-01-01' }),\n end_time: Type.String({ description: '\u7ED3\u675F\u65F6\u95F4\uFF0C\u683C\u5F0F 2006-01-01\uFF0C\u6700\u5927\u4E0D\u8D85\u8FC7 3 \u4E2A\u6708' }),\n work_item_type_keys: Type.Optional(\n Type.Array(Type.String({ description: '\u5DE5\u4F5C\u9879\u7C7B\u578B key\uFF0C\u4F20 _all \u67E5\u8BE2\u6240\u6709\u7C7B\u578B' })),\n ),\n }),\n endpoint,\n });\n count++;\n\n // list_related_workitems \u2014 \u5173\u8054\u5DE5\u4F5C\u9879\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_related_workitems',\n mcpToolName: 'list_related_workitems',\n label: 'Feishu Project: \u5173\u8054\u5DE5\u4F5C\u9879',\n description: '\u67E5\u8BE2\u67D0\u4E2A\u5173\u8054\u5DE5\u4F5C\u9879\u5B57\u6BB5\u6240\u5173\u8054\u7684\u5DE5\u4F5C\u9879\u5B9E\u4F8B\u7B80\u8981\u4FE1\u606F\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n work_item_type_key: Type.String({ description: '\u6E90\u5DE5\u4F5C\u9879\u7C7B\u578B' }),\n work_item_id: Type.Number({ description: '\u6E90\u5DE5\u4F5C\u9879\u5B9E\u4F8B ID' }),\n relation_work_item_type_key: Type.String({ description: '\u5173\u8054\u7684\u76EE\u6807\u5DE5\u4F5C\u9879\u7C7B\u578B' }),\n relation_key: Type.String({ description: '\u5173\u8054\u5173\u7CFB key \u6216\u5BF9\u63A5\u6807\u8BC6' }),\n relation_type: Type.Optional(Type.Number({ description: '\u5173\u8054\u6807\u8BC6\u65B9\u5F0F\uFF1A0=\u5B57\u6BB5ID\uFF0C1=\u5BF9\u63A5\u6807\u8BC6\u3002\u9ED8\u8BA4 0' })),\n page_num: Type.Optional(Type.Number({ description: '\u9875\u7801\uFF0C\u4ECE 1 \u5F00\u59CB' })),\n page_size: Type.Optional(Type.Number({ description: '\u6BCF\u9875\u6570\u91CF\uFF0C\u6700\u5927 50' })),\n }),\n endpoint,\n });\n count++;\n\n // list_workitem_relations \u2014 \u7A7A\u95F4\u5173\u8054\u5173\u7CFB\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_workitem_relations',\n mcpToolName: 'list_workitem_relations',\n label: 'Feishu Project: \u5173\u8054\u5173\u7CFB\u5217\u8868',\n description: '\u67E5\u8BE2\u67D0\u4E2A\u7A7A\u95F4\u4E0B\u7684\u6240\u6709\u5DE5\u4F5C\u9879\u5173\u8054\u5173\u7CFB\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n }),\n endpoint,\n });\n count++;\n\n // list_team_members \u2014 \u56E2\u961F\u6210\u5458\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_team_members',\n mcpToolName: 'list_team_members',\n label: 'Feishu Project: \u56E2\u961F\u6210\u5458',\n description: '\u67E5\u8BE2\u56E2\u961F\u4FE1\u606F\u548C\u6210\u5458\u5217\u8868\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n team_id: Type.String({ description: '\u56E2\u961F ID' }),\n page_token: Type.Optional(Type.String({ description: '\u5206\u9875 token\uFF0C\u9996\u9875\u4E0D\u4F20' })),\n }),\n endpoint,\n });\n count++;\n\n // list_charts \u2014 \u5EA6\u91CF\u56FE\u8868\n registerProjectMcpTool(api, {\n name: 'feishu_project_list_charts',\n mcpToolName: 'list_charts',\n label: 'Feishu Project: \u5EA6\u91CF\u56FE\u8868',\n description: '\u67E5\u8BE2\u6307\u5B9A\u7A7A\u95F4\u89C6\u56FE\u4E0B\u7684\u6240\u6709\u5EA6\u91CF\u56FE\u8868\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n view_id: Type.String({ description: '\u89C6\u56FE ID' }),\n page_num: Type.Optional(Type.Number({ description: '\u9875\u7801\uFF0C\u9ED8\u8BA4 1' })),\n page_size: Type.Optional(Type.Number({ description: '\u6BCF\u9875\u6761\u6570\uFF0C\u9ED8\u8BA4 50\uFF0C\u6700\u5927 200' })),\n }),\n endpoint,\n });\n count++;\n\n // create_fixed_view \u2014 \u521B\u5EFA\u56FA\u5B9A\u89C6\u56FE\n registerProjectMcpTool(api, {\n name: 'feishu_project_create_fixed_view',\n mcpToolName: 'create_fixed_view',\n label: 'Feishu Project: \u521B\u5EFA\u56FA\u5B9A\u89C6\u56FE',\n description: '\u5728\u6307\u5B9A\u7A7A\u95F4\u548C\u5DE5\u4F5C\u9879\u7C7B\u578B\u4E0B\u65B0\u589E\u4E00\u4E2A\u56FA\u5B9A\u89C6\u56FE\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n name: Type.String({ description: '\u56FA\u5B9A\u89C6\u56FE\u540D\u79F0' }),\n work_item_type_key: Type.String({ description: '\u5DE5\u4F5C\u9879\u7C7B\u578B key' }),\n work_item_id_list: Type.Array(\n Type.Number({ description: '\u5DE5\u4F5C\u9879 ID' }),\n { description: '\u9700\u8981\u6DFB\u52A0\u5165\u89C6\u56FE\u7684\u5DE5\u4F5C\u9879 ID \u5217\u8868\uFF0C\u4E0A\u9650 200 \u4E2A' },\n ),\n cooperation_mode: Type.Optional(\n Type.Number({ description: '\u534F\u4F5C\u6A21\u5F0F\uFF1A1=\u6307\u5B9A\u4EBA\u5458/\u56E2\u961F, 2=\u5168\u90E8\u7BA1\u7406\u5458, 3=\u5168\u90E8\u6210\u5458\u3002\u9ED8\u8BA4 1' }),\n ),\n }),\n endpoint,\n });\n count++;\n\n // update_fixed_view \u2014 \u66F4\u65B0\u56FA\u5B9A\u89C6\u56FE\n registerProjectMcpTool(api, {\n name: 'feishu_project_update_fixed_view',\n mcpToolName: 'update_fixed_view',\n label: 'Feishu Project: \u66F4\u65B0\u56FA\u5B9A\u89C6\u56FE',\n description: '\u66F4\u65B0\u56FA\u5B9A\u89C6\u56FE\u7684\u5DE5\u4F5C\u9879\u5217\u8868\uFF08\u65B0\u589E\u6216\u5220\u9664\uFF0C\u4E0D\u80FD\u540C\u65F6\u64CD\u4F5C\uFF09\u3002',\n schema: Type.Object({\n project_key: Type.String({ description: '\u7A7A\u95F4 projectKey' }),\n view_id: Type.String({ description: '\u56FA\u5B9A\u89C6\u56FE ID' }),\n work_item_type_key: Type.String({ description: '\u5DE5\u4F5C\u9879\u7C7B\u578B key' }),\n add_work_item_ids: Type.Optional(\n Type.Array(Type.Number(), { description: '\u9700\u8981\u6DFB\u52A0\u7684\u5DE5\u4F5C\u9879 ID \u5217\u8868\uFF0C\u4E0A\u9650 200' }),\n ),\n remove_work_item_ids: Type.Optional(\n Type.Array(Type.Number(), { description: '\u9700\u8981\u5220\u9664\u7684\u5DE5\u4F5C\u9879 ID \u5217\u8868\uFF0C\u4E0A\u9650 200' }),\n ),\n }),\n endpoint,\n });\n count++;\n\n log.info(`registered ${count} project MCP tools with endpoint=${endpoint}`);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -277,7 +277,19 @@ function buildAuthSuccessCard() {
|
|
|
277
277
|
}
|
|
278
278
|
};
|
|
279
279
|
}
|
|
280
|
-
function buildAuthFailedCard(
|
|
280
|
+
function buildAuthFailedCard(reason) {
|
|
281
|
+
let userMessage;
|
|
282
|
+
if (reason.includes("authorization denied") || reason.includes("access_denied")) {
|
|
283
|
+
userMessage = "\u6388\u6743\u88AB\u62D2\u7EDD\u6216\u5DF2\u53D6\u6D88\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u6388\u6743\u5E76\u786E\u8BA4\u6388\u6743\u3002";
|
|
284
|
+
} else if (reason.includes("state mismatch")) {
|
|
285
|
+
userMessage = "\u6388\u6743\u4F1A\u8BDD\u4E0D\u5339\u914D\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u6388\u6743\u3002";
|
|
286
|
+
} else if (reason.includes("Token exchange failed")) {
|
|
287
|
+
userMessage = "\u6388\u6743\u7801\u4EA4\u6362\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u6388\u6743\u3002\u53EF\u80FD\u662F\u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F\u6216\u5DF2\u88AB\u4F7F\u7528\u3002";
|
|
288
|
+
} else if (reason.includes("missing authorization code")) {
|
|
289
|
+
userMessage = "\u56DE\u8C03 URL \u4E2D\u7F3A\u5C11\u6388\u6743\u7801\u3002\u8BF7\u786E\u4FDD\u590D\u5236\u7684\u662F\u6388\u6743\u5B8C\u6210\u540E\u6D4F\u89C8\u5668\u5730\u5740\u680F\u7684\u5B8C\u6574 URL\u3002";
|
|
290
|
+
} else {
|
|
291
|
+
userMessage = "\u6388\u6743\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u6388\u6743\u3002";
|
|
292
|
+
}
|
|
281
293
|
return {
|
|
282
294
|
schema: "2.0",
|
|
283
295
|
config: {
|
|
@@ -311,7 +323,7 @@ function buildAuthFailedCard(_reason) {
|
|
|
311
323
|
elements: [
|
|
312
324
|
{
|
|
313
325
|
tag: "markdown",
|
|
314
|
-
content:
|
|
326
|
+
content: userMessage
|
|
315
327
|
}
|
|
316
328
|
]
|
|
317
329
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/oauth-cards.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * oauth-cards.ts \u2014 OAuth \u6388\u6743\u5361\u7247\u6784\u5EFA\u51FD\u6570\u3002\n *\n * \u4ECE oauth.ts \u63D0\u53D6\u7684\u7EAF UI \u51FD\u6570\uFF0C\u4E0E OAuth \u4E1A\u52A1\u6D41\u7A0B\u89E3\u8026\u3002\n */\n\n// ---------------------------------------------------------------------------\n// Card builders\n// ---------------------------------------------------------------------------\n\nexport function buildAuthCard(params: {\n verificationUriComplete: string;\n expiresMin: number;\n scope?: string;\n isBatchAuth?: boolean;\n totalAppScopes?: number;\n alreadyGranted?: number;\n batchInfo?: string;\n filteredScopes?: string[]; // \u88AB\u8FC7\u6EE4\u7684 scope\uFF08\u5E94\u7528\u672A\u5F00\u901A\uFF09\n appId?: string; // \u7528\u4E8E\u751F\u6210\u6743\u9650\u7BA1\u7406\u94FE\u63A5\n showBatchAuthHint?: boolean; // \u4EC5 auto-auth \u6D41\u7A0B\u5C55\u793A\u6279\u91CF\u6388\u6743\u63D0\u793A\n}): Record<string, unknown> {\n const {\n verificationUriComplete,\n expiresMin,\n scope,\n isBatchAuth,\n totalAppScopes,\n alreadyGranted,\n batchInfo,\n filteredScopes,\n appId,\n showBatchAuthHint,\n } = params;\n const inAppUrl = toInAppWebUrl(verificationUriComplete);\n const multiUrl = {\n url: inAppUrl,\n pc_url: inAppUrl,\n android_url: inAppUrl,\n ios_url: inAppUrl,\n };\n\n // \u5C06 scope \u8F6C\u6210\u53EF\u8BFB\u8BF4\u660E\n const scopeDesc = formatScopeDescription(\n scope,\n isBatchAuth,\n totalAppScopes,\n alreadyGranted,\n batchInfo,\n filteredScopes,\n appId,\n );\n\n const elements: Record<string, unknown>[] = [\n // \u6388\u6743\u8BF4\u660E\n {\n tag: 'markdown',\n content: scopeDesc,\n text_size: 'normal',\n },\n // \u6388\u6743\u6309\u94AE\uFF08small\uFF0C\u9760\u53F3\uFF09\n {\n tag: 'column_set',\n flex_mode: 'none',\n horizontal_align: 'right',\n columns: [\n {\n tag: 'column',\n width: 'auto',\n elements: [\n {\n tag: 'button',\n text: { tag: 'plain_text', content: '\u524D\u5F80\u6388\u6743' },\n type: 'primary',\n size: 'medium',\n multi_url: multiUrl,\n },\n ],\n },\n ],\n },\n // \u5931\u6548\u65F6\u95F4\u63D0\u9192\n {\n tag: 'markdown',\n content: `<font color='grey'>\u6388\u6743\u94FE\u63A5\u5C06\u5728 ${expiresMin} \u5206\u949F\u540E\u5931\u6548\uFF0C\u5C4A\u65F6\u9700\u91CD\u65B0\u53D1\u8D77</font>`,\n text_size: 'notation',\n },\n // \u6279\u91CF\u6388\u6743\u63D0\u793A\uFF08\u4EC5 auto-auth \u6D41\u7A0B\u5C55\u793A\uFF09\n ...(showBatchAuthHint\n ? [\n {\n tag: 'markdown',\n content:\n \"<font color='grey'>\uD83D\uDCA1\u5982\u679C\u4F60\u5E0C\u671B\u4E00\u6B21\u6027\u6388\u4E88\u6240\u6709\u63D2\u4EF6\u6240\u9700\u8981\u7684\u6743\u9650\uFF0C\u53EF\u4EE5\u544A\u8BC9\u6211\u300C\u6388\u4E88\u6240\u6709\u7528\u6237\u6743\u9650\u300D\uFF0C\u6211\u4F1A\u534F\u52A9\u4F60\u5B8C\u6210\u3002</font>\",\n text_size: 'notation',\n },\n ]\n : []),\n ];\n\n return {\n schema: '2.0',\n config: {\n wide_screen_mode: false,\n style: {\n color: {\n 'light-yellow-bg': {\n light_mode: 'rgba(255, 214, 102, 0.12)',\n dark_mode: 'rgba(255, 214, 102, 0.08)',\n },\n },\n },\n },\n header: {\n title: {\n tag: 'plain_text',\n content: '\u9700\u8981\u60A8\u7684\u6388\u6743\u624D\u80FD\u7EE7\u7EED',\n },\n subtitle: {\n tag: 'plain_text',\n content: '',\n },\n template: 'blue',\n padding: '12px 12px 12px 12px',\n icon: {\n tag: 'standard_icon',\n token: 'lock-chat_filled',\n },\n },\n body: { elements },\n };\n}\n\n/** scope \u5B57\u7B26\u4E32 \u2192 \u53EF\u8BFB\u63CF\u8FF0 */\nexport function formatScopeDescription(\n scope?: string,\n isBatchAuth?: boolean,\n totalAppScopes?: number,\n alreadyGranted?: number,\n batchInfo?: string,\n _filteredScopes?: string[],\n _appId?: string,\n): string {\n const scopes = scope?.split(/\\s+/).filter(Boolean);\n\n if (isBatchAuth && scopes && scopes.length > 0) {\n let message = `\u5E94\u7528\u9700\u8981\u6388\u6743 **${scopes.length}** \u4E2A\u7528\u6237\u6743\u9650\uFF08\u5171 ${totalAppScopes} \u4E2A\uFF0C\u5DF2\u6388\u6743 ${alreadyGranted} \u4E2A\uFF09\u3002`;\n\n // \u5982\u679C\u8D85\u8FC7 5 \u4E2A scope\uFF0C\u53EA\u663E\u793A\u524D 3 \u4E2A\uFF0C\u7136\u540E\u7528\"...\"\u8868\u793A\n if (scopes.length > 5) {\n const previewScopes = scopes.slice(0, 3).join('\\n');\n message += `\\n\\n**\u5C06\u8981\u6388\u6743\u7684\u6743\u9650**\uFF1A\\n${previewScopes}\\n...\\n`;\n } else {\n const scopeList = scopes.map((s, idx) => `${idx + 1}. ${s}`).join('\\n');\n message += `\\n\\n**\u5C06\u8981\u6388\u6743\u7684\u6743\u9650\u5217\u8868**\uFF1A\\n${scopeList}\\n`;\n }\n\n // \u6DFB\u52A0\u5206\u6279\u63D0\u793A\u4FE1\u606F\n if (batchInfo) {\n message += `\\n\\n${batchInfo}`;\n }\n\n return message;\n }\n\n const desc = '\u6388\u6743\u540E\uFF0C\u5E94\u7528\u5C06\u80FD\u591F\u4EE5\u60A8\u7684\u8EAB\u4EFD\u6267\u884C\u76F8\u5173\u64CD\u4F5C\u3002';\n if (!scopes?.length) return desc;\n\n const message = desc + '\\n\\n\u6240\u9700\u6743\u9650\uFF1A\\n' + scopes.map((s) => `- ${s}`).join('\\n');\n\n return message;\n}\n\nexport function toInAppWebUrl(targetUrl: string): string {\n const encoded = encodeURIComponent(targetUrl);\n const lkMeta = encodeURIComponent(\n JSON.stringify({\n 'page-meta': {\n showNavBar: 'false',\n showBottomNavBar: 'false',\n },\n }),\n );\n return (\n 'https://applink.feishu.cn/client/web_url/open' +\n `?mode=sidebar-semi&max_width=800&reload=false&url=${encoded}&lk_meta=${lkMeta}`\n );\n}\n\n/**\n * \u98DE\u4E66\u9879\u76EE OAuth \u4E13\u7528\u6388\u6743\u5361\u7247\u3002\n *\n * \u4E24\u6B65\u5F0F\uFF1A\u2460 \u524D\u5F80\u6388\u6743\u6309\u94AE \u2461 URL \u7C98\u8D34\u8F93\u5165\u6846 + \u63D0\u4EA4\u6309\u94AE\uFF08\u901A\u8FC7\u5361\u7247\u56DE\u8C03\u81EA\u52A8\u5B8C\u6210\uFF09\n */\nexport function buildProjectAuthCard(params: {\n authorizationUrl: string;\n expiresMin: number;\n}): Record<string, unknown> {\n const { authorizationUrl, expiresMin } = params;\n // \u4E0D\u4F7F\u7528 applink \u5305\u88C5\uFF1A\u670D\u52A1\u7AEF\u901A\u8FC7 redirect_mode=manual \u76F4\u63A5\u5C55\u793A\u590D\u5236\u9875\u9762\uFF0C\n // \u5728\u98DE\u4E66\u5185\u7F6E\u6D4F\u89C8\u5668\u4E2D\u5373\u53EF\u6B63\u5E38\u5B8C\u6210\uFF0C\u65E0\u9700\u8DF3\u8F6C\u7CFB\u7EDF\u6D4F\u89C8\u5668\u3002\n const multiUrl = {\n url: authorizationUrl,\n pc_url: authorizationUrl,\n android_url: authorizationUrl,\n ios_url: authorizationUrl,\n };\n\n return {\n schema: '2.0',\n config: { wide_screen_mode: false },\n header: {\n title: { tag: 'plain_text', content: '\u98DE\u4E66\u9879\u76EE\u9700\u8981\u60A8\u7684\u6388\u6743' },\n subtitle: { tag: 'plain_text', content: '' },\n template: 'blue',\n padding: '12px 12px 12px 12px',\n icon: { tag: 'standard_icon', token: 'lock-chat_filled' },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content: '\u6388\u6743\u540E\uFF0C\u5E94\u7528\u5C06\u80FD\u591F\u4EE5\u60A8\u7684\u8EAB\u4EFD\u6267\u884C\u98DE\u4E66\u9879\u76EE\u76F8\u5173\u64CD\u4F5C\u3002',\n text_size: 'normal',\n },\n // Step 1: navigate to auth page\n {\n tag: 'column_set',\n flex_mode: 'none',\n horizontal_spacing: 'default',\n columns: [\n {\n tag: 'column',\n width: 'weighted',\n weight: 3,\n vertical_align: 'center',\n elements: [{ tag: 'markdown', content: '**\u7B2C\u4E00\u6B65\uFF1A\u70B9\u51FB\u6309\u94AE\uFF0C\u5728\u6D4F\u89C8\u5668\u4E2D\u5B8C\u6210\u6388\u6743**' }],\n },\n {\n tag: 'column',\n width: 'weighted',\n weight: 1,\n vertical_align: 'center',\n elements: [{\n tag: 'button',\n text: { tag: 'plain_text', content: '\u524D\u5F80\u6388\u6743' },\n type: 'primary',\n size: 'medium',\n multi_url: multiUrl,\n }],\n },\n ],\n },\n { tag: 'hr' },\n // Step 2: paste callback URL\n {\n tag: 'markdown',\n content:\n '**\u7B2C\u4E8C\u6B65\uFF1A\u7C98\u8D34\u6D4F\u89C8\u5668\u5730\u5740\u680F URL**\\n' +\n \"<font color='grey'>\u6388\u6743\u540E\u6D4F\u89C8\u5668\u4F1A\u8DF3\u8F6C\u5230\u4E00\u4E2A\u65E0\u6CD5\u6253\u5F00\u7684\u9875\u9762\uFF0C\u8FD9\u662F\u6B63\u5E38\u7684\u2014\u2014\u8BF7\u590D\u5236\u5730\u5740\u680F\u4E2D\u7684\u5B8C\u6574 URL \u7C98\u8D34\u5230\u4E0B\u65B9</font>\",\n text_size: 'normal',\n },\n {\n tag: 'form',\n name: `project_auth_form`,\n elements: [\n {\n tag: 'input',\n name: 'callback_url',\n placeholder: {\n tag: 'plain_text',\n content: '\u7C98\u8D34 URL\uFF0C\u5982 http://127.0.0.1:3456/callback?code=...',\n },\n max_length: 1000,\n },\n {\n tag: 'button',\n text: { tag: 'plain_text', content: '\u5B8C\u6210\u6388\u6743' },\n type: 'primary',\n form_action_type: 'submit',\n name: 'submit_project_auth',\n },\n ],\n },\n {\n tag: 'markdown',\n content: `<font color='grey'>\u6388\u6743\u94FE\u63A5\u5C06\u5728 ${expiresMin} \u5206\u949F\u540E\u5931\u6548\uFF0C\u5C4A\u65F6\u9700\u91CD\u65B0\u53D1\u8D77</font>`,\n text_size: 'notation',\n },\n ],\n },\n };\n}\n\nexport function buildAuthSuccessCard(): Record<string, unknown> {\n return {\n schema: '2.0',\n config: {\n wide_screen_mode: false,\n style: {\n color: {\n 'light-green-bg': {\n light_mode: 'rgba(52, 199, 89, 0.12)',\n dark_mode: 'rgba(52, 199, 89, 0.08)',\n },\n },\n },\n },\n header: {\n title: {\n tag: 'plain_text',\n content: '\u6388\u6743\u6210\u529F',\n },\n subtitle: {\n tag: 'plain_text',\n content: '',\n },\n template: 'green',\n padding: '12px 12px 12px 12px',\n icon: {\n tag: 'standard_icon',\n token: 'yes_filled',\n },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content:\n '\u60A8\u7684\u98DE\u4E66\u8D26\u53F7\u5DF2\u6210\u529F\u6388\u6743\uFF0C\u6B63\u5728\u4E3A\u60A8\u7EE7\u7EED\u6267\u884C\u64CD\u4F5C\u3002\\n\\n' +\n \"<font color='grey'>\u5982\u9700\u64A4\u9500\u6388\u6743\uFF0C\u53EF\u968F\u65F6\u544A\u8BC9\u6211\u3002</font>\",\n },\n ],\n },\n };\n}\n\nexport function buildAuthFailedCard(_reason: string): Record<string, unknown> {\n return {\n schema: '2.0',\n config: {\n wide_screen_mode: false,\n style: {\n color: {\n 'light-grey-bg': {\n light_mode: 'rgba(142, 142, 147, 0.12)',\n dark_mode: 'rgba(142, 142, 147, 0.08)',\n },\n },\n },\n },\n header: {\n title: {\n tag: 'plain_text',\n content: '\u6388\u6743\u672A\u5B8C\u6210',\n },\n subtitle: {\n tag: 'plain_text',\n content: '',\n },\n template: 'yellow',\n padding: '12px 12px 12px 12px',\n icon: {\n tag: 'standard_icon',\n token: 'warning_filled',\n },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content: '\u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u6388\u6743\u3002',\n },\n ],\n },\n };\n}\n\n/**\n * \u98DE\u4E66\u9879\u76EE\u57DF\u540D\u9009\u62E9\u5361\u7247\u3002\n *\n * \u4E0B\u62C9\u9009\u62E9\u9884\u8BBE\u73AF\u5883 + \u53EF\u9009\u81EA\u5B9A\u4E49\u57DF\u540D\u8F93\u5165\u6846\uFF0C\u901A\u8FC7 form submit \u56DE\u8C03\u3002\n */\nexport function buildProjectDomainCard(): Record<string, unknown> {\n return {\n schema: '2.0',\n config: { wide_screen_mode: false },\n header: {\n title: { tag: 'plain_text', content: '\u9009\u62E9\u98DE\u4E66\u9879\u76EE\u73AF\u5883' },\n subtitle: { tag: 'plain_text', content: '' },\n template: 'blue',\n padding: '12px 12px 12px 12px',\n icon: { tag: 'standard_icon', token: 'settings_filled' },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content: '\u8BF7\u9009\u62E9\u60A8\u4F7F\u7528\u7684\u98DE\u4E66\u9879\u76EE\u73AF\u5883\uFF1A',\n text_size: 'normal',\n },\n {\n tag: 'form',\n name: 'project_domain_form',\n elements: [\n {\n tag: 'select_static',\n name: 'domain_preset',\n placeholder: { tag: 'plain_text', content: '\u9009\u62E9\u73AF\u5883' },\n options: [\n { value: 'feishu', text: { tag: 'plain_text', content: '\u98DE\u4E66\u9879\u76EE\uFF08project.feishu.cn\uFF09' } },\n { value: 'meegle', text: { tag: 'plain_text', content: 'Meegle\uFF08meegle.com\uFF09' } },\n ],\n value: { value: 'feishu', text: { tag: 'plain_text', content: '\u98DE\u4E66\u9879\u76EE\uFF08project.feishu.cn\uFF09' } },\n },\n {\n tag: 'markdown',\n content: \"\u5982\u4F7F\u7528\u79C1\u6709\u5316\u90E8\u7F72\uFF0C\u8BF7\u5728\u4E0B\u65B9\u586B\u5199\u5B8C\u6574\u57DF\u540D\uFF08\u5C06\u8986\u76D6\u4E0A\u65B9\u9009\u62E9\uFF09\uFF1A\",\n text_size: 'notation',\n },\n {\n tag: 'input',\n name: 'domain_custom',\n placeholder: { tag: 'plain_text', content: 'https://custom.example.com' },\n max_length: 200,\n },\n {\n tag: 'button',\n text: { tag: 'plain_text', content: '\u786E\u8BA4' },\n type: 'primary',\n form_action_type: 'submit',\n name: 'submit_project_domain',\n },\n ],\n },\n ],\n },\n };\n}\n\nexport function buildProjectDomainConfirmedCard(envLabel: string): Record<string, unknown> {\n return {\n schema: '2.0',\n config: { wide_screen_mode: false },\n header: {\n title: { tag: 'plain_text', content: '\u73AF\u5883\u5DF2\u786E\u8BA4' },\n subtitle: { tag: 'plain_text', content: '' },\n template: 'green',\n padding: '12px 12px 12px 12px',\n icon: { tag: 'standard_icon', token: 'yes_filled' },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content: `\u5DF2\u9009\u62E9\uFF1A**${envLabel}**\uFF0C\u6B63\u5728\u7EE7\u7EED\u6388\u6743...`,\n },\n ],\n },\n };\n}\n\nexport function buildAuthIdentityMismatchCard(): Record<string, unknown> {\n return {\n schema: '2.0',\n config: {\n wide_screen_mode: false,\n },\n header: {\n title: {\n tag: 'plain_text',\n content: '\u6388\u6743\u5931\u8D25\uFF0C\u64CD\u4F5C\u8D26\u53F7\u4E0E\u53D1\u8D77\u8D26\u53F7\u4E0D\u4E00\u81F4',\n },\n subtitle: {\n tag: 'plain_text',\n content: '',\n },\n template: 'red',\n padding: '12px 12px 12px 12px',\n icon: {\n tag: 'standard_icon',\n token: 'close_filled',\n },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content:\n '\u68C0\u6D4B\u5230\u5F53\u524D\u8FDB\u884C\u6388\u6743\u64CD\u4F5C\u7684\u98DE\u4E66\u8D26\u53F7\u4E0E\u53D1\u8D77\u6388\u6743\u8BF7\u6C42\u7684\u8D26\u53F7\u4E0D\u4E00\u81F4\u3002\u4E3A\u4FDD\u969C\u6570\u636E\u5B89\u5168\uFF0C\u672C\u6B21\u6388\u6743\u5DF2\u88AB\u62D2\u7EDD\u3002\\n\\n' +\n \"<font color='grey'>\u8BF7\u6388\u6743\u8BF7\u6C42\u7684\u53D1\u8D77\u4EBA\u4F7F\u7528\u5176\u8D26\u53F7\uFF0C\u70B9\u51FB\u6388\u6743\u94FE\u63A5\u5B8C\u6210\u6388\u6743\u3002</font>\",\n },\n ],\n },\n };\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * oauth-cards.ts \u2014 OAuth \u6388\u6743\u5361\u7247\u6784\u5EFA\u51FD\u6570\u3002\n *\n * \u4ECE oauth.ts \u63D0\u53D6\u7684\u7EAF UI \u51FD\u6570\uFF0C\u4E0E OAuth \u4E1A\u52A1\u6D41\u7A0B\u89E3\u8026\u3002\n */\n\n// ---------------------------------------------------------------------------\n// Card builders\n// ---------------------------------------------------------------------------\n\nexport function buildAuthCard(params: {\n verificationUriComplete: string;\n expiresMin: number;\n scope?: string;\n isBatchAuth?: boolean;\n totalAppScopes?: number;\n alreadyGranted?: number;\n batchInfo?: string;\n filteredScopes?: string[]; // \u88AB\u8FC7\u6EE4\u7684 scope\uFF08\u5E94\u7528\u672A\u5F00\u901A\uFF09\n appId?: string; // \u7528\u4E8E\u751F\u6210\u6743\u9650\u7BA1\u7406\u94FE\u63A5\n showBatchAuthHint?: boolean; // \u4EC5 auto-auth \u6D41\u7A0B\u5C55\u793A\u6279\u91CF\u6388\u6743\u63D0\u793A\n}): Record<string, unknown> {\n const {\n verificationUriComplete,\n expiresMin,\n scope,\n isBatchAuth,\n totalAppScopes,\n alreadyGranted,\n batchInfo,\n filteredScopes,\n appId,\n showBatchAuthHint,\n } = params;\n const inAppUrl = toInAppWebUrl(verificationUriComplete);\n const multiUrl = {\n url: inAppUrl,\n pc_url: inAppUrl,\n android_url: inAppUrl,\n ios_url: inAppUrl,\n };\n\n // \u5C06 scope \u8F6C\u6210\u53EF\u8BFB\u8BF4\u660E\n const scopeDesc = formatScopeDescription(\n scope,\n isBatchAuth,\n totalAppScopes,\n alreadyGranted,\n batchInfo,\n filteredScopes,\n appId,\n );\n\n const elements: Record<string, unknown>[] = [\n // \u6388\u6743\u8BF4\u660E\n {\n tag: 'markdown',\n content: scopeDesc,\n text_size: 'normal',\n },\n // \u6388\u6743\u6309\u94AE\uFF08small\uFF0C\u9760\u53F3\uFF09\n {\n tag: 'column_set',\n flex_mode: 'none',\n horizontal_align: 'right',\n columns: [\n {\n tag: 'column',\n width: 'auto',\n elements: [\n {\n tag: 'button',\n text: { tag: 'plain_text', content: '\u524D\u5F80\u6388\u6743' },\n type: 'primary',\n size: 'medium',\n multi_url: multiUrl,\n },\n ],\n },\n ],\n },\n // \u5931\u6548\u65F6\u95F4\u63D0\u9192\n {\n tag: 'markdown',\n content: `<font color='grey'>\u6388\u6743\u94FE\u63A5\u5C06\u5728 ${expiresMin} \u5206\u949F\u540E\u5931\u6548\uFF0C\u5C4A\u65F6\u9700\u91CD\u65B0\u53D1\u8D77</font>`,\n text_size: 'notation',\n },\n // \u6279\u91CF\u6388\u6743\u63D0\u793A\uFF08\u4EC5 auto-auth \u6D41\u7A0B\u5C55\u793A\uFF09\n ...(showBatchAuthHint\n ? [\n {\n tag: 'markdown',\n content:\n \"<font color='grey'>\uD83D\uDCA1\u5982\u679C\u4F60\u5E0C\u671B\u4E00\u6B21\u6027\u6388\u4E88\u6240\u6709\u63D2\u4EF6\u6240\u9700\u8981\u7684\u6743\u9650\uFF0C\u53EF\u4EE5\u544A\u8BC9\u6211\u300C\u6388\u4E88\u6240\u6709\u7528\u6237\u6743\u9650\u300D\uFF0C\u6211\u4F1A\u534F\u52A9\u4F60\u5B8C\u6210\u3002</font>\",\n text_size: 'notation',\n },\n ]\n : []),\n ];\n\n return {\n schema: '2.0',\n config: {\n wide_screen_mode: false,\n style: {\n color: {\n 'light-yellow-bg': {\n light_mode: 'rgba(255, 214, 102, 0.12)',\n dark_mode: 'rgba(255, 214, 102, 0.08)',\n },\n },\n },\n },\n header: {\n title: {\n tag: 'plain_text',\n content: '\u9700\u8981\u60A8\u7684\u6388\u6743\u624D\u80FD\u7EE7\u7EED',\n },\n subtitle: {\n tag: 'plain_text',\n content: '',\n },\n template: 'blue',\n padding: '12px 12px 12px 12px',\n icon: {\n tag: 'standard_icon',\n token: 'lock-chat_filled',\n },\n },\n body: { elements },\n };\n}\n\n/** scope \u5B57\u7B26\u4E32 \u2192 \u53EF\u8BFB\u63CF\u8FF0 */\nexport function formatScopeDescription(\n scope?: string,\n isBatchAuth?: boolean,\n totalAppScopes?: number,\n alreadyGranted?: number,\n batchInfo?: string,\n _filteredScopes?: string[],\n _appId?: string,\n): string {\n const scopes = scope?.split(/\\s+/).filter(Boolean);\n\n if (isBatchAuth && scopes && scopes.length > 0) {\n let message = `\u5E94\u7528\u9700\u8981\u6388\u6743 **${scopes.length}** \u4E2A\u7528\u6237\u6743\u9650\uFF08\u5171 ${totalAppScopes} \u4E2A\uFF0C\u5DF2\u6388\u6743 ${alreadyGranted} \u4E2A\uFF09\u3002`;\n\n // \u5982\u679C\u8D85\u8FC7 5 \u4E2A scope\uFF0C\u53EA\u663E\u793A\u524D 3 \u4E2A\uFF0C\u7136\u540E\u7528\"...\"\u8868\u793A\n if (scopes.length > 5) {\n const previewScopes = scopes.slice(0, 3).join('\\n');\n message += `\\n\\n**\u5C06\u8981\u6388\u6743\u7684\u6743\u9650**\uFF1A\\n${previewScopes}\\n...\\n`;\n } else {\n const scopeList = scopes.map((s, idx) => `${idx + 1}. ${s}`).join('\\n');\n message += `\\n\\n**\u5C06\u8981\u6388\u6743\u7684\u6743\u9650\u5217\u8868**\uFF1A\\n${scopeList}\\n`;\n }\n\n // \u6DFB\u52A0\u5206\u6279\u63D0\u793A\u4FE1\u606F\n if (batchInfo) {\n message += `\\n\\n${batchInfo}`;\n }\n\n return message;\n }\n\n const desc = '\u6388\u6743\u540E\uFF0C\u5E94\u7528\u5C06\u80FD\u591F\u4EE5\u60A8\u7684\u8EAB\u4EFD\u6267\u884C\u76F8\u5173\u64CD\u4F5C\u3002';\n if (!scopes?.length) return desc;\n\n const message = desc + '\\n\\n\u6240\u9700\u6743\u9650\uFF1A\\n' + scopes.map((s) => `- ${s}`).join('\\n');\n\n return message;\n}\n\nexport function toInAppWebUrl(targetUrl: string): string {\n const encoded = encodeURIComponent(targetUrl);\n const lkMeta = encodeURIComponent(\n JSON.stringify({\n 'page-meta': {\n showNavBar: 'false',\n showBottomNavBar: 'false',\n },\n }),\n );\n return (\n 'https://applink.feishu.cn/client/web_url/open' +\n `?mode=sidebar-semi&max_width=800&reload=false&url=${encoded}&lk_meta=${lkMeta}`\n );\n}\n\n/**\n * \u98DE\u4E66\u9879\u76EE OAuth \u4E13\u7528\u6388\u6743\u5361\u7247\u3002\n *\n * \u4E24\u6B65\u5F0F\uFF1A\u2460 \u524D\u5F80\u6388\u6743\u6309\u94AE \u2461 URL \u7C98\u8D34\u8F93\u5165\u6846 + \u63D0\u4EA4\u6309\u94AE\uFF08\u901A\u8FC7\u5361\u7247\u56DE\u8C03\u81EA\u52A8\u5B8C\u6210\uFF09\n */\nexport function buildProjectAuthCard(params: {\n authorizationUrl: string;\n expiresMin: number;\n}): Record<string, unknown> {\n const { authorizationUrl, expiresMin } = params;\n // \u4E0D\u4F7F\u7528 applink \u5305\u88C5\uFF1A\u670D\u52A1\u7AEF\u901A\u8FC7 redirect_mode=manual \u76F4\u63A5\u5C55\u793A\u590D\u5236\u9875\u9762\uFF0C\n // \u5728\u98DE\u4E66\u5185\u7F6E\u6D4F\u89C8\u5668\u4E2D\u5373\u53EF\u6B63\u5E38\u5B8C\u6210\uFF0C\u65E0\u9700\u8DF3\u8F6C\u7CFB\u7EDF\u6D4F\u89C8\u5668\u3002\n const multiUrl = {\n url: authorizationUrl,\n pc_url: authorizationUrl,\n android_url: authorizationUrl,\n ios_url: authorizationUrl,\n };\n\n return {\n schema: '2.0',\n config: { wide_screen_mode: false },\n header: {\n title: { tag: 'plain_text', content: '\u98DE\u4E66\u9879\u76EE\u9700\u8981\u60A8\u7684\u6388\u6743' },\n subtitle: { tag: 'plain_text', content: '' },\n template: 'blue',\n padding: '12px 12px 12px 12px',\n icon: { tag: 'standard_icon', token: 'lock-chat_filled' },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content: '\u6388\u6743\u540E\uFF0C\u5E94\u7528\u5C06\u80FD\u591F\u4EE5\u60A8\u7684\u8EAB\u4EFD\u6267\u884C\u98DE\u4E66\u9879\u76EE\u76F8\u5173\u64CD\u4F5C\u3002',\n text_size: 'normal',\n },\n // Step 1: navigate to auth page\n {\n tag: 'column_set',\n flex_mode: 'none',\n horizontal_spacing: 'default',\n columns: [\n {\n tag: 'column',\n width: 'weighted',\n weight: 3,\n vertical_align: 'center',\n elements: [{ tag: 'markdown', content: '**\u7B2C\u4E00\u6B65\uFF1A\u70B9\u51FB\u6309\u94AE\uFF0C\u5728\u6D4F\u89C8\u5668\u4E2D\u5B8C\u6210\u6388\u6743**' }],\n },\n {\n tag: 'column',\n width: 'weighted',\n weight: 1,\n vertical_align: 'center',\n elements: [{\n tag: 'button',\n text: { tag: 'plain_text', content: '\u524D\u5F80\u6388\u6743' },\n type: 'primary',\n size: 'medium',\n multi_url: multiUrl,\n }],\n },\n ],\n },\n { tag: 'hr' },\n // Step 2: paste callback URL\n {\n tag: 'markdown',\n content:\n '**\u7B2C\u4E8C\u6B65\uFF1A\u7C98\u8D34\u6D4F\u89C8\u5668\u5730\u5740\u680F URL**\\n' +\n \"<font color='grey'>\u6388\u6743\u540E\u6D4F\u89C8\u5668\u4F1A\u8DF3\u8F6C\u5230\u4E00\u4E2A\u65E0\u6CD5\u6253\u5F00\u7684\u9875\u9762\uFF0C\u8FD9\u662F\u6B63\u5E38\u7684\u2014\u2014\u8BF7\u590D\u5236\u5730\u5740\u680F\u4E2D\u7684\u5B8C\u6574 URL \u7C98\u8D34\u5230\u4E0B\u65B9</font>\",\n text_size: 'normal',\n },\n {\n tag: 'form',\n name: `project_auth_form`,\n elements: [\n {\n tag: 'input',\n name: 'callback_url',\n placeholder: {\n tag: 'plain_text',\n content: '\u7C98\u8D34 URL\uFF0C\u5982 http://127.0.0.1:3456/callback?code=...',\n },\n max_length: 1000,\n },\n {\n tag: 'button',\n text: { tag: 'plain_text', content: '\u5B8C\u6210\u6388\u6743' },\n type: 'primary',\n form_action_type: 'submit',\n name: 'submit_project_auth',\n },\n ],\n },\n {\n tag: 'markdown',\n content: `<font color='grey'>\u6388\u6743\u94FE\u63A5\u5C06\u5728 ${expiresMin} \u5206\u949F\u540E\u5931\u6548\uFF0C\u5C4A\u65F6\u9700\u91CD\u65B0\u53D1\u8D77</font>`,\n text_size: 'notation',\n },\n ],\n },\n };\n}\n\nexport function buildAuthSuccessCard(): Record<string, unknown> {\n return {\n schema: '2.0',\n config: {\n wide_screen_mode: false,\n style: {\n color: {\n 'light-green-bg': {\n light_mode: 'rgba(52, 199, 89, 0.12)',\n dark_mode: 'rgba(52, 199, 89, 0.08)',\n },\n },\n },\n },\n header: {\n title: {\n tag: 'plain_text',\n content: '\u6388\u6743\u6210\u529F',\n },\n subtitle: {\n tag: 'plain_text',\n content: '',\n },\n template: 'green',\n padding: '12px 12px 12px 12px',\n icon: {\n tag: 'standard_icon',\n token: 'yes_filled',\n },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content:\n '\u60A8\u7684\u98DE\u4E66\u8D26\u53F7\u5DF2\u6210\u529F\u6388\u6743\uFF0C\u6B63\u5728\u4E3A\u60A8\u7EE7\u7EED\u6267\u884C\u64CD\u4F5C\u3002\\n\\n' +\n \"<font color='grey'>\u5982\u9700\u64A4\u9500\u6388\u6743\uFF0C\u53EF\u968F\u65F6\u544A\u8BC9\u6211\u3002</font>\",\n },\n ],\n },\n };\n}\n\nexport function buildAuthFailedCard(reason: string): Record<string, unknown> {\n // \u5C06\u6280\u672F\u9519\u8BEF\u8F6C\u4E3A\u7528\u6237\u53EF\u8BFB\u7684\u63D0\u793A\n let userMessage: string;\n if (reason.includes('authorization denied') || reason.includes('access_denied')) {\n userMessage = '\u6388\u6743\u88AB\u62D2\u7EDD\u6216\u5DF2\u53D6\u6D88\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u6388\u6743\u5E76\u786E\u8BA4\u6388\u6743\u3002';\n } else if (reason.includes('state mismatch')) {\n userMessage = '\u6388\u6743\u4F1A\u8BDD\u4E0D\u5339\u914D\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u6388\u6743\u3002';\n } else if (reason.includes('Token exchange failed')) {\n userMessage = '\u6388\u6743\u7801\u4EA4\u6362\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u6388\u6743\u3002\u53EF\u80FD\u662F\u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F\u6216\u5DF2\u88AB\u4F7F\u7528\u3002';\n } else if (reason.includes('missing authorization code')) {\n userMessage = '\u56DE\u8C03 URL \u4E2D\u7F3A\u5C11\u6388\u6743\u7801\u3002\u8BF7\u786E\u4FDD\u590D\u5236\u7684\u662F\u6388\u6743\u5B8C\u6210\u540E\u6D4F\u89C8\u5668\u5730\u5740\u680F\u7684\u5B8C\u6574 URL\u3002';\n } else {\n userMessage = '\u6388\u6743\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u6388\u6743\u3002';\n }\n\n return {\n schema: '2.0',\n config: {\n wide_screen_mode: false,\n style: {\n color: {\n 'light-grey-bg': {\n light_mode: 'rgba(142, 142, 147, 0.12)',\n dark_mode: 'rgba(142, 142, 147, 0.08)',\n },\n },\n },\n },\n header: {\n title: {\n tag: 'plain_text',\n content: '\u6388\u6743\u672A\u5B8C\u6210',\n },\n subtitle: {\n tag: 'plain_text',\n content: '',\n },\n template: 'yellow',\n padding: '12px 12px 12px 12px',\n icon: {\n tag: 'standard_icon',\n token: 'warning_filled',\n },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content: userMessage,\n },\n ],\n },\n };\n}\n\n/**\n * \u98DE\u4E66\u9879\u76EE\u57DF\u540D\u9009\u62E9\u5361\u7247\u3002\n *\n * \u4E0B\u62C9\u9009\u62E9\u9884\u8BBE\u73AF\u5883 + \u53EF\u9009\u81EA\u5B9A\u4E49\u57DF\u540D\u8F93\u5165\u6846\uFF0C\u901A\u8FC7 form submit \u56DE\u8C03\u3002\n */\nexport function buildProjectDomainCard(): Record<string, unknown> {\n return {\n schema: '2.0',\n config: { wide_screen_mode: false },\n header: {\n title: { tag: 'plain_text', content: '\u9009\u62E9\u98DE\u4E66\u9879\u76EE\u73AF\u5883' },\n subtitle: { tag: 'plain_text', content: '' },\n template: 'blue',\n padding: '12px 12px 12px 12px',\n icon: { tag: 'standard_icon', token: 'settings_filled' },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content: '\u8BF7\u9009\u62E9\u60A8\u4F7F\u7528\u7684\u98DE\u4E66\u9879\u76EE\u73AF\u5883\uFF1A',\n text_size: 'normal',\n },\n {\n tag: 'form',\n name: 'project_domain_form',\n elements: [\n {\n tag: 'select_static',\n name: 'domain_preset',\n placeholder: { tag: 'plain_text', content: '\u9009\u62E9\u73AF\u5883' },\n options: [\n { value: 'feishu', text: { tag: 'plain_text', content: '\u98DE\u4E66\u9879\u76EE\uFF08project.feishu.cn\uFF09' } },\n { value: 'meegle', text: { tag: 'plain_text', content: 'Meegle\uFF08meegle.com\uFF09' } },\n ],\n value: { value: 'feishu', text: { tag: 'plain_text', content: '\u98DE\u4E66\u9879\u76EE\uFF08project.feishu.cn\uFF09' } },\n },\n {\n tag: 'markdown',\n content: \"\u5982\u4F7F\u7528\u79C1\u6709\u5316\u90E8\u7F72\uFF0C\u8BF7\u5728\u4E0B\u65B9\u586B\u5199\u5B8C\u6574\u57DF\u540D\uFF08\u5C06\u8986\u76D6\u4E0A\u65B9\u9009\u62E9\uFF09\uFF1A\",\n text_size: 'notation',\n },\n {\n tag: 'input',\n name: 'domain_custom',\n placeholder: { tag: 'plain_text', content: 'https://custom.example.com' },\n max_length: 200,\n },\n {\n tag: 'button',\n text: { tag: 'plain_text', content: '\u786E\u8BA4' },\n type: 'primary',\n form_action_type: 'submit',\n name: 'submit_project_domain',\n },\n ],\n },\n ],\n },\n };\n}\n\nexport function buildProjectDomainConfirmedCard(envLabel: string): Record<string, unknown> {\n return {\n schema: '2.0',\n config: { wide_screen_mode: false },\n header: {\n title: { tag: 'plain_text', content: '\u73AF\u5883\u5DF2\u786E\u8BA4' },\n subtitle: { tag: 'plain_text', content: '' },\n template: 'green',\n padding: '12px 12px 12px 12px',\n icon: { tag: 'standard_icon', token: 'yes_filled' },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content: `\u5DF2\u9009\u62E9\uFF1A**${envLabel}**\uFF0C\u6B63\u5728\u7EE7\u7EED\u6388\u6743...`,\n },\n ],\n },\n };\n}\n\nexport function buildAuthIdentityMismatchCard(): Record<string, unknown> {\n return {\n schema: '2.0',\n config: {\n wide_screen_mode: false,\n },\n header: {\n title: {\n tag: 'plain_text',\n content: '\u6388\u6743\u5931\u8D25\uFF0C\u64CD\u4F5C\u8D26\u53F7\u4E0E\u53D1\u8D77\u8D26\u53F7\u4E0D\u4E00\u81F4',\n },\n subtitle: {\n tag: 'plain_text',\n content: '',\n },\n template: 'red',\n padding: '12px 12px 12px 12px',\n icon: {\n tag: 'standard_icon',\n token: 'close_filled',\n },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content:\n '\u68C0\u6D4B\u5230\u5F53\u524D\u8FDB\u884C\u6388\u6743\u64CD\u4F5C\u7684\u98DE\u4E66\u8D26\u53F7\u4E0E\u53D1\u8D77\u6388\u6743\u8BF7\u6C42\u7684\u8D26\u53F7\u4E0D\u4E00\u81F4\u3002\u4E3A\u4FDD\u969C\u6570\u636E\u5B89\u5168\uFF0C\u672C\u6B21\u6388\u6743\u5DF2\u88AB\u62D2\u7EDD\u3002\\n\\n' +\n \"<font color='grey'>\u8BF7\u6388\u6743\u8BF7\u6C42\u7684\u53D1\u8D77\u4EBA\u4F7F\u7528\u5176\u8D26\u53F7\uFF0C\u70B9\u51FB\u6388\u6743\u94FE\u63A5\u5B8C\u6210\u6388\u6743\u3002</font>\",\n },\n ],\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["message"]
|
|
7
7
|
}
|
|
@@ -418,6 +418,28 @@ async function handleProjectAuthCardAction(data, cfg, accountId) {
|
|
|
418
418
|
toast: { type: "error", content: "\u8BF7\u4F7F\u7528\u53D1\u8D77\u6388\u6743\u7684\u8D26\u53F7\u5B8C\u6210\u64CD\u4F5C" }
|
|
419
419
|
};
|
|
420
420
|
}
|
|
421
|
+
try {
|
|
422
|
+
const testUrl = new URL(callbackUrl);
|
|
423
|
+
const hasError = testUrl.searchParams.get("error");
|
|
424
|
+
if (hasError) {
|
|
425
|
+
const desc = testUrl.searchParams.get("error_description") ?? hasError;
|
|
426
|
+
log.warn(`project card action: callback URL contains error: ${hasError} - ${desc}`);
|
|
427
|
+
return {
|
|
428
|
+
toast: { type: "error", content: `\u6388\u6743\u5931\u8D25\uFF1A${desc}\u3002\u8BF7\u91CD\u65B0\u53D1\u8D77\u6388\u6743\u3002` }
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
if (!testUrl.searchParams.get("code")) {
|
|
432
|
+
log.warn(`project card action: callback URL missing code param: ${callbackUrl}`);
|
|
433
|
+
return {
|
|
434
|
+
toast: { type: "error", content: "\u8BE5 URL \u4E2D\u7F3A\u5C11\u6388\u6743\u7801\uFF0C\u8BF7\u786E\u4FDD\u590D\u5236\u7684\u662F\u6388\u6743\u5B8C\u6210\u540E\u7684\u5B8C\u6574 URL" }
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
} catch {
|
|
438
|
+
log.warn(`project card action: invalid callback URL: ${callbackUrl}`);
|
|
439
|
+
return {
|
|
440
|
+
toast: { type: "error", content: "\u65E0\u6548\u7684 URL \u683C\u5F0F\uFF0C\u8BF7\u91CD\u65B0\u7C98\u8D34" }
|
|
441
|
+
};
|
|
442
|
+
}
|
|
421
443
|
pendingRemoteSessions.delete(userKey);
|
|
422
444
|
const capturedPending = pending;
|
|
423
445
|
const capturedCallbackUrl = callbackUrl;
|
|
@@ -455,7 +477,7 @@ async function handleProjectAuthCardAction(data, cfg, accountId) {
|
|
|
455
477
|
chat_id: t.chatId,
|
|
456
478
|
chat_type: t.chatType ?? "p2p",
|
|
457
479
|
message_type: "text",
|
|
458
|
-
content: JSON.stringify({ text: "\
|
|
480
|
+
content: JSON.stringify({ text: "[\u7CFB\u7EDF\u901A\u77E5] \u98DE\u4E66\u9879\u76EE\u6388\u6743\u5DF2\u6210\u529F\u5B8C\u6210\uFF0Ctoken \u5DF2\u4FDD\u5B58\u751F\u6548\u3002\u8BF7\u76F4\u63A5\u7EE7\u7EED\u6267\u884C\u7528\u6237\u4E4B\u524D\u8BF7\u6C42\u7684\u64CD\u4F5C\uFF0C\u65E0\u9700\u518D\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\uFF08\u4E0D\u8981 revoke\u3001\u4E0D\u8981 authorize\u3001\u4E0D\u8981 status\uFF09\u3002" }),
|
|
459
481
|
thread_id: t.threadId
|
|
460
482
|
}
|
|
461
483
|
};
|
|
@@ -496,13 +518,14 @@ async function handleProjectAuthCardAction(data, cfg, accountId) {
|
|
|
496
518
|
}
|
|
497
519
|
}
|
|
498
520
|
} catch (err) {
|
|
499
|
-
|
|
521
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
522
|
+
log.error(`project auth card callback failed: ${errMsg}`);
|
|
500
523
|
if (capturedPending.cardId) {
|
|
501
524
|
try {
|
|
502
525
|
await updateCardKitCardForAuth({
|
|
503
526
|
cfg,
|
|
504
527
|
cardId: capturedPending.cardId,
|
|
505
|
-
card: buildAuthFailedCard(
|
|
528
|
+
card: buildAuthFailedCard(errMsg),
|
|
506
529
|
sequence: 2,
|
|
507
530
|
accountId
|
|
508
531
|
});
|
|
@@ -510,6 +533,57 @@ async function handleProjectAuthCardAction(data, cfg, accountId) {
|
|
|
510
533
|
log.warn(`failed to update project auth card to failure: ${e}`);
|
|
511
534
|
}
|
|
512
535
|
}
|
|
536
|
+
const t = capturedPending.ticket;
|
|
537
|
+
if (t.chatId) {
|
|
538
|
+
try {
|
|
539
|
+
const syntheticMsgId = `${t.messageId}:project-auth-failed`;
|
|
540
|
+
const syntheticEvent = {
|
|
541
|
+
sender: { sender_id: { open_id: capturedPending.senderOpenId } },
|
|
542
|
+
message: {
|
|
543
|
+
message_id: syntheticMsgId,
|
|
544
|
+
chat_id: t.chatId,
|
|
545
|
+
chat_type: t.chatType ?? "p2p",
|
|
546
|
+
message_type: "text",
|
|
547
|
+
content: JSON.stringify({ text: `[\u7CFB\u7EDF\u901A\u77E5] \u98DE\u4E66\u9879\u76EE\u6388\u6743\u5931\u8D25\uFF1A${errMsg}\u3002\u8BF7\u544A\u77E5\u7528\u6237\u6388\u6743\u5931\u8D25\u539F\u56E0\uFF0C\u5E76\u5EFA\u8BAE\u7528\u6237\u91CD\u65B0\u53D1\u8D77\u6388\u6743\u3002` }),
|
|
548
|
+
thread_id: t.threadId
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
const syntheticRuntime = {
|
|
552
|
+
log: (msg) => log.info(msg),
|
|
553
|
+
error: (msg) => log.error(msg)
|
|
554
|
+
};
|
|
555
|
+
const { promise } = enqueueFeishuChatTask({
|
|
556
|
+
accountId: t.accountId,
|
|
557
|
+
chatId: t.chatId,
|
|
558
|
+
threadId: t.threadId,
|
|
559
|
+
task: async () => {
|
|
560
|
+
await withTicket(
|
|
561
|
+
{
|
|
562
|
+
messageId: syntheticMsgId,
|
|
563
|
+
chatId: t.chatId,
|
|
564
|
+
accountId: t.accountId,
|
|
565
|
+
startTime: Date.now(),
|
|
566
|
+
senderOpenId: capturedPending.senderOpenId,
|
|
567
|
+
chatType: t.chatType,
|
|
568
|
+
threadId: t.threadId
|
|
569
|
+
},
|
|
570
|
+
() => handleFeishuMessage({
|
|
571
|
+
cfg,
|
|
572
|
+
event: syntheticEvent,
|
|
573
|
+
accountId: t.accountId,
|
|
574
|
+
forceMention: true,
|
|
575
|
+
runtime: syntheticRuntime,
|
|
576
|
+
replyToMessageId: t.messageId
|
|
577
|
+
})
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
await promise;
|
|
582
|
+
log.info("synthetic failure message dispatched after project auth failure");
|
|
583
|
+
} catch (e) {
|
|
584
|
+
log.warn(`failed to send synthetic message after project auth failure: ${e}`);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
513
587
|
}
|
|
514
588
|
});
|
|
515
589
|
return {
|
|
@@ -538,10 +612,16 @@ async function handleProjectDomainCardAction(data, cfg, accountId) {
|
|
|
538
612
|
let domain;
|
|
539
613
|
let envLabel;
|
|
540
614
|
if (domainCustom) {
|
|
541
|
-
|
|
542
|
-
|
|
615
|
+
let parsed;
|
|
616
|
+
try {
|
|
617
|
+
parsed = new URL(domainCustom);
|
|
618
|
+
} catch {
|
|
619
|
+
return { toast: { type: "error", content: "\u65E0\u6548\u7684 URL\uFF0C\u8BF7\u8F93\u5165\u4EE5 https:// \u5F00\u5934\u7684\u57DF\u540D\u6216\u94FE\u63A5" } };
|
|
620
|
+
}
|
|
621
|
+
if (parsed.protocol !== "https:") {
|
|
622
|
+
return { toast: { type: "error", content: "\u4EC5\u652F\u6301 https \u534F\u8BAE" } };
|
|
543
623
|
}
|
|
544
|
-
domain =
|
|
624
|
+
domain = parsed.origin;
|
|
545
625
|
envLabel = domain;
|
|
546
626
|
} else {
|
|
547
627
|
domain = domainPreset ?? "feishu";
|
|
@@ -596,7 +676,7 @@ async function handleProjectDomainCardAction(data, cfg, accountId) {
|
|
|
596
676
|
chat_id: t.chatId,
|
|
597
677
|
chat_type: t.chatType ?? "p2p",
|
|
598
678
|
message_type: "text",
|
|
599
|
-
content: JSON.stringify({ text: "\u5DF2\u9009\u62E9\u98DE\u4E66\u9879\u76EE\u73AF\u5883\uFF0C\
|
|
679
|
+
content: JSON.stringify({ text: "[\u7CFB\u7EDF\u901A\u77E5] \u7528\u6237\u5DF2\u9009\u62E9\u98DE\u4E66\u9879\u76EE\u73AF\u5883\uFF0C\u914D\u7F6E\u5DF2\u4FDD\u5B58\u3002\u8BF7\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\u7684 authorize \u64CD\u4F5C\u7EE7\u7EED\u5B8C\u6210\u6388\u6743\u6D41\u7A0B\u3002" }),
|
|
600
680
|
thread_id: t.threadId
|
|
601
681
|
}
|
|
602
682
|
};
|