@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.
@@ -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
- const token = await getProjectStoredToken(clientId, senderOpenId);
65
- if (!token || projectTokenStatus(token) === "expired") {
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\u6216\u6388\u6743\u5DF2\u8FC7\u671F\u3002\u8BF7\u8C03\u7528 feishu_project_oauth \u5DE5\u5177\u7684 authorize \u64CD\u4F5C\u5B8C\u6210\u6388\u6743\u3002"
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(_reason) {
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: "\u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u6388\u6743\u3002"
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: "\u6211\u5DF2\u5B8C\u6210\u98DE\u4E66\u9879\u76EE\u6388\u6743\uFF0C\u8BF7\u7EE7\u7EED\u6267\u884C\u4E4B\u524D\u7684\u64CD\u4F5C\u3002" }),
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
- log.error(`project auth card callback failed: ${err}`);
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(err instanceof Error ? err.message : String(err)),
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
- if (!domainCustom.startsWith("https://")) {
542
- return { toast: { type: "error", content: "\u81EA\u5B9A\u4E49\u57DF\u540D\u5FC5\u987B\u4EE5 https:// \u5F00\u5934" } };
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 = domainCustom.replace(/\/+$/, "");
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\u8BF7\u7EE7\u7EED\u6267\u884C\u4E4B\u524D\u7684\u64CD\u4F5C\u3002" }),
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
  };