@lark-project/openclaw-lark-project 2026.3.170 → 2026.3.172

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -67,7 +67,7 @@ import { parseMessageEvent } from "./src/messaging/inbound/parse.js";
67
67
  import { checkMessageGate } from "./src/messaging/inbound/gate.js";
68
68
  import { isMessageExpired } from "./src/messaging/inbound/dedup.js";
69
69
  const plugin = {
70
- id: "feishu-openclaw-plugin",
70
+ id: "openclaw-lark-project",
71
71
  name: "Feishu",
72
72
  description: "Lark/Feishu channel plugin with im/doc/wiki/drive/task/calendar tools",
73
73
  configSchema: emptyPluginConfigSchema(),
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../index.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * OpenClaw Lark/Feishu plugin entry point.\n *\n * Registers the Feishu channel and all tool families:\n * doc, wiki, drive, perm, bitable, task, calendar.\n */\n\nimport type { OpenClawPluginApi } from 'openclaw/plugin-sdk';\nimport { emptyPluginConfigSchema } from 'openclaw/plugin-sdk';\nimport { feishuPlugin } from './src/channel/plugin';\nimport { LarkClient } from './src/core/lark-client';\nimport { registerOapiTools } from './src/tools/oapi/index';\nimport { registerFeishuMcpDocTools } from './src/tools/mcp/doc/index';\nimport { registerFeishuMcpProjectTools } from './src/tools/mcp/project/index';\nimport { registerFeishuOAuthTool } from './src/tools/oauth';\nimport { registerFeishuOAuthBatchAuthTool } from './src/tools/oauth-batch-auth';\nimport { registerFeishuProjectOAuthTool } from './src/tools/project-oauth';\nimport {\n runDiagnosis,\n formatDiagReportCli,\n traceByMessageId,\n formatTraceOutput,\n analyzeTrace,\n} from './src/commands/diagnose';\nimport { registerCommands } from './src/commands/index';\nimport { larkLogger } from './src/core/lark-logger';\nimport { emitSecurityWarnings } from './src/core/security-check';\n\nconst log = larkLogger('plugin');\n\n// ---------------------------------------------------------------------------\n// Re-exports for external consumers\n// ---------------------------------------------------------------------------\n\nexport { monitorFeishuProvider } from './src/channel/monitor';\nexport { sendMessageFeishu, sendCardFeishu, updateCardFeishu, editMessageFeishu } from './src/messaging/outbound/send';\nexport { getMessageFeishu } from './src/messaging/outbound/fetch';\nexport {\n uploadImageLark,\n uploadFileLark,\n sendImageLark,\n sendFileLark,\n sendAudioLark,\n uploadAndSendMediaLark,\n} from './src/messaging/outbound/media';\nexport {\n sendTextLark,\n sendCardLark,\n sendMediaLark,\n type SendTextLarkParams,\n type SendCardLarkParams,\n type SendMediaLarkParams,\n} from './src/messaging/outbound/deliver';\nexport { type FeishuChannelData } from './src/messaging/outbound/outbound';\nexport { probeFeishu } from './src/channel/probe';\nexport {\n addReactionFeishu,\n removeReactionFeishu,\n listReactionsFeishu,\n FeishuEmoji,\n VALID_FEISHU_EMOJI_TYPES,\n} from './src/messaging/outbound/reactions';\nexport { forwardMessageFeishu } from './src/messaging/outbound/forward';\nexport {\n updateChatFeishu,\n addChatMembersFeishu,\n removeChatMembersFeishu,\n listChatMembersFeishu,\n} from './src/messaging/outbound/chat-manage';\nexport { feishuMessageActions } from './src/messaging/outbound/actions';\nexport {\n mentionedBot,\n nonBotMentions,\n extractMessageBody,\n formatMentionForText,\n formatMentionForCard,\n formatMentionAllForText,\n formatMentionAllForCard,\n buildMentionedMessage,\n buildMentionedCardContent,\n type MentionInfo,\n} from './src/messaging/inbound/mention';\nexport { feishuPlugin } from './src/channel/plugin';\nexport type {\n MessageContext,\n RawMessage,\n RawSender,\n FeishuMessageContext,\n FeishuReactionCreatedEvent,\n} from './src/messaging/types';\nexport { handleFeishuReaction } from './src/messaging/inbound/reaction-handler';\nexport { parseMessageEvent } from './src/messaging/inbound/parse';\nexport { checkMessageGate } from './src/messaging/inbound/gate';\nexport { isMessageExpired } from './src/messaging/inbound/dedup';\n\n// ---------------------------------------------------------------------------\n// Plugin definition\n// ---------------------------------------------------------------------------\n\nconst plugin = {\n id: 'feishu-openclaw-plugin',\n name: 'Feishu',\n description: 'Lark/Feishu channel plugin with im/doc/wiki/drive/task/calendar tools',\n configSchema: emptyPluginConfigSchema(),\n register(api: OpenClawPluginApi) {\n LarkClient.setRuntime(api.runtime);\n api.registerChannel({ plugin: feishuPlugin });\n\n // ========================================\n\n // Register OAPI tools (calendar, task - using Feishu Open API directly)\n registerOapiTools(api);\n\n // Register MCP doc tools (using Model Context Protocol)\n registerFeishuMcpDocTools(api);\n\n // Register MCP project tools (Meego - using independent OAuth)\n registerFeishuMcpProjectTools(api);\n\n // Register OAuth tool (UAT device flow authorization)\n registerFeishuOAuthTool(api);\n\n // Register OAuth batch auth tool (batch authorization for all app scopes)\n registerFeishuOAuthBatchAuthTool(api);\n\n // Register Feishu Project OAuth tool (independent OAuth for Meego)\n registerFeishuProjectOAuthTool(api);\n\n // ---- Tool call hooks (auto-trace AI tool invocations) ----\n\n api.on('before_tool_call', (event) => {\n log.info(`tool call: ${event.toolName} params=${JSON.stringify(event.params)}`);\n });\n\n api.on('after_tool_call', (event) => {\n if (event.error) {\n log.error(`tool fail: ${event.toolName} ${event.error} (${event.durationMs ?? 0}ms)`);\n } else {\n log.info(`tool done: ${event.toolName} ok (${event.durationMs ?? 0}ms)`);\n }\n });\n\n // ---- Diagnostic commands ----\n\n // CLI: openclaw feishu-diagnose [--trace <messageId>]\n api.registerCli(\n (ctx) => {\n ctx.program\n .command('feishu-diagnose')\n .description('\u8FD0\u884C\u98DE\u4E66\u63D2\u4EF6\u8BCA\u65AD\uFF0C\u68C0\u67E5\u914D\u7F6E\u3001\u8FDE\u901A\u6027\u548C\u6743\u9650\u72B6\u6001')\n .option('--trace <messageId>', '\u6309 message_id \u8FFD\u8E2A\u5B8C\u6574\u5904\u7406\u94FE\u8DEF')\n .option('--analyze', '\u5206\u6790\u8FFD\u8E2A\u65E5\u5FD7\uFF08\u9700\u914D\u5408 --trace \u4F7F\u7528\uFF09')\n .action(async (opts: { trace?: string; analyze?: boolean }) => {\n try {\n if (opts.trace) {\n const lines = await traceByMessageId(opts.trace);\n // eslint-disable-next-line no-console -- CLI \u547D\u4EE4\u76F4\u63A5\u8F93\u51FA\u5230\u7EC8\u7AEF\n console.log(formatTraceOutput(lines, opts.trace));\n if (opts.analyze && lines.length > 0) {\n // eslint-disable-next-line no-console -- CLI \u547D\u4EE4\u76F4\u63A5\u8F93\u51FA\u5230\u7EC8\u7AEF\n console.log(analyzeTrace(lines, opts.trace));\n }\n } else {\n const report = await runDiagnosis({\n config: ctx.config,\n logger: ctx.logger,\n });\n // eslint-disable-next-line no-console -- CLI \u547D\u4EE4\u76F4\u63A5\u8F93\u51FA\u5230\u7EC8\u7AEF\n console.log(formatDiagReportCli(report));\n if (report.overallStatus === 'unhealthy') {\n process.exitCode = 1;\n }\n }\n } catch (err) {\n ctx.logger.error(`\u8BCA\u65AD\u547D\u4EE4\u6267\u884C\u5931\u8D25: ${err}`);\n process.exitCode = 1;\n }\n });\n },\n { commands: ['feishu-diagnose'] },\n );\n\n // Chat commands: /feishu_diagnose, /feishu_doctor, /feishu_auth, /feishu\n registerCommands(api);\n\n // ---- Multi-account security checks ----\n if (api.config) {\n emitSecurityWarnings(api.config, api.logger);\n }\n },\n};\n\nexport default plugin;\n"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * OpenClaw Lark/Feishu plugin entry point.\n *\n * Registers the Feishu channel and all tool families:\n * doc, wiki, drive, perm, bitable, task, calendar.\n */\n\nimport type { OpenClawPluginApi } from 'openclaw/plugin-sdk';\nimport { emptyPluginConfigSchema } from 'openclaw/plugin-sdk';\nimport { feishuPlugin } from './src/channel/plugin';\nimport { LarkClient } from './src/core/lark-client';\nimport { registerOapiTools } from './src/tools/oapi/index';\nimport { registerFeishuMcpDocTools } from './src/tools/mcp/doc/index';\nimport { registerFeishuMcpProjectTools } from './src/tools/mcp/project/index';\nimport { registerFeishuOAuthTool } from './src/tools/oauth';\nimport { registerFeishuOAuthBatchAuthTool } from './src/tools/oauth-batch-auth';\nimport { registerFeishuProjectOAuthTool } from './src/tools/project-oauth';\nimport {\n runDiagnosis,\n formatDiagReportCli,\n traceByMessageId,\n formatTraceOutput,\n analyzeTrace,\n} from './src/commands/diagnose';\nimport { registerCommands } from './src/commands/index';\nimport { larkLogger } from './src/core/lark-logger';\nimport { emitSecurityWarnings } from './src/core/security-check';\n\nconst log = larkLogger('plugin');\n\n// ---------------------------------------------------------------------------\n// Re-exports for external consumers\n// ---------------------------------------------------------------------------\n\nexport { monitorFeishuProvider } from './src/channel/monitor';\nexport { sendMessageFeishu, sendCardFeishu, updateCardFeishu, editMessageFeishu } from './src/messaging/outbound/send';\nexport { getMessageFeishu } from './src/messaging/outbound/fetch';\nexport {\n uploadImageLark,\n uploadFileLark,\n sendImageLark,\n sendFileLark,\n sendAudioLark,\n uploadAndSendMediaLark,\n} from './src/messaging/outbound/media';\nexport {\n sendTextLark,\n sendCardLark,\n sendMediaLark,\n type SendTextLarkParams,\n type SendCardLarkParams,\n type SendMediaLarkParams,\n} from './src/messaging/outbound/deliver';\nexport { type FeishuChannelData } from './src/messaging/outbound/outbound';\nexport { probeFeishu } from './src/channel/probe';\nexport {\n addReactionFeishu,\n removeReactionFeishu,\n listReactionsFeishu,\n FeishuEmoji,\n VALID_FEISHU_EMOJI_TYPES,\n} from './src/messaging/outbound/reactions';\nexport { forwardMessageFeishu } from './src/messaging/outbound/forward';\nexport {\n updateChatFeishu,\n addChatMembersFeishu,\n removeChatMembersFeishu,\n listChatMembersFeishu,\n} from './src/messaging/outbound/chat-manage';\nexport { feishuMessageActions } from './src/messaging/outbound/actions';\nexport {\n mentionedBot,\n nonBotMentions,\n extractMessageBody,\n formatMentionForText,\n formatMentionForCard,\n formatMentionAllForText,\n formatMentionAllForCard,\n buildMentionedMessage,\n buildMentionedCardContent,\n type MentionInfo,\n} from './src/messaging/inbound/mention';\nexport { feishuPlugin } from './src/channel/plugin';\nexport type {\n MessageContext,\n RawMessage,\n RawSender,\n FeishuMessageContext,\n FeishuReactionCreatedEvent,\n} from './src/messaging/types';\nexport { handleFeishuReaction } from './src/messaging/inbound/reaction-handler';\nexport { parseMessageEvent } from './src/messaging/inbound/parse';\nexport { checkMessageGate } from './src/messaging/inbound/gate';\nexport { isMessageExpired } from './src/messaging/inbound/dedup';\n\n// ---------------------------------------------------------------------------\n// Plugin definition\n// ---------------------------------------------------------------------------\n\nconst plugin = {\n id: 'openclaw-lark-project',\n name: 'Feishu',\n description: 'Lark/Feishu channel plugin with im/doc/wiki/drive/task/calendar tools',\n configSchema: emptyPluginConfigSchema(),\n register(api: OpenClawPluginApi) {\n LarkClient.setRuntime(api.runtime);\n api.registerChannel({ plugin: feishuPlugin });\n\n // ========================================\n\n // Register OAPI tools (calendar, task - using Feishu Open API directly)\n registerOapiTools(api);\n\n // Register MCP doc tools (using Model Context Protocol)\n registerFeishuMcpDocTools(api);\n\n // Register MCP project tools (Meego - using independent OAuth)\n registerFeishuMcpProjectTools(api);\n\n // Register OAuth tool (UAT device flow authorization)\n registerFeishuOAuthTool(api);\n\n // Register OAuth batch auth tool (batch authorization for all app scopes)\n registerFeishuOAuthBatchAuthTool(api);\n\n // Register Feishu Project OAuth tool (independent OAuth for Meego)\n registerFeishuProjectOAuthTool(api);\n\n // ---- Tool call hooks (auto-trace AI tool invocations) ----\n\n api.on('before_tool_call', (event) => {\n log.info(`tool call: ${event.toolName} params=${JSON.stringify(event.params)}`);\n });\n\n api.on('after_tool_call', (event) => {\n if (event.error) {\n log.error(`tool fail: ${event.toolName} ${event.error} (${event.durationMs ?? 0}ms)`);\n } else {\n log.info(`tool done: ${event.toolName} ok (${event.durationMs ?? 0}ms)`);\n }\n });\n\n // ---- Diagnostic commands ----\n\n // CLI: openclaw feishu-diagnose [--trace <messageId>]\n api.registerCli(\n (ctx) => {\n ctx.program\n .command('feishu-diagnose')\n .description('\u8FD0\u884C\u98DE\u4E66\u63D2\u4EF6\u8BCA\u65AD\uFF0C\u68C0\u67E5\u914D\u7F6E\u3001\u8FDE\u901A\u6027\u548C\u6743\u9650\u72B6\u6001')\n .option('--trace <messageId>', '\u6309 message_id \u8FFD\u8E2A\u5B8C\u6574\u5904\u7406\u94FE\u8DEF')\n .option('--analyze', '\u5206\u6790\u8FFD\u8E2A\u65E5\u5FD7\uFF08\u9700\u914D\u5408 --trace \u4F7F\u7528\uFF09')\n .action(async (opts: { trace?: string; analyze?: boolean }) => {\n try {\n if (opts.trace) {\n const lines = await traceByMessageId(opts.trace);\n // eslint-disable-next-line no-console -- CLI \u547D\u4EE4\u76F4\u63A5\u8F93\u51FA\u5230\u7EC8\u7AEF\n console.log(formatTraceOutput(lines, opts.trace));\n if (opts.analyze && lines.length > 0) {\n // eslint-disable-next-line no-console -- CLI \u547D\u4EE4\u76F4\u63A5\u8F93\u51FA\u5230\u7EC8\u7AEF\n console.log(analyzeTrace(lines, opts.trace));\n }\n } else {\n const report = await runDiagnosis({\n config: ctx.config,\n logger: ctx.logger,\n });\n // eslint-disable-next-line no-console -- CLI \u547D\u4EE4\u76F4\u63A5\u8F93\u51FA\u5230\u7EC8\u7AEF\n console.log(formatDiagReportCli(report));\n if (report.overallStatus === 'unhealthy') {\n process.exitCode = 1;\n }\n }\n } catch (err) {\n ctx.logger.error(`\u8BCA\u65AD\u547D\u4EE4\u6267\u884C\u5931\u8D25: ${err}`);\n process.exitCode = 1;\n }\n });\n },\n { commands: ['feishu-diagnose'] },\n );\n\n // Chat commands: /feishu_diagnose, /feishu_doctor, /feishu_auth, /feishu\n registerCommands(api);\n\n // ---- Multi-account security checks ----\n if (api.config) {\n emitSecurityWarnings(api.config, api.logger);\n }\n },\n};\n\nexport default plugin;\n"],
5
5
  "mappings": "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",
6
6
  "names": ["feishuPlugin"]
7
7
  }
@@ -18,7 +18,7 @@ function getPluginVersion() {
18
18
  }
19
19
  }
20
20
  function getUserAgent() {
21
- return `feishu-openclaw-plugin/${getPluginVersion()}`;
21
+ return `openclaw-lark-project/${getPluginVersion()}`;
22
22
  }
23
23
  export {
24
24
  getPluginVersion,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/core/version.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * \u63D2\u4EF6\u7248\u672C\u53F7\u7BA1\u7406\n *\n * \u4ECE package.json \u8BFB\u53D6\u7248\u672C\u53F7\u5E76\u751F\u6210 User-Agent \u5B57\u7B26\u4E32\u3002\n */\n\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { readFileSync } from 'node:fs';\n\n/** \u7F13\u5B58\u7684\u7248\u672C\u53F7 */\nlet cachedVersion: string | undefined;\n\n/**\n * \u83B7\u53D6\u63D2\u4EF6\u7248\u672C\u53F7\uFF08\u4ECE package.json \u8BFB\u53D6\uFF09\n *\n * @returns \u7248\u672C\u53F7\u5B57\u7B26\u4E32\uFF0C\u5982 \"2026.2.28.5\"\uFF1B\u8BFB\u53D6\u5931\u8D25\u8FD4\u56DE \"unknown\"\n */\nexport function getPluginVersion(): string {\n if (cachedVersion) return cachedVersion;\n\n try {\n // \u5F53\u524D\u6587\u4EF6: src/core/version.ts \u2192 \u5411\u4E0A\u4E24\u7EA7\u5230\u8FBE\u9879\u76EE\u6839\u76EE\u5F55\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const packageJsonPath = join(__dirname, '..', '..', 'package.json');\n\n const raw = readFileSync(packageJsonPath, 'utf8');\n const pkg = JSON.parse(raw) as { version?: string };\n cachedVersion = pkg.version ?? 'unknown';\n return cachedVersion;\n } catch {\n cachedVersion = 'unknown';\n return cachedVersion;\n }\n}\n\n/**\n * \u751F\u6210 User-Agent \u5B57\u7B26\u4E32\n *\n * @returns User-Agent \u5B57\u7B26\u4E32\uFF0C\u683C\u5F0F\uFF1A`feishu-openclaw-plugin/{version}`\n *\n * @example\n * ```typescript\n * getUserAgent() // => \"feishu-openclaw-plugin/2026.2.28.5\"\n * ```\n */\nexport function getUserAgent(): string {\n return `feishu-openclaw-plugin/${getPluginVersion()}`;\n}\n"],
5
- "mappings": "AASA,SAAS,qBAAqB;AAC9B,SAAS,SAAS,YAAY;AAC9B,SAAS,oBAAoB;AAG7B,IAAI;AAOG,SAAS,mBAA2B;AACzC,MAAI,cAAe,QAAO;AAE1B,MAAI;AAEF,UAAM,aAAa,cAAc,YAAY,GAAG;AAChD,UAAM,YAAY,QAAQ,UAAU;AACpC,UAAM,kBAAkB,KAAK,WAAW,MAAM,MAAM,cAAc;AAElE,UAAM,MAAM,aAAa,iBAAiB,MAAM;AAChD,UAAM,MAAM,KAAK,MAAM,GAAG;AAC1B,oBAAgB,IAAI,WAAW;AAC/B,WAAO;AAAA,EACT,QAAQ;AACN,oBAAgB;AAChB,WAAO;AAAA,EACT;AACF;AAYO,SAAS,eAAuB;AACrC,SAAO,0BAA0B,iBAAiB,CAAC;AACrD;",
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * \u63D2\u4EF6\u7248\u672C\u53F7\u7BA1\u7406\n *\n * \u4ECE package.json \u8BFB\u53D6\u7248\u672C\u53F7\u5E76\u751F\u6210 User-Agent \u5B57\u7B26\u4E32\u3002\n */\n\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { readFileSync } from 'node:fs';\n\n/** \u7F13\u5B58\u7684\u7248\u672C\u53F7 */\nlet cachedVersion: string | undefined;\n\n/**\n * \u83B7\u53D6\u63D2\u4EF6\u7248\u672C\u53F7\uFF08\u4ECE package.json \u8BFB\u53D6\uFF09\n *\n * @returns \u7248\u672C\u53F7\u5B57\u7B26\u4E32\uFF0C\u5982 \"2026.2.28.5\"\uFF1B\u8BFB\u53D6\u5931\u8D25\u8FD4\u56DE \"unknown\"\n */\nexport function getPluginVersion(): string {\n if (cachedVersion) return cachedVersion;\n\n try {\n // \u5F53\u524D\u6587\u4EF6: src/core/version.ts \u2192 \u5411\u4E0A\u4E24\u7EA7\u5230\u8FBE\u9879\u76EE\u6839\u76EE\u5F55\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const packageJsonPath = join(__dirname, '..', '..', 'package.json');\n\n const raw = readFileSync(packageJsonPath, 'utf8');\n const pkg = JSON.parse(raw) as { version?: string };\n cachedVersion = pkg.version ?? 'unknown';\n return cachedVersion;\n } catch {\n cachedVersion = 'unknown';\n return cachedVersion;\n }\n}\n\n/**\n * \u751F\u6210 User-Agent \u5B57\u7B26\u4E32\n *\n * @returns User-Agent \u5B57\u7B26\u4E32\uFF0C\u683C\u5F0F\uFF1A`openclaw-lark-project/{version}`\n *\n * @example\n * ```typescript\n * getUserAgent() // => \"openclaw-lark-project/2026.2.28.5\"\n * ```\n */\nexport function getUserAgent(): string {\n return `openclaw-lark-project/${getPluginVersion()}`;\n}\n"],
5
+ "mappings": "AASA,SAAS,qBAAqB;AAC9B,SAAS,SAAS,YAAY;AAC9B,SAAS,oBAAoB;AAG7B,IAAI;AAOG,SAAS,mBAA2B;AACzC,MAAI,cAAe,QAAO;AAE1B,MAAI;AAEF,UAAM,aAAa,cAAc,YAAY,GAAG;AAChD,UAAM,YAAY,QAAQ,UAAU;AACpC,UAAM,kBAAkB,KAAK,WAAW,MAAM,MAAM,cAAc;AAElE,UAAM,MAAM,aAAa,iBAAiB,MAAM;AAChD,UAAM,MAAM,KAAK,MAAM,GAAG;AAC1B,oBAAgB,IAAI,WAAW;AAC/B,WAAO;AAAA,EACT,QAAQ;AACN,oBAAgB;AAChB,WAAO;AAAA,EACT;AACF;AAYO,SAAS,eAAuB;AACrC,SAAO,yBAAyB,iBAAiB,CAAC;AACpD;",
6
6
  "names": []
7
7
  }
@@ -2,6 +2,7 @@ import { getEnabledLarkAccounts } from "../../../core/accounts.js";
2
2
  import { resolveAnyEnabledToolsConfig } from "../../../core/tools-config.js";
3
3
  import { getProjectMcpEndpoint } from "./endpoint.js";
4
4
  import { registerProjectTools } from "./tools.js";
5
+ import { LarkClient } from "../../../core/lark-client.js";
5
6
  function registerFeishuMcpProjectTools(api) {
6
7
  if (!api.config) {
7
8
  api.logger.debug?.("feishu_project: No config available, skipping");
@@ -17,7 +18,13 @@ function registerFeishuMcpProjectTools(api) {
17
18
  api.logger.debug?.("feishu_project: project tool disabled in all accounts");
18
19
  return;
19
20
  }
20
- const endpoint = getProjectMcpEndpoint(api.config);
21
+ const endpoint = () => {
22
+ try {
23
+ return getProjectMcpEndpoint(LarkClient.runtime.config.loadConfig());
24
+ } catch {
25
+ return getProjectMcpEndpoint(api.config);
26
+ }
27
+ };
21
28
  registerProjectTools(api, endpoint);
22
29
  api.logger.info?.("feishu_project: Registered project MCP tools");
23
30
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/tools/mcp/project/index.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * \u98DE\u4E66\u9879\u76EE\uFF08Meego\uFF09MCP \u5DE5\u5177\u6CE8\u518C\u5165\u53E3\n *\n * \u4E0E doc \u5DE5\u5177\u4E0D\u540C\uFF0C\u98DE\u4E66\u9879\u76EE\u5DE5\u5177\u4F7F\u7528\u72EC\u7ACB\u7684 MCP \u7AEF\u70B9\u548C\u72EC\u7ACB\u7684 OAuth token\u3002\n */\n\nimport type { OpenClawPluginApi } from 'openclaw/plugin-sdk';\nimport { getEnabledLarkAccounts } from '../../../core/accounts';\nimport { resolveAnyEnabledToolsConfig } from '../../../core/tools-config';\nimport { getProjectMcpEndpoint } from './endpoint';\nimport { registerProjectTools } from './tools';\n\nexport function registerFeishuMcpProjectTools(api: OpenClawPluginApi) {\n if (!api.config) {\n api.logger.debug?.('feishu_project: No config available, skipping');\n return;\n }\n\n const accounts = getEnabledLarkAccounts(api.config);\n if (accounts.length === 0) {\n api.logger.debug?.('feishu_project: No Feishu accounts configured, skipping');\n return;\n }\n\n const toolsCfg = resolveAnyEnabledToolsConfig(accounts);\n if (!toolsCfg.project) {\n api.logger.debug?.('feishu_project: project tool disabled in all accounts');\n return;\n }\n\n const endpoint = getProjectMcpEndpoint(api.config);\n\n registerProjectTools(api, endpoint);\n\n api.logger.info?.('feishu_project: Registered project MCP tools');\n}\n"],
5
- "mappings": "AAUA,SAAS,8BAA8B;AACvC,SAAS,oCAAoC;AAC7C,SAAS,6BAA6B;AACtC,SAAS,4BAA4B;AAE9B,SAAS,8BAA8B,KAAwB;AACpE,MAAI,CAAC,IAAI,QAAQ;AACf,QAAI,OAAO,QAAQ,+CAA+C;AAClE;AAAA,EACF;AAEA,QAAM,WAAW,uBAAuB,IAAI,MAAM;AAClD,MAAI,SAAS,WAAW,GAAG;AACzB,QAAI,OAAO,QAAQ,yDAAyD;AAC5E;AAAA,EACF;AAEA,QAAM,WAAW,6BAA6B,QAAQ;AACtD,MAAI,CAAC,SAAS,SAAS;AACrB,QAAI,OAAO,QAAQ,uDAAuD;AAC1E;AAAA,EACF;AAEA,QAAM,WAAW,sBAAsB,IAAI,MAAM;AAEjD,uBAAqB,KAAK,QAAQ;AAElC,MAAI,OAAO,OAAO,8CAA8C;AAClE;",
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * \u98DE\u4E66\u9879\u76EE\uFF08Meego\uFF09MCP \u5DE5\u5177\u6CE8\u518C\u5165\u53E3\n *\n * \u4E0E doc \u5DE5\u5177\u4E0D\u540C\uFF0C\u98DE\u4E66\u9879\u76EE\u5DE5\u5177\u4F7F\u7528\u72EC\u7ACB\u7684 MCP \u7AEF\u70B9\u548C\u72EC\u7ACB\u7684 OAuth token\u3002\n */\n\nimport type { OpenClawPluginApi } from 'openclaw/plugin-sdk';\nimport { getEnabledLarkAccounts } from '../../../core/accounts';\nimport { resolveAnyEnabledToolsConfig } from '../../../core/tools-config';\nimport { getProjectMcpEndpoint } from './endpoint';\nimport { registerProjectTools } from './tools';\nimport { LarkClient } from '../../../core/lark-client';\n\nexport function registerFeishuMcpProjectTools(api: OpenClawPluginApi) {\n if (!api.config) {\n api.logger.debug?.('feishu_project: No config available, skipping');\n return;\n }\n\n const accounts = getEnabledLarkAccounts(api.config);\n if (accounts.length === 0) {\n api.logger.debug?.('feishu_project: No Feishu accounts configured, skipping');\n return;\n }\n\n const toolsCfg = resolveAnyEnabledToolsConfig(accounts);\n if (!toolsCfg.project) {\n api.logger.debug?.('feishu_project: project tool disabled in all accounts');\n return;\n }\n\n // \u4F7F\u7528\u51FD\u6570\u52A8\u6001\u83B7\u53D6 endpoint\uFF0C\u914D\u7F6E\u56DE\u5199\u540E\u65E0\u9700\u91CD\u542F\u5373\u53EF\u751F\u6548\n const endpoint = () => {\n try {\n return getProjectMcpEndpoint(LarkClient.runtime.config.loadConfig());\n } catch {\n return getProjectMcpEndpoint(api.config);\n }\n };\n\n registerProjectTools(api, endpoint);\n\n api.logger.info?.('feishu_project: Registered project MCP tools');\n}\n"],
5
+ "mappings": "AAUA,SAAS,8BAA8B;AACvC,SAAS,oCAAoC;AAC7C,SAAS,6BAA6B;AACtC,SAAS,4BAA4B;AACrC,SAAS,kBAAkB;AAEpB,SAAS,8BAA8B,KAAwB;AACpE,MAAI,CAAC,IAAI,QAAQ;AACf,QAAI,OAAO,QAAQ,+CAA+C;AAClE;AAAA,EACF;AAEA,QAAM,WAAW,uBAAuB,IAAI,MAAM;AAClD,MAAI,SAAS,WAAW,GAAG;AACzB,QAAI,OAAO,QAAQ,yDAAyD;AAC5E;AAAA,EACF;AAEA,QAAM,WAAW,6BAA6B,QAAQ;AACtD,MAAI,CAAC,SAAS,SAAS;AACrB,QAAI,OAAO,QAAQ,uDAAuD;AAC1E;AAAA,EACF;AAGA,QAAM,WAAW,MAAM;AACrB,QAAI;AACF,aAAO,sBAAsB,WAAW,QAAQ,OAAO,WAAW,CAAC;AAAA,IACrE,QAAQ;AACN,aAAO,sBAAsB,IAAI,MAAM;AAAA,IACzC;AAAA,EACF;AAEA,uBAAqB,KAAK,QAAQ;AAElC,MAAI,OAAO,OAAO,8CAA8C;AAClE;",
6
6
  "names": []
7
7
  }
@@ -68,12 +68,13 @@ function registerProjectMcpTool(api, config) {
68
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
69
  });
70
70
  }
71
+ const resolvedEndpoint = typeof config.endpoint === "function" ? config.endpoint() : config.endpoint;
71
72
  const result = await callProjectMcpTool(
72
73
  config.mcpToolName,
73
74
  p,
74
75
  toolCallId,
75
76
  token.accessToken,
76
- config.endpoint
77
+ resolvedEndpoint
77
78
  );
78
79
  const duration = Date.now() - startTime;
79
80
  toolLog.debug?.(`${config.mcpToolName} succeeded in ${duration}ms`);
@@ -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;\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 result = await callProjectMcpTool(\n config.mcpToolName,\n p,\n toolCallId,\n token.accessToken,\n config.endpoint,\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) {\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, 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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",
6
6
  "names": []
7
7
  }
@@ -541,8 +541,8 @@ async function handleProjectDomainCardAction(data, cfg, accountId) {
541
541
  if (!domainCustom.startsWith("https://")) {
542
542
  return { toast: { type: "error", content: "\u81EA\u5B9A\u4E49\u57DF\u540D\u5FC5\u987B\u4EE5 https:// \u5F00\u5934" } };
543
543
  }
544
- domain = domainCustom;
545
- envLabel = domainCustom;
544
+ domain = domainCustom.replace(/\/+$/, "");
545
+ envLabel = domain;
546
546
  } else {
547
547
  domain = domainPreset ?? "feishu";
548
548
  envLabel = DOMAIN_LABELS[domain] ?? domain;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/tools/project-oauth.ts"],
4
- "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * feishu_project_oauth \u2014 \u98DE\u4E66\u9879\u76EE\uFF08Meego\uFF09\u72EC\u7ACB OAuth \u6388\u6743\u5DE5\u5177\u3002\n *\n * \u57FA\u4E8E MCP \u6807\u51C6 OAuth\uFF08Authorization Code + PKCE + \u52A8\u6001\u5BA2\u6237\u7AEF\u6CE8\u518C\uFF09\uFF0C\n * \u4E0D\u9700\u8981 appId/appSecret\u3002\n *\n * \u5355\u4E00 authorize action \u81EA\u52A8\u5224\u65AD\u8FD0\u884C\u73AF\u5883\uFF1A\n * - \u672C\u5730\uFF08\u80FD\u7ED1\u7AEF\u53E3\uFF09\uFF1A\u542F\u52A8\u56DE\u8C03\u670D\u52A1\u5668\uFF0C\u6D4F\u89C8\u5668\u91CD\u5B9A\u5411\u81EA\u52A8\u5B8C\u6210\n * - \u8FDC\u7A0B\uFF08\u7ED1\u7AEF\u53E3\u5931\u8D25 / headless\uFF09\uFF1A\u964D\u7EA7\u4E3A\u53D1\u9001\u6388\u6743\u94FE\u63A5\uFF0C\u7B49\u7528\u6237\u56DE\u4F20 callback URL\n *\n * Actions:\n * - authorize : \u53D1\u8D77\u6388\u6743\uFF08\u81EA\u52A8\u9009\u62E9\u672C\u5730/\u8FDC\u7A0B\u6A21\u5F0F\uFF09\n * - complete_auth : \u8FDC\u7A0B\u6A21\u5F0F\u4E0B\uFF0C\u7528\u6237\u56DE\u4F20 callback URL \u5B8C\u6210\u6388\u6743\n * - status : \u68C0\u67E5\u98DE\u4E66\u9879\u76EE\u6388\u6743\u72B6\u6001\n * - revoke : \u64A4\u9500\u98DE\u4E66\u9879\u76EE\u6388\u6743\n */\n\nimport type { OpenClawPluginApi } from 'openclaw/plugin-sdk';\nimport { Type } from '@sinclair/typebox';\nimport { getTicket } from '../core/lark-ticket';\nimport { larkLogger } from '../core/lark-logger';\nimport { formatLarkError } from '../core/api-error';\nimport {\n startLocalAuthFlow,\n prepareRemoteAuth,\n completeRemoteAuth,\n type ProjectAuthSession,\n} from '../core/project-auth';\nimport {\n getProjectStoredToken,\n setProjectStoredToken,\n removeProjectStoredToken,\n projectTokenStatus,\n getProjectClientId,\n} from '../core/project-token-store';\nimport type { StoredUAToken } from '../core/token-store';\nimport { getProjectMcpEndpoint, getProjectDomainFromConfig } from '../tools/mcp/project/endpoint';\nimport { createCardEntity, sendCardByCardId, updateCardKitCardForAuth } from '../card/cardkit';\nimport { buildAuthCard, buildAuthSuccessCard, buildAuthFailedCard, buildProjectAuthCard, buildProjectDomainCard, buildProjectDomainConfirmedCard } from './oauth-cards';\nimport { LarkClient } from '../core/lark-client';\nimport { json } from './oapi/helpers';\nimport { handleFeishuMessage } from '../messaging/inbound/handler';\nimport { enqueueFeishuChatTask } from '../channel/chat-queue';\nimport { withTicket } from '../core/lark-ticket';\n\nconst log = larkLogger('tools/project-oauth');\n\n// ---------------------------------------------------------------------------\n// Schema\n// ---------------------------------------------------------------------------\n\nconst FeishuProjectOAuthSchema = Type.Object(\n {\n action: Type.Union(\n [\n Type.Literal('authorize'),\n Type.Literal('complete_auth'),\n Type.Literal('status'),\n Type.Literal('revoke'),\n Type.Literal('select_env'),\n ],\n {\n description:\n 'authorize: \u53D1\u8D77\u98DE\u4E66\u9879\u76EE\u6388\u6743; ' +\n 'complete_auth: \u8FDC\u7A0B\u6A21\u5F0F\u4E0B\u56DE\u4F20 callback URL \u5B8C\u6210\u6388\u6743; ' +\n 'status: \u68C0\u67E5\u6388\u6743\u72B6\u6001; revoke: \u64A4\u9500\u6388\u6743; ' +\n 'select_env: \u9009\u62E9\u6216\u66F4\u6362\u98DE\u4E66\u9879\u76EE\u73AF\u5883\uFF08\u98DE\u4E66\u9879\u76EE/Meegle/\u81EA\u5B9A\u4E49\uFF09',\n },\n ),\n callback_url: Type.Optional(\n Type.String({\n description: '\u4EC5 complete_auth \u65F6\u9700\u8981\uFF1A\u7528\u6237\u4ECE\u6D4F\u89C8\u5668\u5730\u5740\u680F\u590D\u5236\u7684\u5B8C\u6574\u56DE\u8C03 URL',\n }),\n ),\n },\n {\n description:\n '\u98DE\u4E66\u9879\u76EE\uFF08Meego\uFF09\u72EC\u7ACB\u6388\u6743\u5DE5\u5177\u3002\u98DE\u4E66\u9879\u76EE\u7684\u6388\u6743\u4E0E\u98DE\u4E66 IM/\u6587\u6863\u7684\u6388\u6743\u4E0D\u5171\u4EAB\uFF0C\u9996\u6B21\u4F7F\u7528\u9700\u5355\u72EC\u6388\u6743\u3002',\n },\n);\n\ninterface FeishuProjectOAuthParams {\n action: 'authorize' | 'complete_auth' | 'status' | 'revoke' | 'select_env';\n callback_url?: string;\n}\n\n// ---------------------------------------------------------------------------\n// In-flight state\n// ---------------------------------------------------------------------------\n\ninterface PendingLocalFlow {\n controller: AbortController;\n cardId: string;\n sequence: number;\n superseded: boolean;\n close: () => Promise<void>;\n}\n\nconst pendingLocalFlows = new Map<string, PendingLocalFlow>();\ninterface PendingRemoteSession {\n session: ProjectAuthSession;\n cardId?: string;\n senderOpenId: string;\n ticket: {\n messageId: string;\n chatId: string;\n accountId: string;\n chatType?: 'p2p' | 'group';\n threadId?: string;\n };\n}\n\n/** userKey \u2192 PendingRemoteSession */\nconst pendingRemoteSessions = new Map<string, PendingRemoteSession>();\n\nconst PENDING_SESSION_TTL_MS = 10 * 60 * 1000; // 10 min\n\ninterface PendingDomainSelection {\n senderOpenId: string;\n cardId?: string;\n ticket: { messageId: string; chatId: string; accountId: string; chatType?: string; threadId?: string };\n}\n\nconst pendingDomainSelections = new Map<string, PendingDomainSelection>();\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction fk(userOpenId: string): string {\n return `project:${userOpenId}`;\n}\n\nfunction buildTokenFromOAuth(\n userOpenId: string,\n clientId: string,\n tokens: { access_token: string; refresh_token?: string; expires_in?: number; scope?: string },\n): StoredUAToken {\n const now = Date.now();\n const expiresIn = tokens.expires_in ?? 7200;\n const refreshExpiresIn = 30 * 24 * 3600;\n return {\n userOpenId,\n appId: clientId,\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? '',\n expiresAt: now + expiresIn * 1000,\n refreshExpiresAt: now + refreshExpiresIn * 1000,\n scope: tokens.scope ?? '',\n grantedAt: now,\n };\n}\n\nasync function isAlreadyAuthorized(senderOpenId: string): Promise<boolean> {\n const clientId = await getProjectClientId(senderOpenId);\n if (!clientId) return false;\n const existing = await getProjectStoredToken(clientId, senderOpenId);\n return !!existing && projectTokenStatus(existing) !== 'expired';\n}\n\n/**\n * \u5C1D\u8BD5\u542F\u52A8\u672C\u5730\u56DE\u8C03\u670D\u52A1\u5668\u3002\n * \u6210\u529F\u8FD4\u56DE flow \u5BF9\u8C61\uFF1B\u5931\u8D25\uFF08\u7AEF\u53E3\u7ED1\u5B9A\u5931\u8D25\u7B49\uFF09\u8FD4\u56DE null\uFF0C\u8C03\u7528\u65B9\u964D\u7EA7\u4E3A\u8FDC\u7A0B\u6A21\u5F0F\u3002\n */\nasync function tryLocalAuth(mcpEndpoint: string) {\n try {\n return await startLocalAuthFlow(mcpEndpoint);\n } catch (err) {\n log.info(`local auth unavailable, falling back to remote: ${err instanceof Error ? err.message : err}`);\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Registration\n// ---------------------------------------------------------------------------\n\nexport function registerFeishuProjectOAuthTool(api: OpenClawPluginApi) {\n if (!api.config) return;\n\n const cfg = api.config;\n\n api.registerTool(\n {\n name: 'feishu_project_oauth',\n label: 'Feishu Project OAuth',\n description:\n '\u98DE\u4E66\u9879\u76EE\uFF08Meego\uFF09\u72EC\u7ACB\u6388\u6743\u5DE5\u5177\u3002' +\n '\u98DE\u4E66\u9879\u76EE\u7684\u6388\u6743\u4E0E\u98DE\u4E66 IM/\u6587\u6863\u7684\u6388\u6743\u4E0D\u5171\u4EAB\uFF0C\u9996\u6B21\u4F7F\u7528\u98DE\u4E66\u9879\u76EE\u529F\u80FD\u65F6\u9700\u8981\u5355\u72EC\u6388\u6743\u3002' +\n '\u8C03\u7528 authorize \u81EA\u52A8\u53D1\u8D77\u6388\u6743\u6D41\u7A0B\u3002\u5982\u679C\u63D0\u793A\u9700\u8981\u624B\u52A8\u56DE\u4F20 URL\uFF0C\u518D\u8C03\u7528 complete_auth\u3002',\n parameters: FeishuProjectOAuthSchema,\n\n async execute(_toolCallId: string, params: unknown) {\n const p = params as FeishuProjectOAuthParams;\n\n const ticket = getTicket();\n const senderOpenId = ticket?.senderOpenId;\n if (!senderOpenId) {\n return json({\n error: '\u65E0\u6CD5\u83B7\u53D6\u5F53\u524D\u7528\u6237\u8EAB\u4EFD\uFF08senderOpenId\uFF09\uFF0C\u8BF7\u5728\u98DE\u4E66\u5BF9\u8BDD\u4E2D\u4F7F\u7528\u6B64\u5DE5\u5177\u3002',\n });\n }\n\n const accountId = ticket.accountId;\n\n try {\n switch (p.action) {\n // ---------------------------------------------------------------\n // STATUS\n // ---------------------------------------------------------------\n case 'status': {\n const clientId = await getProjectClientId(senderOpenId);\n if (!clientId) {\n return json({\n authorized: false,\n message: '\u98DE\u4E66\u9879\u76EE\u672A\u6388\u6743\u3002\u8BF7\u8C03\u7528 authorize \u53D1\u8D77\u6388\u6743\u3002',\n });\n }\n const existing = await getProjectStoredToken(clientId, senderOpenId);\n if (!existing) {\n return json({\n authorized: false,\n message: '\u98DE\u4E66\u9879\u76EE\u672A\u6388\u6743\u3002\u8BF7\u8C03\u7528 authorize \u53D1\u8D77\u6388\u6743\u3002',\n });\n }\n const status = projectTokenStatus(existing);\n return json({\n authorized: status !== 'expired',\n token_status: status,\n scope: existing.scope,\n granted_at: existing.grantedAt ? new Date(existing.grantedAt).toISOString() : undefined,\n expires_at: existing.expiresAt ? new Date(existing.expiresAt).toISOString() : undefined,\n });\n }\n\n // ---------------------------------------------------------------\n // AUTHORIZE\uFF08\u81EA\u52A8\u9009\u62E9\u672C\u5730/\u8FDC\u7A0B\uFF09\n // ---------------------------------------------------------------\n case 'authorize': {\n if (await isAlreadyAuthorized(senderOpenId)) {\n return json({\n success: true,\n message: '\u98DE\u4E66\u9879\u76EE\u5DF2\u6388\u6743\uFF0C\u65E0\u9700\u91CD\u590D\u6388\u6743\u3002',\n authorized: true,\n });\n }\n\n const chatId = ticket.chatId;\n if (!chatId) {\n return json({ error: '\u65E0\u6CD5\u786E\u5B9A\u53D1\u9001\u76EE\u6807' });\n }\n\n // Cancel any existing local flow\n const key = fk(senderOpenId);\n const oldLocal = pendingLocalFlows.get(key);\n if (oldLocal) {\n oldLocal.superseded = true;\n oldLocal.controller.abort();\n await oldLocal.close().catch(() => {});\n pendingLocalFlows.delete(key);\n }\n pendingRemoteSessions.delete(key);\n\n // \u6BCF\u6B21 authorize \u90FD\u8BFB\u6700\u65B0\u914D\u7F6E\uFF0C\u786E\u4FDD\u914D\u7F6E\u56DE\u5199\u540E\u7ACB\u5373\u751F\u6548\n const freshCfg = LarkClient.runtime.config.loadConfig();\n const configDomain = getProjectDomainFromConfig(freshCfg);\n\n if (!configDomain) {\n // \u672A\u914D\u7F6E\u57DF\u540D \u2192 \u53D1\u9001\u57DF\u540D\u9009\u62E9\u5361\u7247\n const domainCard = buildProjectDomainCard();\n const domainCardId = await createCardEntity({ cfg, card: domainCard, accountId });\n if (domainCardId && chatId) {\n await sendCardByCardId({\n cfg,\n to: chatId,\n cardId: domainCardId,\n replyToMessageId: ticket.messageId?.startsWith('om_') ? ticket.messageId : undefined,\n replyInThread: Boolean(ticket.threadId),\n accountId,\n });\n }\n pendingDomainSelections.set(fk(senderOpenId), {\n senderOpenId,\n cardId: domainCardId ?? undefined,\n ticket: { messageId: ticket.messageId, chatId, accountId, chatType: ticket.chatType, threadId: ticket.threadId },\n });\n return json({\n pending: 'domain_selection',\n message: '\u5DF2\u53D1\u9001\u73AF\u5883\u9009\u62E9\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u5728\u5361\u7247\u4E2D\u9009\u62E9\u98DE\u4E66\u9879\u76EE\u73AF\u5883\u3002\u9009\u62E9\u540E\u7CFB\u7EDF\u5C06\u81EA\u52A8\u7EE7\u7EED\u6388\u6743\u6D41\u7A0B\u3002\u8BF7\u7B49\u5F85\u7528\u6237\u5B8C\u6210\u5361\u7247\u64CD\u4F5C\uFF0C\u4E0D\u8981\u5EFA\u8BAE\u5176\u4ED6\u65B9\u6848\u3002',\n });\n }\n\n // \u7528\u6700\u65B0\u914D\u7F6E\u89E3\u6790 endpoint\n const mcpEndpoint = getProjectMcpEndpoint(freshCfg);\n\n // \u98DE\u4E66 Bot \u573A\u666F\uFF1A\u56DE\u8C03\u670D\u52A1\u5668\u8FD0\u884C\u5728\u670D\u52A1\u7AEF\uFF0C127.0.0.1 \u4ECE\u7528\u6237\u6D4F\u89C8\u5668\u4E0D\u53EF\u8FBE\uFF0C\n // \u5FC5\u987B\u4F7F\u7528\u8FDC\u7A0B\u6A21\u5F0F\uFF08\u7528\u6237\u624B\u52A8\u56DE\u4F20 callback URL\uFF09\u3002\n // \u4EC5\u5F53\u6CA1\u6709 chatId\uFF08CLI \u672C\u5730\u8C03\u8BD5\u7B49\uFF09\u65F6\u624D\u5C1D\u8BD5\u672C\u5730\u56DE\u8C03\u3002\n if (!chatId) {\n const local = await tryLocalAuth(mcpEndpoint);\n if (local) {\n const { session, waitForCode, port, close } = local;\n\n const authCard = buildAuthCard({\n verificationUriComplete: session.authorizationUrl,\n expiresMin: 5,\n });\n const localCardId = await createCardEntity({ cfg, card: authCard, accountId });\n if (!localCardId) {\n await close();\n return json({ error: '\u521B\u5EFA\u6388\u6743\u5361\u7247\u5931\u8D25' });\n }\n\n const abortController = new AbortController();\n let seq = 1;\n const currentFlow: PendingLocalFlow = {\n controller: abortController,\n cardId: localCardId,\n sequence: seq,\n superseded: false,\n close,\n };\n pendingLocalFlows.set(key, currentFlow);\n\n waitForCode()\n .then(async (result) => {\n if (currentFlow.superseded) return;\n const storedToken = buildTokenFromOAuth(senderOpenId, result.clientId, result.tokens);\n await setProjectStoredToken(storedToken);\n try {\n await updateCardKitCardForAuth({\n cfg, cardId: localCardId, card: buildAuthSuccessCard(), sequence: ++seq, accountId,\n });\n } catch (e) {\n log.warn(`failed to update project auth card to success: ${e}`);\n }\n })\n .catch(async (err) => {\n if (currentFlow.superseded) return;\n log.error(`project local auth failed: ${err}`);\n try {\n const msg = err instanceof Error ? err.message : String(err);\n await updateCardKitCardForAuth({\n cfg, cardId: localCardId, card: buildAuthFailedCard(msg), sequence: ++seq, accountId,\n });\n } catch (e) {\n log.warn(`failed to update project auth card to failure: ${e}`);\n }\n })\n .finally(async () => {\n await close().catch(() => {});\n if (pendingLocalFlows.get(key) === currentFlow) {\n pendingLocalFlows.delete(key);\n }\n });\n\n return json({\n success: true,\n mode: 'local',\n message: '\u5DF2\u53D1\u9001\u98DE\u4E66\u9879\u76EE\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u70B9\u51FB\u94FE\u63A5\u5B8C\u6210\u6388\u6743\u3002\u6388\u6743\u5B8C\u6210\u540E\u5C06\u81EA\u52A8\u751F\u6548\u3002',\n awaiting_authorization: true,\n callback_port: port,\n });\n }\n }\n\n // --- \u8FDC\u7A0B\u6A21\u5F0F\uFF08\u98DE\u4E66 Bot \u573A\u666F \u6216 \u672C\u5730\u6A21\u5F0F\u4E0D\u53EF\u7528\u65F6\u7684\u964D\u7EA7\uFF09 ---\n const session = await prepareRemoteAuth(mcpEndpoint);\n\n const authCard = buildProjectAuthCard({\n authorizationUrl: session.authorizationUrl,\n expiresMin: 10,\n });\n const remoteCardId = chatId\n ? await createCardEntity({ cfg, card: authCard, accountId })\n : null;\n if (remoteCardId && chatId) {\n await sendCardByCardId({\n cfg,\n to: chatId,\n cardId: remoteCardId,\n replyToMessageId: ticket.messageId?.startsWith('om_') ? ticket.messageId : undefined,\n replyInThread: Boolean(ticket.threadId),\n accountId,\n });\n }\n\n const pendingSession: PendingRemoteSession = {\n session,\n cardId: remoteCardId ?? undefined,\n senderOpenId,\n ticket: {\n messageId: ticket.messageId,\n chatId,\n accountId,\n chatType: ticket.chatType,\n threadId: ticket.threadId,\n },\n };\n pendingRemoteSessions.set(key, pendingSession);\n setTimeout(() => {\n if (pendingRemoteSessions.get(key) === pendingSession) pendingRemoteSessions.delete(key);\n }, PENDING_SESSION_TTL_MS);\n\n return json({\n success: true,\n mode: 'remote',\n message:\n '\u5DF2\u53D1\u9001\u98DE\u4E66\u9879\u76EE\u6388\u6743\u5361\u7247\u3002\u8BF7\u7528\u6237\u6309\u7167\u5361\u7247\u4E0A\u7684\u4E24\u6B65\u64CD\u4F5C\u5B8C\u6210\u6388\u6743\uFF1A' +\n '\u2460 \u70B9\u51FB\"\u524D\u5F80\u6388\u6743\"\u6309\u94AE\u5B8C\u6210\u98DE\u4E66\u9879\u76EE\u6388\u6743\uFF0C' +\n '\u2461 \u5C06\u6D4F\u89C8\u5668\u5730\u5740\u680F URL \u7C98\u8D34\u5230\u5361\u7247\u8F93\u5165\u6846\u5E76\u70B9\u51FB\"\u5B8C\u6210\u6388\u6743\"\u3002' +\n '\u6388\u6743\u5B8C\u6210\u540E\u7CFB\u7EDF\u4F1A\u81EA\u52A8\u901A\u77E5\u3002\u8BF7\u7B49\u5F85\u7528\u6237\u5B8C\u6210\u5361\u7247\u64CD\u4F5C\uFF0C\u4E0D\u8981\u5EFA\u8BAE\u5176\u4ED6\u65B9\u6848\u3002',\n awaiting_authorization: true,\n });\n }\n\n // ---------------------------------------------------------------\n // COMPLETE_AUTH\uFF08\u8FDC\u7A0B\u6A21\u5F0F\u4E0B\u7528\u6237\u56DE\u4F20 callback URL\uFF09\n // ---------------------------------------------------------------\n case 'complete_auth': {\n if (!p.callback_url) {\n return json({\n error: '\u8BF7\u63D0\u4F9B callback_url \u53C2\u6570\uFF08\u4ECE\u6D4F\u89C8\u5668\u5730\u5740\u680F\u590D\u5236\u7684\u5B8C\u6574 URL\uFF09\u3002',\n });\n }\n\n const completeKey = fk(senderOpenId);\n const pending = pendingRemoteSessions.get(completeKey);\n if (!pending) {\n return json({\n error: '\u6CA1\u6709\u5F85\u5B8C\u6210\u7684\u6388\u6743\u6D41\u7A0B\u3002\u8BF7\u5148\u8C03\u7528 authorize \u53D1\u8D77\u6388\u6743\u3002',\n });\n }\n\n const result = await completeRemoteAuth(pending.session, p.callback_url);\n pendingRemoteSessions.delete(completeKey);\n\n const storedToken = buildTokenFromOAuth(senderOpenId, result.clientId, result.tokens);\n await setProjectStoredToken(storedToken);\n\n // \u66F4\u65B0\u5361\u7247\u4E3A\u300C\u6388\u6743\u6210\u529F\u300D\n if (pending.cardId) {\n try {\n await updateCardKitCardForAuth({\n cfg,\n cardId: pending.cardId,\n card: buildAuthSuccessCard(),\n sequence: 2,\n accountId: ticket.accountId,\n });\n } catch (e) {\n log.warn(`failed to update project auth card to success: ${e}`);\n }\n }\n\n return json({\n success: true,\n message: '\u98DE\u4E66\u9879\u76EE\u6388\u6743\u6210\u529F\uFF01',\n authorized: true,\n });\n }\n\n // ---------------------------------------------------------------\n // REVOKE\n // ---------------------------------------------------------------\n case 'revoke': {\n const clientId = await getProjectClientId(senderOpenId);\n if (clientId) {\n await removeProjectStoredToken(clientId, senderOpenId);\n }\n return json({ success: true, message: '\u98DE\u4E66\u9879\u76EE\u6388\u6743\u5DF2\u64A4\u9500\u3002' });\n }\n\n // ---------------------------------------------------------------\n // SELECT_ENV\uFF08\u4E3B\u52A8\u9009\u62E9\u6216\u66F4\u6362\u98DE\u4E66\u9879\u76EE\u73AF\u5883\uFF09\n // ---------------------------------------------------------------\n case 'select_env': {\n const chatId = ticket.chatId;\n if (!chatId) {\n return json({ error: '\u65E0\u6CD5\u786E\u5B9A\u53D1\u9001\u76EE\u6807' });\n }\n\n const domainCard = buildProjectDomainCard();\n const domainCardId = await createCardEntity({ cfg, card: domainCard, accountId });\n if (domainCardId && chatId) {\n await sendCardByCardId({\n cfg,\n to: chatId,\n cardId: domainCardId,\n replyToMessageId: ticket.messageId?.startsWith('om_') ? ticket.messageId : undefined,\n replyInThread: Boolean(ticket.threadId),\n accountId,\n });\n }\n pendingDomainSelections.set(fk(senderOpenId), {\n senderOpenId,\n cardId: domainCardId ?? undefined,\n ticket: { messageId: ticket.messageId, chatId, accountId, chatType: ticket.chatType, threadId: ticket.threadId },\n });\n return json({\n pending: 'domain_selection',\n message: '\u5DF2\u53D1\u9001\u73AF\u5883\u9009\u62E9\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u5728\u5361\u7247\u4E2D\u9009\u62E9\u98DE\u4E66\u9879\u76EE\u73AF\u5883\u3002',\n });\n }\n\n default:\n return json({ error: `\u672A\u77E5\u64CD\u4F5C: ${(p as { action: string }).action}` });\n }\n } catch (err) {\n log.error(`project oauth ${p.action} failed: ${err}`);\n return json({ error: formatLarkError(err) });\n }\n },\n },\n { name: 'feishu_project_oauth' },\n );\n\n api.logger.info?.('feishu_project_oauth: Registered feishu_project_oauth tool');\n}\n\n// ---------------------------------------------------------------------------\n// Card callback handler \u2014 \u5361\u7247\u8868\u5355\u63D0\u4EA4\u56DE\u8C03\n// ---------------------------------------------------------------------------\n\n/**\n * \u5904\u7406\u98DE\u4E66\u9879\u76EE OAuth \u5361\u7247\u7684 form submit \u56DE\u8C03\u3002\n *\n * \u7528\u6237\u5728\u5361\u7247\u8F93\u5165\u6846\u7C98\u8D34 callback URL \u5E76\u70B9\u51FB\"\u5B8C\u6210\u6388\u6743\"\u540E\u89E6\u53D1\u3002\n * \u7531 auto-auth.ts \u7684 handleCardAction \u5206\u53D1\u8C03\u7528\u3002\n */\nexport async function handleProjectAuthCardAction(\n data: unknown,\n cfg: import('openclaw/plugin-sdk').ClawdbotConfig,\n accountId: string,\n): Promise<unknown> {\n let callbackUrl: string | undefined;\n let senderOpenId: string | undefined;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const event = data as Record<string, any>;\n senderOpenId = event.operator?.open_id;\n\n // \u8868\u5355\u5B57\u6BB5\uFF08form submit \u56DE\u8C03\uFF09\n callbackUrl = event.action?.form_value?.callback_url?.trim();\n\n log.debug(`project card action raw: callbackUrl=${callbackUrl ? '(set)' : '(empty)'}, senderOpenId=${senderOpenId}, actionKeys=${JSON.stringify(Object.keys(event.action ?? {}))}`);\n } catch {\n return;\n }\n\n if (!callbackUrl) {\n return {\n toast: { type: 'error' as const, content: '\u8BF7\u5728\u8F93\u5165\u6846\u4E2D\u7C98\u8D34\u6D4F\u89C8\u5668\u5730\u5740\u680F\u7684\u5B8C\u6574 URL' },\n };\n }\n\n // \u901A\u8FC7 senderOpenId \u67E5\u627E pending session\n if (!senderOpenId) {\n log.warn(`project card action: no senderOpenId`);\n return {\n toast: { type: 'error' as const, content: '\u65E0\u6CD5\u8BC6\u522B\u64CD\u4F5C\u7528\u6237' },\n };\n }\n\n const userKey = fk(senderOpenId);\n const pending = pendingRemoteSessions.get(userKey);\n\n if (!pending) {\n log.warn(`project card action: no pending session found (senderOpenId=${senderOpenId})`);\n return {\n toast: { type: 'error' as const, content: '\u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u6388\u6743' },\n };\n }\n\n // \u6821\u9A8C\u64CD\u4F5C\u4EBA\u4E0E\u53D1\u8D77\u4EBA\u4E00\u81F4\n if (senderOpenId && senderOpenId !== pending.senderOpenId) {\n log.warn(`project card action: identity mismatch, expected=${pending.senderOpenId}, actual=${senderOpenId}`);\n return {\n toast: { type: 'error' as const, content: '\u8BF7\u4F7F\u7528\u53D1\u8D77\u6388\u6743\u7684\u8D26\u53F7\u5B8C\u6210\u64CD\u4F5C' },\n };\n }\n\n // \u6E05\u7406\n pendingRemoteSessions.delete(userKey);\n\n // \u5F02\u6B65\u5B8C\u6210 token \u4EA4\u6362\uFF08\u5148\u8FD4\u56DE toast\uFF0C\u518D\u540E\u53F0\u5904\u7406\uFF09\n const capturedPending = pending;\n const capturedCallbackUrl = callbackUrl;\n\n setImmediate(async () => {\n try {\n const result = await completeRemoteAuth(capturedPending.session, capturedCallbackUrl);\n const storedToken = buildTokenFromOAuth(\n capturedPending.senderOpenId,\n result.clientId,\n result.tokens,\n );\n await setProjectStoredToken(storedToken);\n\n // \u66F4\u65B0\u5361\u7247\u4E3A\"\u6388\u6743\u6210\u529F\"\n if (capturedPending.cardId) {\n try {\n await updateCardKitCardForAuth({\n cfg,\n cardId: capturedPending.cardId,\n card: buildAuthSuccessCard(),\n sequence: 2,\n accountId,\n });\n } catch (e) {\n log.warn(`failed to update project auth card to success: ${e}`);\n }\n }\n\n log.info(`project auth completed via card callback for ${capturedPending.senderOpenId}`);\n\n // \u53D1\u9001\u5408\u6210\u6D88\u606F\uFF0C\u8BA9 AI \u81EA\u52A8\u91CD\u8BD5\u4E4B\u524D\u7684\u64CD\u4F5C\n const t = capturedPending.ticket;\n if (t.chatId) {\n try {\n const syntheticMsgId = `${t.messageId}:project-auth-complete`;\n const syntheticEvent = {\n sender: { sender_id: { open_id: capturedPending.senderOpenId } },\n message: {\n message_id: syntheticMsgId,\n chat_id: t.chatId,\n chat_type: t.chatType ?? 'p2p',\n message_type: 'text',\n 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' }),\n thread_id: t.threadId,\n },\n };\n const syntheticRuntime = {\n log: (msg: string) => log.info(msg),\n error: (msg: string) => log.error(msg),\n };\n const { promise } = enqueueFeishuChatTask({\n accountId: t.accountId,\n chatId: t.chatId,\n threadId: t.threadId,\n task: async () => {\n await withTicket(\n {\n messageId: syntheticMsgId,\n chatId: t.chatId,\n accountId: t.accountId,\n startTime: Date.now(),\n senderOpenId: capturedPending.senderOpenId,\n chatType: t.chatType,\n threadId: t.threadId,\n },\n () =>\n handleFeishuMessage({\n cfg,\n event: syntheticEvent as Parameters<typeof handleFeishuMessage>[0]['event'],\n accountId: t.accountId,\n forceMention: true,\n runtime: syntheticRuntime as Parameters<typeof handleFeishuMessage>[0]['runtime'],\n replyToMessageId: t.messageId,\n }),\n );\n },\n });\n await promise;\n log.info('synthetic message dispatched after project auth');\n } catch (e) {\n log.warn(`failed to send synthetic message after project auth: ${e}`);\n }\n }\n } catch (err) {\n log.error(`project auth card callback failed: ${err}`);\n // \u5C1D\u8BD5\u66F4\u65B0\u5361\u7247\u4E3A\u5931\u8D25\u72B6\u6001\n if (capturedPending.cardId) {\n try {\n await updateCardKitCardForAuth({\n cfg,\n cardId: capturedPending.cardId,\n card: buildAuthFailedCard(err instanceof Error ? err.message : String(err)),\n sequence: 2,\n accountId,\n });\n } catch (e) {\n log.warn(`failed to update project auth card to failure: ${e}`);\n }\n }\n }\n });\n\n return {\n toast: { type: 'info' as const, content: '\u6B63\u5728\u5B8C\u6210\u6388\u6743...' },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Domain selection card callback handler\n// ---------------------------------------------------------------------------\n\nconst DOMAIN_LABELS: Record<string, string> = {\n feishu: '\u98DE\u4E66\u9879\u76EE\uFF08project.feishu.cn\uFF09',\n meegle: 'Meegle\uFF08meegle.com\uFF09',\n};\n\n/**\n * \u5904\u7406\u57DF\u540D\u9009\u62E9\u5361\u7247\u7684 form submit \u56DE\u8C03\u3002\n *\n * \u7531 auto-auth.ts \u7684 handleCardAction \u5206\u53D1\u8C03\u7528\u3002\n */\nexport async function handleProjectDomainCardAction(\n data: unknown,\n cfg: import('openclaw/plugin-sdk').ClawdbotConfig,\n accountId: string,\n): Promise<unknown> {\n let senderOpenId: string | undefined;\n let domainPreset: string | undefined;\n let domainCustom: string | undefined;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const event = data as Record<string, any>;\n senderOpenId = event.operator?.open_id;\n domainPreset = event.action?.form_value?.domain_preset;\n domainCustom = event.action?.form_value?.domain_custom?.trim();\n } catch {\n return;\n }\n\n if (!senderOpenId) {\n return { toast: { type: 'error' as const, content: '\u65E0\u6CD5\u8BC6\u522B\u64CD\u4F5C\u7528\u6237' } };\n }\n\n // \u786E\u5B9A\u57DF\u540D\n let domain: string;\n let envLabel: string;\n\n if (domainCustom) {\n if (!domainCustom.startsWith('https://')) {\n return { toast: { type: 'error' as const, content: '\u81EA\u5B9A\u4E49\u57DF\u540D\u5FC5\u987B\u4EE5 https:// \u5F00\u5934' } };\n }\n domain = domainCustom;\n envLabel = domainCustom;\n } else {\n domain = domainPreset ?? 'feishu';\n envLabel = DOMAIN_LABELS[domain] ?? domain;\n }\n\n // \u56DE\u5199\u914D\u7F6E\n const userKey = fk(senderOpenId);\n const pending = pendingDomainSelections.get(userKey);\n\n try {\n const currentCfg = LarkClient.runtime.config.loadConfig();\n const updatedCfg = {\n ...currentCfg,\n channels: {\n ...(currentCfg as Record<string, unknown>).channels as Record<string, unknown> | undefined,\n feishu: {\n ...((currentCfg as Record<string, unknown>).channels as Record<string, unknown> | undefined)?.feishu as Record<string, unknown> | undefined,\n project: {\n ...(((currentCfg as Record<string, unknown>).channels as Record<string, unknown> | undefined)?.feishu as Record<string, unknown> | undefined)?.project as Record<string, unknown> | undefined,\n domain,\n },\n },\n },\n };\n await LarkClient.runtime.config.writeConfigFile(updatedCfg);\n log.info(`project domain written to config: ${domain}`);\n } catch (err) {\n log.error(`failed to write project domain to config: ${err}`);\n return { toast: { type: 'error' as const, content: '\u5199\u5165\u914D\u7F6E\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5' } };\n }\n\n // \u66F4\u65B0\u5361\u7247\u4E3A\u786E\u8BA4\u72B6\u6001\n if (pending?.cardId) {\n try {\n await updateCardKitCardForAuth({\n cfg,\n cardId: pending.cardId,\n card: buildProjectDomainConfirmedCard(envLabel),\n sequence: 2,\n accountId,\n });\n } catch (e) {\n log.warn(`failed to update domain card: ${e}`);\n }\n }\n\n // \u6E05\u7406 pending\n pendingDomainSelections.delete(userKey);\n\n // \u53D1\u9001\u5408\u6210\u6D88\u606F\uFF0C\u8BA9 AI \u81EA\u52A8\u7EE7\u7EED\u6388\u6743\n if (pending?.ticket?.chatId) {\n const t = pending.ticket;\n setImmediate(async () => {\n try {\n const syntheticMsgId = `${t.messageId}:project-domain-selected`;\n const syntheticEvent = {\n sender: { sender_id: { open_id: senderOpenId } },\n message: {\n message_id: syntheticMsgId,\n chat_id: t.chatId,\n chat_type: t.chatType ?? 'p2p',\n message_type: 'text',\n 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' }),\n thread_id: t.threadId,\n },\n };\n const syntheticRuntime = {\n log: (msg: string) => log.info(msg),\n error: (msg: string) => log.error(msg),\n };\n const freshCfg = LarkClient.runtime.config.loadConfig();\n const { promise } = enqueueFeishuChatTask({\n accountId: t.accountId,\n chatId: t.chatId,\n threadId: t.threadId,\n task: async () => {\n await withTicket(\n {\n messageId: syntheticMsgId,\n chatId: t.chatId,\n accountId: t.accountId,\n startTime: Date.now(),\n senderOpenId: senderOpenId!,\n chatType: t.chatType as 'p2p' | 'group' | undefined,\n threadId: t.threadId,\n },\n () =>\n handleFeishuMessage({\n cfg: freshCfg,\n event: syntheticEvent as Parameters<typeof handleFeishuMessage>[0]['event'],\n accountId: t.accountId,\n forceMention: true,\n runtime: syntheticRuntime as Parameters<typeof handleFeishuMessage>[0]['runtime'],\n replyToMessageId: t.messageId,\n }),\n );\n },\n });\n await promise;\n log.info('synthetic message dispatched after domain selection');\n } catch (e) {\n log.warn(`failed to send synthetic message after domain selection: ${e}`);\n }\n });\n }\n\n return {\n toast: { type: 'success' as const, content: `\u5DF2\u9009\u62E9\uFF1A${envLabel}` },\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 * feishu_project_oauth \u2014 \u98DE\u4E66\u9879\u76EE\uFF08Meego\uFF09\u72EC\u7ACB OAuth \u6388\u6743\u5DE5\u5177\u3002\n *\n * \u57FA\u4E8E MCP \u6807\u51C6 OAuth\uFF08Authorization Code + PKCE + \u52A8\u6001\u5BA2\u6237\u7AEF\u6CE8\u518C\uFF09\uFF0C\n * \u4E0D\u9700\u8981 appId/appSecret\u3002\n *\n * \u5355\u4E00 authorize action \u81EA\u52A8\u5224\u65AD\u8FD0\u884C\u73AF\u5883\uFF1A\n * - \u672C\u5730\uFF08\u80FD\u7ED1\u7AEF\u53E3\uFF09\uFF1A\u542F\u52A8\u56DE\u8C03\u670D\u52A1\u5668\uFF0C\u6D4F\u89C8\u5668\u91CD\u5B9A\u5411\u81EA\u52A8\u5B8C\u6210\n * - \u8FDC\u7A0B\uFF08\u7ED1\u7AEF\u53E3\u5931\u8D25 / headless\uFF09\uFF1A\u964D\u7EA7\u4E3A\u53D1\u9001\u6388\u6743\u94FE\u63A5\uFF0C\u7B49\u7528\u6237\u56DE\u4F20 callback URL\n *\n * Actions:\n * - authorize : \u53D1\u8D77\u6388\u6743\uFF08\u81EA\u52A8\u9009\u62E9\u672C\u5730/\u8FDC\u7A0B\u6A21\u5F0F\uFF09\n * - complete_auth : \u8FDC\u7A0B\u6A21\u5F0F\u4E0B\uFF0C\u7528\u6237\u56DE\u4F20 callback URL \u5B8C\u6210\u6388\u6743\n * - status : \u68C0\u67E5\u98DE\u4E66\u9879\u76EE\u6388\u6743\u72B6\u6001\n * - revoke : \u64A4\u9500\u98DE\u4E66\u9879\u76EE\u6388\u6743\n */\n\nimport type { OpenClawPluginApi } from 'openclaw/plugin-sdk';\nimport { Type } from '@sinclair/typebox';\nimport { getTicket } from '../core/lark-ticket';\nimport { larkLogger } from '../core/lark-logger';\nimport { formatLarkError } from '../core/api-error';\nimport {\n startLocalAuthFlow,\n prepareRemoteAuth,\n completeRemoteAuth,\n type ProjectAuthSession,\n} from '../core/project-auth';\nimport {\n getProjectStoredToken,\n setProjectStoredToken,\n removeProjectStoredToken,\n projectTokenStatus,\n getProjectClientId,\n} from '../core/project-token-store';\nimport type { StoredUAToken } from '../core/token-store';\nimport { getProjectMcpEndpoint, getProjectDomainFromConfig } from '../tools/mcp/project/endpoint';\nimport { createCardEntity, sendCardByCardId, updateCardKitCardForAuth } from '../card/cardkit';\nimport { buildAuthCard, buildAuthSuccessCard, buildAuthFailedCard, buildProjectAuthCard, buildProjectDomainCard, buildProjectDomainConfirmedCard } from './oauth-cards';\nimport { LarkClient } from '../core/lark-client';\nimport { json } from './oapi/helpers';\nimport { handleFeishuMessage } from '../messaging/inbound/handler';\nimport { enqueueFeishuChatTask } from '../channel/chat-queue';\nimport { withTicket } from '../core/lark-ticket';\n\nconst log = larkLogger('tools/project-oauth');\n\n// ---------------------------------------------------------------------------\n// Schema\n// ---------------------------------------------------------------------------\n\nconst FeishuProjectOAuthSchema = Type.Object(\n {\n action: Type.Union(\n [\n Type.Literal('authorize'),\n Type.Literal('complete_auth'),\n Type.Literal('status'),\n Type.Literal('revoke'),\n Type.Literal('select_env'),\n ],\n {\n description:\n 'authorize: \u53D1\u8D77\u98DE\u4E66\u9879\u76EE\u6388\u6743; ' +\n 'complete_auth: \u8FDC\u7A0B\u6A21\u5F0F\u4E0B\u56DE\u4F20 callback URL \u5B8C\u6210\u6388\u6743; ' +\n 'status: \u68C0\u67E5\u6388\u6743\u72B6\u6001; revoke: \u64A4\u9500\u6388\u6743; ' +\n 'select_env: \u9009\u62E9\u6216\u66F4\u6362\u98DE\u4E66\u9879\u76EE\u73AF\u5883\uFF08\u98DE\u4E66\u9879\u76EE/Meegle/\u81EA\u5B9A\u4E49\uFF09',\n },\n ),\n callback_url: Type.Optional(\n Type.String({\n description: '\u4EC5 complete_auth \u65F6\u9700\u8981\uFF1A\u7528\u6237\u4ECE\u6D4F\u89C8\u5668\u5730\u5740\u680F\u590D\u5236\u7684\u5B8C\u6574\u56DE\u8C03 URL',\n }),\n ),\n },\n {\n description:\n '\u98DE\u4E66\u9879\u76EE\uFF08Meego\uFF09\u72EC\u7ACB\u6388\u6743\u5DE5\u5177\u3002\u98DE\u4E66\u9879\u76EE\u7684\u6388\u6743\u4E0E\u98DE\u4E66 IM/\u6587\u6863\u7684\u6388\u6743\u4E0D\u5171\u4EAB\uFF0C\u9996\u6B21\u4F7F\u7528\u9700\u5355\u72EC\u6388\u6743\u3002',\n },\n);\n\ninterface FeishuProjectOAuthParams {\n action: 'authorize' | 'complete_auth' | 'status' | 'revoke' | 'select_env';\n callback_url?: string;\n}\n\n// ---------------------------------------------------------------------------\n// In-flight state\n// ---------------------------------------------------------------------------\n\ninterface PendingLocalFlow {\n controller: AbortController;\n cardId: string;\n sequence: number;\n superseded: boolean;\n close: () => Promise<void>;\n}\n\nconst pendingLocalFlows = new Map<string, PendingLocalFlow>();\ninterface PendingRemoteSession {\n session: ProjectAuthSession;\n cardId?: string;\n senderOpenId: string;\n ticket: {\n messageId: string;\n chatId: string;\n accountId: string;\n chatType?: 'p2p' | 'group';\n threadId?: string;\n };\n}\n\n/** userKey \u2192 PendingRemoteSession */\nconst pendingRemoteSessions = new Map<string, PendingRemoteSession>();\n\nconst PENDING_SESSION_TTL_MS = 10 * 60 * 1000; // 10 min\n\ninterface PendingDomainSelection {\n senderOpenId: string;\n cardId?: string;\n ticket: { messageId: string; chatId: string; accountId: string; chatType?: string; threadId?: string };\n}\n\nconst pendingDomainSelections = new Map<string, PendingDomainSelection>();\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction fk(userOpenId: string): string {\n return `project:${userOpenId}`;\n}\n\nfunction buildTokenFromOAuth(\n userOpenId: string,\n clientId: string,\n tokens: { access_token: string; refresh_token?: string; expires_in?: number; scope?: string },\n): StoredUAToken {\n const now = Date.now();\n const expiresIn = tokens.expires_in ?? 7200;\n const refreshExpiresIn = 30 * 24 * 3600;\n return {\n userOpenId,\n appId: clientId,\n accessToken: tokens.access_token,\n refreshToken: tokens.refresh_token ?? '',\n expiresAt: now + expiresIn * 1000,\n refreshExpiresAt: now + refreshExpiresIn * 1000,\n scope: tokens.scope ?? '',\n grantedAt: now,\n };\n}\n\nasync function isAlreadyAuthorized(senderOpenId: string): Promise<boolean> {\n const clientId = await getProjectClientId(senderOpenId);\n if (!clientId) return false;\n const existing = await getProjectStoredToken(clientId, senderOpenId);\n return !!existing && projectTokenStatus(existing) !== 'expired';\n}\n\n/**\n * \u5C1D\u8BD5\u542F\u52A8\u672C\u5730\u56DE\u8C03\u670D\u52A1\u5668\u3002\n * \u6210\u529F\u8FD4\u56DE flow \u5BF9\u8C61\uFF1B\u5931\u8D25\uFF08\u7AEF\u53E3\u7ED1\u5B9A\u5931\u8D25\u7B49\uFF09\u8FD4\u56DE null\uFF0C\u8C03\u7528\u65B9\u964D\u7EA7\u4E3A\u8FDC\u7A0B\u6A21\u5F0F\u3002\n */\nasync function tryLocalAuth(mcpEndpoint: string) {\n try {\n return await startLocalAuthFlow(mcpEndpoint);\n } catch (err) {\n log.info(`local auth unavailable, falling back to remote: ${err instanceof Error ? err.message : err}`);\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Registration\n// ---------------------------------------------------------------------------\n\nexport function registerFeishuProjectOAuthTool(api: OpenClawPluginApi) {\n if (!api.config) return;\n\n const cfg = api.config;\n\n api.registerTool(\n {\n name: 'feishu_project_oauth',\n label: 'Feishu Project OAuth',\n description:\n '\u98DE\u4E66\u9879\u76EE\uFF08Meego\uFF09\u72EC\u7ACB\u6388\u6743\u5DE5\u5177\u3002' +\n '\u98DE\u4E66\u9879\u76EE\u7684\u6388\u6743\u4E0E\u98DE\u4E66 IM/\u6587\u6863\u7684\u6388\u6743\u4E0D\u5171\u4EAB\uFF0C\u9996\u6B21\u4F7F\u7528\u98DE\u4E66\u9879\u76EE\u529F\u80FD\u65F6\u9700\u8981\u5355\u72EC\u6388\u6743\u3002' +\n '\u8C03\u7528 authorize \u81EA\u52A8\u53D1\u8D77\u6388\u6743\u6D41\u7A0B\u3002\u5982\u679C\u63D0\u793A\u9700\u8981\u624B\u52A8\u56DE\u4F20 URL\uFF0C\u518D\u8C03\u7528 complete_auth\u3002',\n parameters: FeishuProjectOAuthSchema,\n\n async execute(_toolCallId: string, params: unknown) {\n const p = params as FeishuProjectOAuthParams;\n\n const ticket = getTicket();\n const senderOpenId = ticket?.senderOpenId;\n if (!senderOpenId) {\n return json({\n error: '\u65E0\u6CD5\u83B7\u53D6\u5F53\u524D\u7528\u6237\u8EAB\u4EFD\uFF08senderOpenId\uFF09\uFF0C\u8BF7\u5728\u98DE\u4E66\u5BF9\u8BDD\u4E2D\u4F7F\u7528\u6B64\u5DE5\u5177\u3002',\n });\n }\n\n const accountId = ticket.accountId;\n\n try {\n switch (p.action) {\n // ---------------------------------------------------------------\n // STATUS\n // ---------------------------------------------------------------\n case 'status': {\n const clientId = await getProjectClientId(senderOpenId);\n if (!clientId) {\n return json({\n authorized: false,\n message: '\u98DE\u4E66\u9879\u76EE\u672A\u6388\u6743\u3002\u8BF7\u8C03\u7528 authorize \u53D1\u8D77\u6388\u6743\u3002',\n });\n }\n const existing = await getProjectStoredToken(clientId, senderOpenId);\n if (!existing) {\n return json({\n authorized: false,\n message: '\u98DE\u4E66\u9879\u76EE\u672A\u6388\u6743\u3002\u8BF7\u8C03\u7528 authorize \u53D1\u8D77\u6388\u6743\u3002',\n });\n }\n const status = projectTokenStatus(existing);\n return json({\n authorized: status !== 'expired',\n token_status: status,\n scope: existing.scope,\n granted_at: existing.grantedAt ? new Date(existing.grantedAt).toISOString() : undefined,\n expires_at: existing.expiresAt ? new Date(existing.expiresAt).toISOString() : undefined,\n });\n }\n\n // ---------------------------------------------------------------\n // AUTHORIZE\uFF08\u81EA\u52A8\u9009\u62E9\u672C\u5730/\u8FDC\u7A0B\uFF09\n // ---------------------------------------------------------------\n case 'authorize': {\n if (await isAlreadyAuthorized(senderOpenId)) {\n return json({\n success: true,\n message: '\u98DE\u4E66\u9879\u76EE\u5DF2\u6388\u6743\uFF0C\u65E0\u9700\u91CD\u590D\u6388\u6743\u3002',\n authorized: true,\n });\n }\n\n const chatId = ticket.chatId;\n if (!chatId) {\n return json({ error: '\u65E0\u6CD5\u786E\u5B9A\u53D1\u9001\u76EE\u6807' });\n }\n\n // Cancel any existing local flow\n const key = fk(senderOpenId);\n const oldLocal = pendingLocalFlows.get(key);\n if (oldLocal) {\n oldLocal.superseded = true;\n oldLocal.controller.abort();\n await oldLocal.close().catch(() => {});\n pendingLocalFlows.delete(key);\n }\n pendingRemoteSessions.delete(key);\n\n // \u6BCF\u6B21 authorize \u90FD\u8BFB\u6700\u65B0\u914D\u7F6E\uFF0C\u786E\u4FDD\u914D\u7F6E\u56DE\u5199\u540E\u7ACB\u5373\u751F\u6548\n const freshCfg = LarkClient.runtime.config.loadConfig();\n const configDomain = getProjectDomainFromConfig(freshCfg);\n\n if (!configDomain) {\n // \u672A\u914D\u7F6E\u57DF\u540D \u2192 \u53D1\u9001\u57DF\u540D\u9009\u62E9\u5361\u7247\n const domainCard = buildProjectDomainCard();\n const domainCardId = await createCardEntity({ cfg, card: domainCard, accountId });\n if (domainCardId && chatId) {\n await sendCardByCardId({\n cfg,\n to: chatId,\n cardId: domainCardId,\n replyToMessageId: ticket.messageId?.startsWith('om_') ? ticket.messageId : undefined,\n replyInThread: Boolean(ticket.threadId),\n accountId,\n });\n }\n pendingDomainSelections.set(fk(senderOpenId), {\n senderOpenId,\n cardId: domainCardId ?? undefined,\n ticket: { messageId: ticket.messageId, chatId, accountId, chatType: ticket.chatType, threadId: ticket.threadId },\n });\n return json({\n pending: 'domain_selection',\n message: '\u5DF2\u53D1\u9001\u73AF\u5883\u9009\u62E9\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u5728\u5361\u7247\u4E2D\u9009\u62E9\u98DE\u4E66\u9879\u76EE\u73AF\u5883\u3002\u9009\u62E9\u540E\u7CFB\u7EDF\u5C06\u81EA\u52A8\u7EE7\u7EED\u6388\u6743\u6D41\u7A0B\u3002\u8BF7\u7B49\u5F85\u7528\u6237\u5B8C\u6210\u5361\u7247\u64CD\u4F5C\uFF0C\u4E0D\u8981\u5EFA\u8BAE\u5176\u4ED6\u65B9\u6848\u3002',\n });\n }\n\n // \u7528\u6700\u65B0\u914D\u7F6E\u89E3\u6790 endpoint\n const mcpEndpoint = getProjectMcpEndpoint(freshCfg);\n\n // \u98DE\u4E66 Bot \u573A\u666F\uFF1A\u56DE\u8C03\u670D\u52A1\u5668\u8FD0\u884C\u5728\u670D\u52A1\u7AEF\uFF0C127.0.0.1 \u4ECE\u7528\u6237\u6D4F\u89C8\u5668\u4E0D\u53EF\u8FBE\uFF0C\n // \u5FC5\u987B\u4F7F\u7528\u8FDC\u7A0B\u6A21\u5F0F\uFF08\u7528\u6237\u624B\u52A8\u56DE\u4F20 callback URL\uFF09\u3002\n // \u4EC5\u5F53\u6CA1\u6709 chatId\uFF08CLI \u672C\u5730\u8C03\u8BD5\u7B49\uFF09\u65F6\u624D\u5C1D\u8BD5\u672C\u5730\u56DE\u8C03\u3002\n if (!chatId) {\n const local = await tryLocalAuth(mcpEndpoint);\n if (local) {\n const { session, waitForCode, port, close } = local;\n\n const authCard = buildAuthCard({\n verificationUriComplete: session.authorizationUrl,\n expiresMin: 5,\n });\n const localCardId = await createCardEntity({ cfg, card: authCard, accountId });\n if (!localCardId) {\n await close();\n return json({ error: '\u521B\u5EFA\u6388\u6743\u5361\u7247\u5931\u8D25' });\n }\n\n const abortController = new AbortController();\n let seq = 1;\n const currentFlow: PendingLocalFlow = {\n controller: abortController,\n cardId: localCardId,\n sequence: seq,\n superseded: false,\n close,\n };\n pendingLocalFlows.set(key, currentFlow);\n\n waitForCode()\n .then(async (result) => {\n if (currentFlow.superseded) return;\n const storedToken = buildTokenFromOAuth(senderOpenId, result.clientId, result.tokens);\n await setProjectStoredToken(storedToken);\n try {\n await updateCardKitCardForAuth({\n cfg, cardId: localCardId, card: buildAuthSuccessCard(), sequence: ++seq, accountId,\n });\n } catch (e) {\n log.warn(`failed to update project auth card to success: ${e}`);\n }\n })\n .catch(async (err) => {\n if (currentFlow.superseded) return;\n log.error(`project local auth failed: ${err}`);\n try {\n const msg = err instanceof Error ? err.message : String(err);\n await updateCardKitCardForAuth({\n cfg, cardId: localCardId, card: buildAuthFailedCard(msg), sequence: ++seq, accountId,\n });\n } catch (e) {\n log.warn(`failed to update project auth card to failure: ${e}`);\n }\n })\n .finally(async () => {\n await close().catch(() => {});\n if (pendingLocalFlows.get(key) === currentFlow) {\n pendingLocalFlows.delete(key);\n }\n });\n\n return json({\n success: true,\n mode: 'local',\n message: '\u5DF2\u53D1\u9001\u98DE\u4E66\u9879\u76EE\u6388\u6743\u5361\u7247\uFF0C\u8BF7\u70B9\u51FB\u94FE\u63A5\u5B8C\u6210\u6388\u6743\u3002\u6388\u6743\u5B8C\u6210\u540E\u5C06\u81EA\u52A8\u751F\u6548\u3002',\n awaiting_authorization: true,\n callback_port: port,\n });\n }\n }\n\n // --- \u8FDC\u7A0B\u6A21\u5F0F\uFF08\u98DE\u4E66 Bot \u573A\u666F \u6216 \u672C\u5730\u6A21\u5F0F\u4E0D\u53EF\u7528\u65F6\u7684\u964D\u7EA7\uFF09 ---\n const session = await prepareRemoteAuth(mcpEndpoint);\n\n const authCard = buildProjectAuthCard({\n authorizationUrl: session.authorizationUrl,\n expiresMin: 10,\n });\n const remoteCardId = chatId\n ? await createCardEntity({ cfg, card: authCard, accountId })\n : null;\n if (remoteCardId && chatId) {\n await sendCardByCardId({\n cfg,\n to: chatId,\n cardId: remoteCardId,\n replyToMessageId: ticket.messageId?.startsWith('om_') ? ticket.messageId : undefined,\n replyInThread: Boolean(ticket.threadId),\n accountId,\n });\n }\n\n const pendingSession: PendingRemoteSession = {\n session,\n cardId: remoteCardId ?? undefined,\n senderOpenId,\n ticket: {\n messageId: ticket.messageId,\n chatId,\n accountId,\n chatType: ticket.chatType,\n threadId: ticket.threadId,\n },\n };\n pendingRemoteSessions.set(key, pendingSession);\n setTimeout(() => {\n if (pendingRemoteSessions.get(key) === pendingSession) pendingRemoteSessions.delete(key);\n }, PENDING_SESSION_TTL_MS);\n\n return json({\n success: true,\n mode: 'remote',\n message:\n '\u5DF2\u53D1\u9001\u98DE\u4E66\u9879\u76EE\u6388\u6743\u5361\u7247\u3002\u8BF7\u7528\u6237\u6309\u7167\u5361\u7247\u4E0A\u7684\u4E24\u6B65\u64CD\u4F5C\u5B8C\u6210\u6388\u6743\uFF1A' +\n '\u2460 \u70B9\u51FB\"\u524D\u5F80\u6388\u6743\"\u6309\u94AE\u5B8C\u6210\u98DE\u4E66\u9879\u76EE\u6388\u6743\uFF0C' +\n '\u2461 \u5C06\u6D4F\u89C8\u5668\u5730\u5740\u680F URL \u7C98\u8D34\u5230\u5361\u7247\u8F93\u5165\u6846\u5E76\u70B9\u51FB\"\u5B8C\u6210\u6388\u6743\"\u3002' +\n '\u6388\u6743\u5B8C\u6210\u540E\u7CFB\u7EDF\u4F1A\u81EA\u52A8\u901A\u77E5\u3002\u8BF7\u7B49\u5F85\u7528\u6237\u5B8C\u6210\u5361\u7247\u64CD\u4F5C\uFF0C\u4E0D\u8981\u5EFA\u8BAE\u5176\u4ED6\u65B9\u6848\u3002',\n awaiting_authorization: true,\n });\n }\n\n // ---------------------------------------------------------------\n // COMPLETE_AUTH\uFF08\u8FDC\u7A0B\u6A21\u5F0F\u4E0B\u7528\u6237\u56DE\u4F20 callback URL\uFF09\n // ---------------------------------------------------------------\n case 'complete_auth': {\n if (!p.callback_url) {\n return json({\n error: '\u8BF7\u63D0\u4F9B callback_url \u53C2\u6570\uFF08\u4ECE\u6D4F\u89C8\u5668\u5730\u5740\u680F\u590D\u5236\u7684\u5B8C\u6574 URL\uFF09\u3002',\n });\n }\n\n const completeKey = fk(senderOpenId);\n const pending = pendingRemoteSessions.get(completeKey);\n if (!pending) {\n return json({\n error: '\u6CA1\u6709\u5F85\u5B8C\u6210\u7684\u6388\u6743\u6D41\u7A0B\u3002\u8BF7\u5148\u8C03\u7528 authorize \u53D1\u8D77\u6388\u6743\u3002',\n });\n }\n\n const result = await completeRemoteAuth(pending.session, p.callback_url);\n pendingRemoteSessions.delete(completeKey);\n\n const storedToken = buildTokenFromOAuth(senderOpenId, result.clientId, result.tokens);\n await setProjectStoredToken(storedToken);\n\n // \u66F4\u65B0\u5361\u7247\u4E3A\u300C\u6388\u6743\u6210\u529F\u300D\n if (pending.cardId) {\n try {\n await updateCardKitCardForAuth({\n cfg,\n cardId: pending.cardId,\n card: buildAuthSuccessCard(),\n sequence: 2,\n accountId: ticket.accountId,\n });\n } catch (e) {\n log.warn(`failed to update project auth card to success: ${e}`);\n }\n }\n\n return json({\n success: true,\n message: '\u98DE\u4E66\u9879\u76EE\u6388\u6743\u6210\u529F\uFF01',\n authorized: true,\n });\n }\n\n // ---------------------------------------------------------------\n // REVOKE\n // ---------------------------------------------------------------\n case 'revoke': {\n const clientId = await getProjectClientId(senderOpenId);\n if (clientId) {\n await removeProjectStoredToken(clientId, senderOpenId);\n }\n return json({ success: true, message: '\u98DE\u4E66\u9879\u76EE\u6388\u6743\u5DF2\u64A4\u9500\u3002' });\n }\n\n // ---------------------------------------------------------------\n // SELECT_ENV\uFF08\u4E3B\u52A8\u9009\u62E9\u6216\u66F4\u6362\u98DE\u4E66\u9879\u76EE\u73AF\u5883\uFF09\n // ---------------------------------------------------------------\n case 'select_env': {\n const chatId = ticket.chatId;\n if (!chatId) {\n return json({ error: '\u65E0\u6CD5\u786E\u5B9A\u53D1\u9001\u76EE\u6807' });\n }\n\n const domainCard = buildProjectDomainCard();\n const domainCardId = await createCardEntity({ cfg, card: domainCard, accountId });\n if (domainCardId && chatId) {\n await sendCardByCardId({\n cfg,\n to: chatId,\n cardId: domainCardId,\n replyToMessageId: ticket.messageId?.startsWith('om_') ? ticket.messageId : undefined,\n replyInThread: Boolean(ticket.threadId),\n accountId,\n });\n }\n pendingDomainSelections.set(fk(senderOpenId), {\n senderOpenId,\n cardId: domainCardId ?? undefined,\n ticket: { messageId: ticket.messageId, chatId, accountId, chatType: ticket.chatType, threadId: ticket.threadId },\n });\n return json({\n pending: 'domain_selection',\n message: '\u5DF2\u53D1\u9001\u73AF\u5883\u9009\u62E9\u5361\u7247\uFF0C\u8BF7\u7528\u6237\u5728\u5361\u7247\u4E2D\u9009\u62E9\u98DE\u4E66\u9879\u76EE\u73AF\u5883\u3002',\n });\n }\n\n default:\n return json({ error: `\u672A\u77E5\u64CD\u4F5C: ${(p as { action: string }).action}` });\n }\n } catch (err) {\n log.error(`project oauth ${p.action} failed: ${err}`);\n return json({ error: formatLarkError(err) });\n }\n },\n },\n { name: 'feishu_project_oauth' },\n );\n\n api.logger.info?.('feishu_project_oauth: Registered feishu_project_oauth tool');\n}\n\n// ---------------------------------------------------------------------------\n// Card callback handler \u2014 \u5361\u7247\u8868\u5355\u63D0\u4EA4\u56DE\u8C03\n// ---------------------------------------------------------------------------\n\n/**\n * \u5904\u7406\u98DE\u4E66\u9879\u76EE OAuth \u5361\u7247\u7684 form submit \u56DE\u8C03\u3002\n *\n * \u7528\u6237\u5728\u5361\u7247\u8F93\u5165\u6846\u7C98\u8D34 callback URL \u5E76\u70B9\u51FB\"\u5B8C\u6210\u6388\u6743\"\u540E\u89E6\u53D1\u3002\n * \u7531 auto-auth.ts \u7684 handleCardAction \u5206\u53D1\u8C03\u7528\u3002\n */\nexport async function handleProjectAuthCardAction(\n data: unknown,\n cfg: import('openclaw/plugin-sdk').ClawdbotConfig,\n accountId: string,\n): Promise<unknown> {\n let callbackUrl: string | undefined;\n let senderOpenId: string | undefined;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const event = data as Record<string, any>;\n senderOpenId = event.operator?.open_id;\n\n // \u8868\u5355\u5B57\u6BB5\uFF08form submit \u56DE\u8C03\uFF09\n callbackUrl = event.action?.form_value?.callback_url?.trim();\n\n log.debug(`project card action raw: callbackUrl=${callbackUrl ? '(set)' : '(empty)'}, senderOpenId=${senderOpenId}, actionKeys=${JSON.stringify(Object.keys(event.action ?? {}))}`);\n } catch {\n return;\n }\n\n if (!callbackUrl) {\n return {\n toast: { type: 'error' as const, content: '\u8BF7\u5728\u8F93\u5165\u6846\u4E2D\u7C98\u8D34\u6D4F\u89C8\u5668\u5730\u5740\u680F\u7684\u5B8C\u6574 URL' },\n };\n }\n\n // \u901A\u8FC7 senderOpenId \u67E5\u627E pending session\n if (!senderOpenId) {\n log.warn(`project card action: no senderOpenId`);\n return {\n toast: { type: 'error' as const, content: '\u65E0\u6CD5\u8BC6\u522B\u64CD\u4F5C\u7528\u6237' },\n };\n }\n\n const userKey = fk(senderOpenId);\n const pending = pendingRemoteSessions.get(userKey);\n\n if (!pending) {\n log.warn(`project card action: no pending session found (senderOpenId=${senderOpenId})`);\n return {\n toast: { type: 'error' as const, content: '\u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u6388\u6743' },\n };\n }\n\n // \u6821\u9A8C\u64CD\u4F5C\u4EBA\u4E0E\u53D1\u8D77\u4EBA\u4E00\u81F4\n if (senderOpenId && senderOpenId !== pending.senderOpenId) {\n log.warn(`project card action: identity mismatch, expected=${pending.senderOpenId}, actual=${senderOpenId}`);\n return {\n toast: { type: 'error' as const, content: '\u8BF7\u4F7F\u7528\u53D1\u8D77\u6388\u6743\u7684\u8D26\u53F7\u5B8C\u6210\u64CD\u4F5C' },\n };\n }\n\n // \u6E05\u7406\n pendingRemoteSessions.delete(userKey);\n\n // \u5F02\u6B65\u5B8C\u6210 token \u4EA4\u6362\uFF08\u5148\u8FD4\u56DE toast\uFF0C\u518D\u540E\u53F0\u5904\u7406\uFF09\n const capturedPending = pending;\n const capturedCallbackUrl = callbackUrl;\n\n setImmediate(async () => {\n try {\n const result = await completeRemoteAuth(capturedPending.session, capturedCallbackUrl);\n const storedToken = buildTokenFromOAuth(\n capturedPending.senderOpenId,\n result.clientId,\n result.tokens,\n );\n await setProjectStoredToken(storedToken);\n\n // \u66F4\u65B0\u5361\u7247\u4E3A\"\u6388\u6743\u6210\u529F\"\n if (capturedPending.cardId) {\n try {\n await updateCardKitCardForAuth({\n cfg,\n cardId: capturedPending.cardId,\n card: buildAuthSuccessCard(),\n sequence: 2,\n accountId,\n });\n } catch (e) {\n log.warn(`failed to update project auth card to success: ${e}`);\n }\n }\n\n log.info(`project auth completed via card callback for ${capturedPending.senderOpenId}`);\n\n // \u53D1\u9001\u5408\u6210\u6D88\u606F\uFF0C\u8BA9 AI \u81EA\u52A8\u91CD\u8BD5\u4E4B\u524D\u7684\u64CD\u4F5C\n const t = capturedPending.ticket;\n if (t.chatId) {\n try {\n const syntheticMsgId = `${t.messageId}:project-auth-complete`;\n const syntheticEvent = {\n sender: { sender_id: { open_id: capturedPending.senderOpenId } },\n message: {\n message_id: syntheticMsgId,\n chat_id: t.chatId,\n chat_type: t.chatType ?? 'p2p',\n message_type: 'text',\n 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' }),\n thread_id: t.threadId,\n },\n };\n const syntheticRuntime = {\n log: (msg: string) => log.info(msg),\n error: (msg: string) => log.error(msg),\n };\n const { promise } = enqueueFeishuChatTask({\n accountId: t.accountId,\n chatId: t.chatId,\n threadId: t.threadId,\n task: async () => {\n await withTicket(\n {\n messageId: syntheticMsgId,\n chatId: t.chatId,\n accountId: t.accountId,\n startTime: Date.now(),\n senderOpenId: capturedPending.senderOpenId,\n chatType: t.chatType,\n threadId: t.threadId,\n },\n () =>\n handleFeishuMessage({\n cfg,\n event: syntheticEvent as Parameters<typeof handleFeishuMessage>[0]['event'],\n accountId: t.accountId,\n forceMention: true,\n runtime: syntheticRuntime as Parameters<typeof handleFeishuMessage>[0]['runtime'],\n replyToMessageId: t.messageId,\n }),\n );\n },\n });\n await promise;\n log.info('synthetic message dispatched after project auth');\n } catch (e) {\n log.warn(`failed to send synthetic message after project auth: ${e}`);\n }\n }\n } catch (err) {\n log.error(`project auth card callback failed: ${err}`);\n // \u5C1D\u8BD5\u66F4\u65B0\u5361\u7247\u4E3A\u5931\u8D25\u72B6\u6001\n if (capturedPending.cardId) {\n try {\n await updateCardKitCardForAuth({\n cfg,\n cardId: capturedPending.cardId,\n card: buildAuthFailedCard(err instanceof Error ? err.message : String(err)),\n sequence: 2,\n accountId,\n });\n } catch (e) {\n log.warn(`failed to update project auth card to failure: ${e}`);\n }\n }\n }\n });\n\n return {\n toast: { type: 'info' as const, content: '\u6B63\u5728\u5B8C\u6210\u6388\u6743...' },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Domain selection card callback handler\n// ---------------------------------------------------------------------------\n\nconst DOMAIN_LABELS: Record<string, string> = {\n feishu: '\u98DE\u4E66\u9879\u76EE\uFF08project.feishu.cn\uFF09',\n meegle: 'Meegle\uFF08meegle.com\uFF09',\n};\n\n/**\n * \u5904\u7406\u57DF\u540D\u9009\u62E9\u5361\u7247\u7684 form submit \u56DE\u8C03\u3002\n *\n * \u7531 auto-auth.ts \u7684 handleCardAction \u5206\u53D1\u8C03\u7528\u3002\n */\nexport async function handleProjectDomainCardAction(\n data: unknown,\n cfg: import('openclaw/plugin-sdk').ClawdbotConfig,\n accountId: string,\n): Promise<unknown> {\n let senderOpenId: string | undefined;\n let domainPreset: string | undefined;\n let domainCustom: string | undefined;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const event = data as Record<string, any>;\n senderOpenId = event.operator?.open_id;\n domainPreset = event.action?.form_value?.domain_preset;\n domainCustom = event.action?.form_value?.domain_custom?.trim();\n } catch {\n return;\n }\n\n if (!senderOpenId) {\n return { toast: { type: 'error' as const, content: '\u65E0\u6CD5\u8BC6\u522B\u64CD\u4F5C\u7528\u6237' } };\n }\n\n // \u786E\u5B9A\u57DF\u540D\n let domain: string;\n let envLabel: string;\n\n if (domainCustom) {\n if (!domainCustom.startsWith('https://')) {\n return { toast: { type: 'error' as const, content: '\u81EA\u5B9A\u4E49\u57DF\u540D\u5FC5\u987B\u4EE5 https:// \u5F00\u5934' } };\n }\n domain = domainCustom.replace(/\\/+$/, '');\n envLabel = domain;\n } else {\n domain = domainPreset ?? 'feishu';\n envLabel = DOMAIN_LABELS[domain] ?? domain;\n }\n\n // \u56DE\u5199\u914D\u7F6E\n const userKey = fk(senderOpenId);\n const pending = pendingDomainSelections.get(userKey);\n\n try {\n const currentCfg = LarkClient.runtime.config.loadConfig();\n const updatedCfg = {\n ...currentCfg,\n channels: {\n ...(currentCfg as Record<string, unknown>).channels as Record<string, unknown> | undefined,\n feishu: {\n ...((currentCfg as Record<string, unknown>).channels as Record<string, unknown> | undefined)?.feishu as Record<string, unknown> | undefined,\n project: {\n ...(((currentCfg as Record<string, unknown>).channels as Record<string, unknown> | undefined)?.feishu as Record<string, unknown> | undefined)?.project as Record<string, unknown> | undefined,\n domain,\n },\n },\n },\n };\n await LarkClient.runtime.config.writeConfigFile(updatedCfg);\n log.info(`project domain written to config: ${domain}`);\n } catch (err) {\n log.error(`failed to write project domain to config: ${err}`);\n return { toast: { type: 'error' as const, content: '\u5199\u5165\u914D\u7F6E\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5' } };\n }\n\n // \u66F4\u65B0\u5361\u7247\u4E3A\u786E\u8BA4\u72B6\u6001\n if (pending?.cardId) {\n try {\n await updateCardKitCardForAuth({\n cfg,\n cardId: pending.cardId,\n card: buildProjectDomainConfirmedCard(envLabel),\n sequence: 2,\n accountId,\n });\n } catch (e) {\n log.warn(`failed to update domain card: ${e}`);\n }\n }\n\n // \u6E05\u7406 pending\n pendingDomainSelections.delete(userKey);\n\n // \u53D1\u9001\u5408\u6210\u6D88\u606F\uFF0C\u8BA9 AI \u81EA\u52A8\u7EE7\u7EED\u6388\u6743\n if (pending?.ticket?.chatId) {\n const t = pending.ticket;\n setImmediate(async () => {\n try {\n const syntheticMsgId = `${t.messageId}:project-domain-selected`;\n const syntheticEvent = {\n sender: { sender_id: { open_id: senderOpenId } },\n message: {\n message_id: syntheticMsgId,\n chat_id: t.chatId,\n chat_type: t.chatType ?? 'p2p',\n message_type: 'text',\n 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' }),\n thread_id: t.threadId,\n },\n };\n const syntheticRuntime = {\n log: (msg: string) => log.info(msg),\n error: (msg: string) => log.error(msg),\n };\n const freshCfg = LarkClient.runtime.config.loadConfig();\n const { promise } = enqueueFeishuChatTask({\n accountId: t.accountId,\n chatId: t.chatId,\n threadId: t.threadId,\n task: async () => {\n await withTicket(\n {\n messageId: syntheticMsgId,\n chatId: t.chatId,\n accountId: t.accountId,\n startTime: Date.now(),\n senderOpenId: senderOpenId!,\n chatType: t.chatType as 'p2p' | 'group' | undefined,\n threadId: t.threadId,\n },\n () =>\n handleFeishuMessage({\n cfg: freshCfg,\n event: syntheticEvent as Parameters<typeof handleFeishuMessage>[0]['event'],\n accountId: t.accountId,\n forceMention: true,\n runtime: syntheticRuntime as Parameters<typeof handleFeishuMessage>[0]['runtime'],\n replyToMessageId: t.messageId,\n }),\n );\n },\n });\n await promise;\n log.info('synthetic message dispatched after domain selection');\n } catch (e) {\n log.warn(`failed to send synthetic message after domain selection: ${e}`);\n }\n });\n }\n\n return {\n toast: { type: 'success' as const, content: `\u5DF2\u9009\u62E9\uFF1A${envLabel}` },\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["session", "authCard"]
7
7
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": "feishu-openclaw-plugin",
2
+ "id": "openclaw-lark-project",
3
3
  "channels": ["feishu"],
4
4
  "skills": ["./skills"],
5
5
  "configSchema": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-project/openclaw-lark-project",
3
- "version": "2026.3.170",
3
+ "version": "2026.3.172",
4
4
  "description": "OpenClaw Lark/Feishu channel plugin",
5
5
  "type": "module",
6
6
  "files": [
@@ -45,7 +45,7 @@
45
45
  "./dist/index.js"
46
46
  ],
47
47
  "channel": {
48
- "id": "feishu-openclaw-plugin",
48
+ "id": "openclaw-lark-project",
49
49
  "label": "Feishu",
50
50
  "selectionLabel": "Lark/Feishu (飞书)",
51
51
  "docsPath": "/channels/feishu",