@lark-project/openclaw-lark-project 2026.3.131
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/LICENSE +21 -0
- package/README.md +80 -0
- package/README.zh.md +80 -0
- package/dist/index.js +172 -0
- package/dist/index.js.map +7 -0
- package/dist/skills/feishu-bitable/SKILL.md +248 -0
- package/dist/skills/feishu-bitable/references/examples.md +813 -0
- package/dist/skills/feishu-bitable/references/field-properties.md +763 -0
- package/dist/skills/feishu-bitable/references/record-values.md +911 -0
- package/dist/skills/feishu-calendar/SKILL.md +244 -0
- package/dist/skills/feishu-channel-rules/SKILL.md +18 -0
- package/dist/skills/feishu-channel-rules/references/markdown-syntax.md +138 -0
- package/dist/skills/feishu-create-doc/SKILL.md +719 -0
- package/dist/skills/feishu-fetch-doc/SKILL.md +93 -0
- package/dist/skills/feishu-im-read/SKILL.md +163 -0
- package/dist/skills/feishu-project/SKILL.md +122 -0
- package/dist/skills/feishu-task/SKILL.md +293 -0
- package/dist/skills/feishu-troubleshoot/SKILL.md +70 -0
- package/dist/skills/feishu-update-doc/SKILL.md +285 -0
- package/dist/src/card/builder.js +293 -0
- package/dist/src/card/builder.js.map +7 -0
- package/dist/src/card/cardkit.js +126 -0
- package/dist/src/card/cardkit.js.map +7 -0
- package/dist/src/card/flush-controller.js +107 -0
- package/dist/src/card/flush-controller.js.map +7 -0
- package/dist/src/card/markdown-style.js +57 -0
- package/dist/src/card/markdown-style.js.map +7 -0
- package/dist/src/card/reply-dispatcher-types.js +39 -0
- package/dist/src/card/reply-dispatcher-types.js.map +7 -0
- package/dist/src/card/reply-dispatcher.js +245 -0
- package/dist/src/card/reply-dispatcher.js.map +7 -0
- package/dist/src/card/reply-mode.js +29 -0
- package/dist/src/card/reply-mode.js.map +7 -0
- package/dist/src/card/streaming-card-controller.js +653 -0
- package/dist/src/card/streaming-card-controller.js.map +7 -0
- package/dist/src/card/unavailable-guard.js +76 -0
- package/dist/src/card/unavailable-guard.js.map +7 -0
- package/dist/src/channel/abort-detect.js +79 -0
- package/dist/src/channel/abort-detect.js.map +7 -0
- package/dist/src/channel/chat-queue.js +50 -0
- package/dist/src/channel/chat-queue.js.map +7 -0
- package/dist/src/channel/config-adapter.js +89 -0
- package/dist/src/channel/config-adapter.js.map +7 -0
- package/dist/src/channel/directory.js +133 -0
- package/dist/src/channel/directory.js.map +7 -0
- package/dist/src/channel/event-handlers.js +175 -0
- package/dist/src/channel/event-handlers.js.map +7 -0
- package/dist/src/channel/monitor.js +108 -0
- package/dist/src/channel/monitor.js.map +7 -0
- package/dist/src/channel/onboarding-config.js +76 -0
- package/dist/src/channel/onboarding-config.js.map +7 -0
- package/dist/src/channel/onboarding-migrate.js +55 -0
- package/dist/src/channel/onboarding-migrate.js.map +7 -0
- package/dist/src/channel/onboarding.js +285 -0
- package/dist/src/channel/onboarding.js.map +7 -0
- package/dist/src/channel/plugin.js +260 -0
- package/dist/src/channel/plugin.js.map +7 -0
- package/dist/src/channel/probe.js +14 -0
- package/dist/src/channel/probe.js.map +7 -0
- package/dist/src/channel/types.js +1 -0
- package/dist/src/channel/types.js.map +7 -0
- package/dist/src/commands/auth.js +73 -0
- package/dist/src/commands/auth.js.map +7 -0
- package/dist/src/commands/diagnose.js +658 -0
- package/dist/src/commands/diagnose.js.map +7 -0
- package/dist/src/commands/doctor.js +327 -0
- package/dist/src/commands/doctor.js.map +7 -0
- package/dist/src/commands/index.js +124 -0
- package/dist/src/commands/index.js.map +7 -0
- package/dist/src/core/accounts.js +129 -0
- package/dist/src/core/accounts.js.map +7 -0
- package/dist/src/core/agent-config.js +60 -0
- package/dist/src/core/agent-config.js.map +7 -0
- package/dist/src/core/api-error.js +55 -0
- package/dist/src/core/api-error.js.map +7 -0
- package/dist/src/core/app-owner-fallback.js +17 -0
- package/dist/src/core/app-owner-fallback.js.map +7 -0
- package/dist/src/core/app-scope-checker.js +95 -0
- package/dist/src/core/app-scope-checker.js.map +7 -0
- package/dist/src/core/auth-errors.js +120 -0
- package/dist/src/core/auth-errors.js.map +7 -0
- package/dist/src/core/chat-info-cache.js +102 -0
- package/dist/src/core/chat-info-cache.js.map +7 -0
- package/dist/src/core/config-schema.js +150 -0
- package/dist/src/core/config-schema.js.map +7 -0
- package/dist/src/core/device-flow.js +174 -0
- package/dist/src/core/device-flow.js.map +7 -0
- package/dist/src/core/feishu-fetch.js +12 -0
- package/dist/src/core/feishu-fetch.js.map +7 -0
- package/dist/src/core/footer-config.js +16 -0
- package/dist/src/core/footer-config.js.map +7 -0
- package/dist/src/core/lark-client.js +322 -0
- package/dist/src/core/lark-client.js.map +7 -0
- package/dist/src/core/lark-logger.js +92 -0
- package/dist/src/core/lark-logger.js.map +7 -0
- package/dist/src/core/lark-ticket.js +18 -0
- package/dist/src/core/lark-ticket.js.map +7 -0
- package/dist/src/core/message-unavailable.js +119 -0
- package/dist/src/core/message-unavailable.js.map +7 -0
- package/dist/src/core/owner-policy.js +25 -0
- package/dist/src/core/owner-policy.js.map +7 -0
- package/dist/src/core/permission-url.js +37 -0
- package/dist/src/core/permission-url.js.map +7 -0
- package/dist/src/core/project-auth.js +177 -0
- package/dist/src/core/project-auth.js.map +7 -0
- package/dist/src/core/project-oauth-flow.js +124 -0
- package/dist/src/core/project-oauth-flow.js.map +7 -0
- package/dist/src/core/project-token-store.js +172 -0
- package/dist/src/core/project-token-store.js.map +7 -0
- package/dist/src/core/raw-request.js +45 -0
- package/dist/src/core/raw-request.js.map +7 -0
- package/dist/src/core/scope-manager.js +62 -0
- package/dist/src/core/scope-manager.js.map +7 -0
- package/dist/src/core/security-check.js +118 -0
- package/dist/src/core/security-check.js.map +7 -0
- package/dist/src/core/shutdown-hooks.js +37 -0
- package/dist/src/core/shutdown-hooks.js.map +7 -0
- package/dist/src/core/targets.js +55 -0
- package/dist/src/core/targets.js.map +7 -0
- package/dist/src/core/token-store.js +215 -0
- package/dist/src/core/token-store.js.map +7 -0
- package/dist/src/core/tool-client.js +335 -0
- package/dist/src/core/tool-client.js.map +7 -0
- package/dist/src/core/tool-scopes.js +207 -0
- package/dist/src/core/tool-scopes.js.map +7 -0
- package/dist/src/core/tools-config.js +57 -0
- package/dist/src/core/tools-config.js.map +7 -0
- package/dist/src/core/types.js +1 -0
- package/dist/src/core/types.js.map +7 -0
- package/dist/src/core/uat-client.js +124 -0
- package/dist/src/core/uat-client.js.map +7 -0
- package/dist/src/core/version.js +27 -0
- package/dist/src/core/version.js.map +7 -0
- package/dist/src/messaging/converters/audio.js +19 -0
- package/dist/src/messaging/converters/audio.js.map +7 -0
- package/dist/src/messaging/converters/calendar.js +46 -0
- package/dist/src/messaging/converters/calendar.js.map +7 -0
- package/dist/src/messaging/converters/content-converter.js +61 -0
- package/dist/src/messaging/converters/content-converter.js.map +7 -0
- package/dist/src/messaging/converters/file.js +18 -0
- package/dist/src/messaging/converters/file.js.map +7 -0
- package/dist/src/messaging/converters/folder.js +18 -0
- package/dist/src/messaging/converters/folder.js.map +7 -0
- package/dist/src/messaging/converters/hongbao.js +14 -0
- package/dist/src/messaging/converters/hongbao.js.map +7 -0
- package/dist/src/messaging/converters/image.js +16 -0
- package/dist/src/messaging/converters/image.js.map +7 -0
- package/dist/src/messaging/converters/index.js +48 -0
- package/dist/src/messaging/converters/index.js.map +7 -0
- package/dist/src/messaging/converters/interactive/card-converter.js +1040 -0
- package/dist/src/messaging/converters/interactive/card-converter.js.map +7 -0
- package/dist/src/messaging/converters/interactive/card-utils.js +36 -0
- package/dist/src/messaging/converters/interactive/card-utils.js.map +7 -0
- package/dist/src/messaging/converters/interactive/index.js +19 -0
- package/dist/src/messaging/converters/interactive/index.js.map +7 -0
- package/dist/src/messaging/converters/interactive/legacy.js +53 -0
- package/dist/src/messaging/converters/interactive/legacy.js.map +7 -0
- package/dist/src/messaging/converters/interactive/types.js +23 -0
- package/dist/src/messaging/converters/interactive/types.js.map +7 -0
- package/dist/src/messaging/converters/location.js +17 -0
- package/dist/src/messaging/converters/location.js.map +7 -0
- package/dist/src/messaging/converters/merge-forward.js +143 -0
- package/dist/src/messaging/converters/merge-forward.js.map +7 -0
- package/dist/src/messaging/converters/post.js +113 -0
- package/dist/src/messaging/converters/post.js.map +7 -0
- package/dist/src/messaging/converters/share.js +22 -0
- package/dist/src/messaging/converters/share.js.map +7 -0
- package/dist/src/messaging/converters/sticker.js +16 -0
- package/dist/src/messaging/converters/sticker.js.map +7 -0
- package/dist/src/messaging/converters/system.js +25 -0
- package/dist/src/messaging/converters/system.js.map +7 -0
- package/dist/src/messaging/converters/text.js +12 -0
- package/dist/src/messaging/converters/text.js.map +7 -0
- package/dist/src/messaging/converters/todo.js +37 -0
- package/dist/src/messaging/converters/todo.js.map +7 -0
- package/dist/src/messaging/converters/types.js +1 -0
- package/dist/src/messaging/converters/types.js.map +7 -0
- package/dist/src/messaging/converters/unknown.js +13 -0
- package/dist/src/messaging/converters/unknown.js.map +7 -0
- package/dist/src/messaging/converters/utils.js +35 -0
- package/dist/src/messaging/converters/utils.js.map +7 -0
- package/dist/src/messaging/converters/video-chat.js +21 -0
- package/dist/src/messaging/converters/video-chat.js.map +7 -0
- package/dist/src/messaging/converters/video.js +30 -0
- package/dist/src/messaging/converters/video.js.map +7 -0
- package/dist/src/messaging/converters/vote.js +24 -0
- package/dist/src/messaging/converters/vote.js.map +7 -0
- package/dist/src/messaging/inbound/dedup.js +82 -0
- package/dist/src/messaging/inbound/dedup.js.map +7 -0
- package/dist/src/messaging/inbound/dispatch-builders.js +98 -0
- package/dist/src/messaging/inbound/dispatch-builders.js.map +7 -0
- package/dist/src/messaging/inbound/dispatch-commands.js +94 -0
- package/dist/src/messaging/inbound/dispatch-commands.js.map +7 -0
- package/dist/src/messaging/inbound/dispatch-context.js +96 -0
- package/dist/src/messaging/inbound/dispatch-context.js.map +7 -0
- package/dist/src/messaging/inbound/dispatch.js +150 -0
- package/dist/src/messaging/inbound/dispatch.js.map +7 -0
- package/dist/src/messaging/inbound/enrich.js +137 -0
- package/dist/src/messaging/inbound/enrich.js.map +7 -0
- package/dist/src/messaging/inbound/gate-effects.js +28 -0
- package/dist/src/messaging/inbound/gate-effects.js.map +7 -0
- package/dist/src/messaging/inbound/gate.js +163 -0
- package/dist/src/messaging/inbound/gate.js.map +7 -0
- package/dist/src/messaging/inbound/handler.js +132 -0
- package/dist/src/messaging/inbound/handler.js.map +7 -0
- package/dist/src/messaging/inbound/media-resolver.js +70 -0
- package/dist/src/messaging/inbound/media-resolver.js.map +7 -0
- package/dist/src/messaging/inbound/mention.js +50 -0
- package/dist/src/messaging/inbound/mention.js.map +7 -0
- package/dist/src/messaging/inbound/parse-io.js +41 -0
- package/dist/src/messaging/inbound/parse-io.js.map +7 -0
- package/dist/src/messaging/inbound/parse.js +79 -0
- package/dist/src/messaging/inbound/parse.js.map +7 -0
- package/dist/src/messaging/inbound/permission.js +30 -0
- package/dist/src/messaging/inbound/permission.js.map +7 -0
- package/dist/src/messaging/inbound/policy.js +83 -0
- package/dist/src/messaging/inbound/policy.js.map +7 -0
- package/dist/src/messaging/inbound/reaction-handler.js +162 -0
- package/dist/src/messaging/inbound/reaction-handler.js.map +7 -0
- package/dist/src/messaging/inbound/user-name-cache.js +172 -0
- package/dist/src/messaging/inbound/user-name-cache.js.map +7 -0
- package/dist/src/messaging/outbound/actions.js +239 -0
- package/dist/src/messaging/outbound/actions.js.map +7 -0
- package/dist/src/messaging/outbound/chat-manage.js +74 -0
- package/dist/src/messaging/outbound/chat-manage.js.map +7 -0
- package/dist/src/messaging/outbound/deliver.js +162 -0
- package/dist/src/messaging/outbound/deliver.js.map +7 -0
- package/dist/src/messaging/outbound/fetch.js +7 -0
- package/dist/src/messaging/outbound/fetch.js.map +7 -0
- package/dist/src/messaging/outbound/forward.js +31 -0
- package/dist/src/messaging/outbound/forward.js.map +7 -0
- package/dist/src/messaging/outbound/media-url-utils.js +101 -0
- package/dist/src/messaging/outbound/media-url-utils.js.map +7 -0
- package/dist/src/messaging/outbound/media.js +463 -0
- package/dist/src/messaging/outbound/media.js.map +7 -0
- package/dist/src/messaging/outbound/outbound.js +95 -0
- package/dist/src/messaging/outbound/outbound.js.map +7 -0
- package/dist/src/messaging/outbound/reactions.js +312 -0
- package/dist/src/messaging/outbound/reactions.js.map +7 -0
- package/dist/src/messaging/outbound/send.js +194 -0
- package/dist/src/messaging/outbound/send.js.map +7 -0
- package/dist/src/messaging/outbound/typing.js +77 -0
- package/dist/src/messaging/outbound/typing.js.map +7 -0
- package/dist/src/messaging/shared/message-lookup.js +84 -0
- package/dist/src/messaging/shared/message-lookup.js.map +7 -0
- package/dist/src/messaging/types.js +1 -0
- package/dist/src/messaging/types.js.map +7 -0
- package/dist/src/tools/auto-auth.js +714 -0
- package/dist/src/tools/auto-auth.js.map +7 -0
- package/dist/src/tools/helpers.js +133 -0
- package/dist/src/tools/helpers.js.map +7 -0
- package/dist/src/tools/mcp/doc/create.js +35 -0
- package/dist/src/tools/mcp/doc/create.js.map +7 -0
- package/dist/src/tools/mcp/doc/fetch.js +33 -0
- package/dist/src/tools/mcp/doc/fetch.js.map +7 -0
- package/dist/src/tools/mcp/doc/index.js +32 -0
- package/dist/src/tools/mcp/doc/index.js.map +7 -0
- package/dist/src/tools/mcp/doc/update.js +61 -0
- package/dist/src/tools/mcp/doc/update.js.map +7 -0
- package/dist/src/tools/mcp/project/endpoint.js +25 -0
- package/dist/src/tools/mcp/project/endpoint.js.map +7 -0
- package/dist/src/tools/mcp/project/index.js +27 -0
- package/dist/src/tools/mcp/project/index.js.map +7 -0
- package/dist/src/tools/mcp/project/tools.js +579 -0
- package/dist/src/tools/mcp/project/tools.js.map +7 -0
- package/dist/src/tools/mcp/shared.js +170 -0
- package/dist/src/tools/mcp/shared.js.map +7 -0
- package/dist/src/tools/oapi/bitable/app-table-field.js +244 -0
- package/dist/src/tools/oapi/bitable/app-table-field.js.map +7 -0
- package/dist/src/tools/oapi/bitable/app-table-record.js +501 -0
- package/dist/src/tools/oapi/bitable/app-table-record.js.map +7 -0
- package/dist/src/tools/oapi/bitable/app-table-view.js +226 -0
- package/dist/src/tools/oapi/bitable/app-table-view.js.map +7 -0
- package/dist/src/tools/oapi/bitable/app-table.js +278 -0
- package/dist/src/tools/oapi/bitable/app-table.js.map +7 -0
- package/dist/src/tools/oapi/bitable/app.js +200 -0
- package/dist/src/tools/oapi/bitable/app.js.map +7 -0
- package/dist/src/tools/oapi/bitable/index.js +13 -0
- package/dist/src/tools/oapi/bitable/index.js.map +7 -0
- package/dist/src/tools/oapi/calendar/calendar.js +131 -0
- package/dist/src/tools/oapi/calendar/calendar.js.map +7 -0
- package/dist/src/tools/oapi/calendar/event-attendee.js +301 -0
- package/dist/src/tools/oapi/calendar/event-attendee.js.map +7 -0
- package/dist/src/tools/oapi/calendar/event.js +834 -0
- package/dist/src/tools/oapi/calendar/event.js.map +7 -0
- package/dist/src/tools/oapi/calendar/freebusy.js +111 -0
- package/dist/src/tools/oapi/calendar/freebusy.js.map +7 -0
- package/dist/src/tools/oapi/calendar/index.js +11 -0
- package/dist/src/tools/oapi/calendar/index.js.map +7 -0
- package/dist/src/tools/oapi/chat/chat.js +132 -0
- package/dist/src/tools/oapi/chat/chat.js.map +7 -0
- package/dist/src/tools/oapi/chat/index.js +11 -0
- package/dist/src/tools/oapi/chat/index.js.map +7 -0
- package/dist/src/tools/oapi/chat/members.js +83 -0
- package/dist/src/tools/oapi/chat/members.js.map +7 -0
- package/dist/src/tools/oapi/common/get-user.js +95 -0
- package/dist/src/tools/oapi/common/get-user.js.map +7 -0
- package/dist/src/tools/oapi/common/index.js +7 -0
- package/dist/src/tools/oapi/common/index.js.map +7 -0
- package/dist/src/tools/oapi/common/search-user.js +67 -0
- package/dist/src/tools/oapi/common/search-user.js.map +7 -0
- package/dist/src/tools/oapi/drive/doc-comments.js +310 -0
- package/dist/src/tools/oapi/drive/doc-comments.js.map +7 -0
- package/dist/src/tools/oapi/drive/doc-media.js +314 -0
- package/dist/src/tools/oapi/drive/doc-media.js.map +7 -0
- package/dist/src/tools/oapi/drive/file.js +548 -0
- package/dist/src/tools/oapi/drive/file.js.map +7 -0
- package/dist/src/tools/oapi/drive/index.js +29 -0
- package/dist/src/tools/oapi/drive/index.js.map +7 -0
- package/dist/src/tools/oapi/helpers.js +199 -0
- package/dist/src/tools/oapi/helpers.js.map +7 -0
- package/dist/src/tools/oapi/im/format-messages.js +128 -0
- package/dist/src/tools/oapi/im/format-messages.js.map +7 -0
- package/dist/src/tools/oapi/im/index.js +15 -0
- package/dist/src/tools/oapi/im/index.js.map +7 -0
- package/dist/src/tools/oapi/im/message-read.js +404 -0
- package/dist/src/tools/oapi/im/message-read.js.map +7 -0
- package/dist/src/tools/oapi/im/message.js +179 -0
- package/dist/src/tools/oapi/im/message.js.map +7 -0
- package/dist/src/tools/oapi/im/resource.js +126 -0
- package/dist/src/tools/oapi/im/resource.js.map +7 -0
- package/dist/src/tools/oapi/im/time-utils.js +169 -0
- package/dist/src/tools/oapi/im/time-utils.js.map +7 -0
- package/dist/src/tools/oapi/im/user-name-uat.js +103 -0
- package/dist/src/tools/oapi/im/user-name-uat.js.map +7 -0
- package/dist/src/tools/oapi/index.js +56 -0
- package/dist/src/tools/oapi/index.js.map +7 -0
- package/dist/src/tools/oapi/sdk-types.js +1 -0
- package/dist/src/tools/oapi/sdk-types.js.map +7 -0
- package/dist/src/tools/oapi/search/doc-search.js +215 -0
- package/dist/src/tools/oapi/search/doc-search.js.map +7 -0
- package/dist/src/tools/oapi/search/index.js +25 -0
- package/dist/src/tools/oapi/search/index.js.map +7 -0
- package/dist/src/tools/oapi/sheets/index.js +25 -0
- package/dist/src/tools/oapi/sheets/index.js.map +7 -0
- package/dist/src/tools/oapi/sheets/sheet.js +652 -0
- package/dist/src/tools/oapi/sheets/sheet.js.map +7 -0
- package/dist/src/tools/oapi/task/comment.js +151 -0
- package/dist/src/tools/oapi/task/comment.js.map +7 -0
- package/dist/src/tools/oapi/task/index.js +11 -0
- package/dist/src/tools/oapi/task/index.js.map +7 -0
- package/dist/src/tools/oapi/task/subtask.js +175 -0
- package/dist/src/tools/oapi/task/subtask.js.map +7 -0
- package/dist/src/tools/oapi/task/task.js +405 -0
- package/dist/src/tools/oapi/task/task.js.map +7 -0
- package/dist/src/tools/oapi/task/tasklist.js +366 -0
- package/dist/src/tools/oapi/task/tasklist.js.map +7 -0
- package/dist/src/tools/oapi/wiki/index.js +27 -0
- package/dist/src/tools/oapi/wiki/index.js.map +7 -0
- package/dist/src/tools/oapi/wiki/space-node.js +311 -0
- package/dist/src/tools/oapi/wiki/space-node.js.map +7 -0
- package/dist/src/tools/oapi/wiki/space.js +148 -0
- package/dist/src/tools/oapi/wiki/space.js.map +7 -0
- package/dist/src/tools/oauth-batch-auth.js +125 -0
- package/dist/src/tools/oauth-batch-auth.js.map +7 -0
- package/dist/src/tools/oauth-cards.js +269 -0
- package/dist/src/tools/oauth-cards.js.map +7 -0
- package/dist/src/tools/oauth.js +538 -0
- package/dist/src/tools/oauth.js.map +7 -0
- package/dist/src/tools/onboarding-auth.js +101 -0
- package/dist/src/tools/onboarding-auth.js.map +7 -0
- package/dist/src/tools/project-oauth.js +305 -0
- package/dist/src/tools/project-oauth.js.map +7 -0
- package/dist/src/tools/tat/im/index.js +9 -0
- package/dist/src/tools/tat/im/index.js.map +7 -0
- package/dist/src/tools/tat/im/resource.js +123 -0
- package/dist/src/tools/tat/im/resource.js.map +7 -0
- package/package.json +64 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: feishu-troubleshoot
|
|
3
|
+
description: |
|
|
4
|
+
飞书插件问题排查工具。包含常见问题 FAQ 和深度诊断命令(/feishu_doctor)。
|
|
5
|
+
|
|
6
|
+
常见问题可随时查阅。诊断命令用于排查复杂问题(多次授权仍失败、自动授权无法解决等),
|
|
7
|
+
会检查账户配置、API 连通性、应用权限、用户授权状态,并生成详细的诊断报告和解决方案。
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# 飞书插件问题排查
|
|
12
|
+
|
|
13
|
+
## ❓ 常见问题(FAQ)
|
|
14
|
+
|
|
15
|
+
### 卡片按钮点击无反应
|
|
16
|
+
|
|
17
|
+
**现象**:点击卡片按钮后没有任何反应,然后提示报错.
|
|
18
|
+
|
|
19
|
+
**原因**:应用未开通「消息卡片回传交互」权限。
|
|
20
|
+
|
|
21
|
+
**解决步骤**:
|
|
22
|
+
|
|
23
|
+
1. 登录飞书开放平台:https://open.feishu.cn/app
|
|
24
|
+
2. 选择您的应用 → **事件与回调**
|
|
25
|
+
3. 在回调配置中,修改订阅方式为"长链接"并添加回调 "卡片回传交互"(card.action.trigger)
|
|
26
|
+
4. 创建应用版本 → 提交审核 → 发布
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 🔍 诊断命令(深度工具)
|
|
31
|
+
|
|
32
|
+
**注意**:诊断命令仅用于排查复杂/疑难的**权限相关问题**。常规权限问题会自动触发授权流程,无需手动诊断。
|
|
33
|
+
|
|
34
|
+
**何时使用诊断**:
|
|
35
|
+
- 多次授权后仍然报错
|
|
36
|
+
- 自动授权流程无法解决的问题
|
|
37
|
+
- 需要查看完整的权限配置状态
|
|
38
|
+
|
|
39
|
+
**使用方法**:
|
|
40
|
+
|
|
41
|
+
在飞书聊天会话中直接输入(作为用户消息发送):
|
|
42
|
+
|
|
43
|
+
/feishu doctor
|
|
44
|
+
|
|
45
|
+
诊断命令会检查:
|
|
46
|
+
|
|
47
|
+
- **📋 诊断摘要**(首先展示):
|
|
48
|
+
- 总体状态(✅ 正常 / ⚠️ 警告 / ❌ 失败)
|
|
49
|
+
- 发现的问题列表和简要描述
|
|
50
|
+
|
|
51
|
+
- **环境信息**:
|
|
52
|
+
- 插件版本
|
|
53
|
+
|
|
54
|
+
- **账号信息**:
|
|
55
|
+
- 凭证完整性(appId, appSecret 掩码)
|
|
56
|
+
- 账户启用状态
|
|
57
|
+
- API 连通性测试
|
|
58
|
+
- Bot 信息(名称和 openId)
|
|
59
|
+
|
|
60
|
+
- **应用身份权限**:
|
|
61
|
+
- 应用已开通的必需权限数量
|
|
62
|
+
- 缺失的必需权限列表
|
|
63
|
+
- 一键申请链接(自动带上缺失权限参数)
|
|
64
|
+
|
|
65
|
+
- **用户身份权限**:
|
|
66
|
+
- 用户授权状态统计(✓ 有效 / ⟳ 需刷新 / ✗ 已过期)
|
|
67
|
+
- Token 自动刷新状态(是否包含 offline_access)
|
|
68
|
+
- 权限对照表(应用已开通 vs 用户已授权,逐项对比)
|
|
69
|
+
- 应用权限缺失时的申请指引和链接
|
|
70
|
+
- 用户授权不足时的重新授权操作方法
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: feishu-update-doc
|
|
3
|
+
description: |
|
|
4
|
+
更新飞书云文档。支持 7 种更新模式:追加、覆盖、定位替换、全文替换、前/后插入、删除。
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# feishu__update_doc
|
|
8
|
+
|
|
9
|
+
更新飞书云文档内容,支持 7 种更新模式。优先使用局部更新(replace_range/append/insert_before/insert_after),慎用 overwrite(会清空文档重写,可能丢失图片、评论等)。
|
|
10
|
+
|
|
11
|
+
# 定位方式
|
|
12
|
+
|
|
13
|
+
定位模式(replace_range/replace_all/insert_before/insert_after/delete_range)支持两种定位方式,二选一:
|
|
14
|
+
|
|
15
|
+
## selection_with_ellipsis - 内容定位
|
|
16
|
+
|
|
17
|
+
支持两种格式:
|
|
18
|
+
|
|
19
|
+
1. **范围匹配**:`开头内容...结尾内容`
|
|
20
|
+
- 匹配从开头到结尾的所有内容(包含中间内容)
|
|
21
|
+
- 建议 10-20 字符确保唯一性
|
|
22
|
+
|
|
23
|
+
2. **精确匹配**:`完整内容`(不含 `...`)
|
|
24
|
+
- 匹配完整的文本内容
|
|
25
|
+
- 适合替换短文本、关键词等
|
|
26
|
+
|
|
27
|
+
**转义说明**:如果要匹配的内容本身包含 `...`,使用 `\.\.\.` 表示字面量的三个点。
|
|
28
|
+
|
|
29
|
+
示例:
|
|
30
|
+
- `你好...世界` → 匹配从"你好"到"世界"之间的任意内容
|
|
31
|
+
- `你好\.\.\.世界` → 匹配字面量 "你好...世界"
|
|
32
|
+
|
|
33
|
+
**建议**:如果文档中有多个 `...`,建议使用更长的上下文来精确定位,避免歧义。
|
|
34
|
+
|
|
35
|
+
## selection_by_title - 标题定位
|
|
36
|
+
|
|
37
|
+
格式:`## 章节标题`(可带或不带 # 前缀)
|
|
38
|
+
|
|
39
|
+
自动定位整个章节(从该标题到下一个同级或更高级标题之前)。
|
|
40
|
+
|
|
41
|
+
**示例**:
|
|
42
|
+
- `## 功能说明` → 定位二级标题"功能说明"及其下所有内容
|
|
43
|
+
- `功能说明` → 定位任意级别的"功能说明"标题及其内容
|
|
44
|
+
|
|
45
|
+
# 可选参数
|
|
46
|
+
|
|
47
|
+
## new_title
|
|
48
|
+
|
|
49
|
+
更新文档标题。如果提供此参数,将在更新文档内容后同步更新文档标题。
|
|
50
|
+
|
|
51
|
+
**特性**:
|
|
52
|
+
- 仅支持纯文本,不支持富文本格式
|
|
53
|
+
- 长度限制:1-800 字符
|
|
54
|
+
- 可以与任何 mode 配合使用
|
|
55
|
+
- 标题更新在内容更新之后执行
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# 返回值
|
|
59
|
+
|
|
60
|
+
## 成功
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"success": true,
|
|
65
|
+
"doc_id": "文档ID",
|
|
66
|
+
"mode": "使用的模式",
|
|
67
|
+
"message": "文档更新成功(xxx模式)",
|
|
68
|
+
"warnings": ["可选警告列表"],
|
|
69
|
+
"log_id": "请求日志ID"
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## 异步模式(大文档超时)
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"task_id": "async_task_xxxx",
|
|
78
|
+
"message": "文档更新已提交异步处理,请使用 task_id 查询状态",
|
|
79
|
+
"log_id": "请求日志ID"
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
使用返回的 `task_id` 再次调用 update-doc(仅传 task_id 参数)查询状态。
|
|
84
|
+
|
|
85
|
+
## 错误
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"error": "[错误码] 错误消息\n💡 Suggestion: 修复建议\n📍 Context: 上下文信息",
|
|
90
|
+
"log_id": "请求日志ID"
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
# 使用示例
|
|
97
|
+
|
|
98
|
+
## append - 追加到末尾
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"doc_id": "文档ID或URL",
|
|
103
|
+
"mode": "append",
|
|
104
|
+
"markdown": "## 新章节\n\n追加的内容..."
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## replace_range - 定位替换
|
|
109
|
+
|
|
110
|
+
使用 `selection_with_ellipsis`:
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"doc_id": "文档ID或URL",
|
|
114
|
+
"mode": "replace_range",
|
|
115
|
+
"selection_with_ellipsis": "## 旧章节标题...旧章节结尾。",
|
|
116
|
+
"markdown": "## 新章节标题\n\n新的内容..."
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
使用 `selection_by_title`(替换整个章节):
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"doc_id": "文档ID或URL",
|
|
124
|
+
"mode": "replace_range",
|
|
125
|
+
"selection_by_title": "## 功能说明",
|
|
126
|
+
"markdown": "## 功能说明\n\n更新后的功能说明内容..."
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## replace_all - 全文替换
|
|
131
|
+
|
|
132
|
+
与 replace_range 类似,但支持多处同时替换(replace_range 要求匹配唯一):
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"doc_id": "文档ID或URL",
|
|
136
|
+
"mode": "replace_all",
|
|
137
|
+
"selection_with_ellipsis": "张三",
|
|
138
|
+
"markdown": "李四"
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**返回值**包含 `replace_count` 字段,表示替换的次数:
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"success": true,
|
|
146
|
+
"replace_count": 4,
|
|
147
|
+
"message": "文档更新成功(replace_all模式,替换4处)"
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**注意**:
|
|
152
|
+
- 与 `replace_range` 不同,`replace_all` 允许多个匹配
|
|
153
|
+
- 如果没有找到匹配内容,会返回错误
|
|
154
|
+
- `markdown` 可以为空字符串,表示删除所有匹配内容
|
|
155
|
+
|
|
156
|
+
## insert_before - 前插入
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"doc_id": "文档ID或URL",
|
|
161
|
+
"mode": "insert_before",
|
|
162
|
+
"selection_with_ellipsis": "## 危险操作...数据丢失风险。",
|
|
163
|
+
"markdown": "> **警告**:以下操作需谨慎!"
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## insert_after - 后插入
|
|
168
|
+
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"doc_id": "文档ID或URL",
|
|
172
|
+
"mode": "insert_after",
|
|
173
|
+
"selection_with_ellipsis": "```python...```",
|
|
174
|
+
"markdown": "**输出示例**:\n```\nresult = 42\n```"
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## delete_range - 删除内容
|
|
179
|
+
|
|
180
|
+
使用 `selection_with_ellipsis`:
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"doc_id": "文档ID或URL",
|
|
184
|
+
"mode": "delete_range",
|
|
185
|
+
"selection_with_ellipsis": "## 废弃章节...不再需要的内容。"
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
使用 `selection_by_title`(删除整个章节):
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"doc_id": "文档ID或URL",
|
|
193
|
+
"mode": "delete_range",
|
|
194
|
+
"selection_by_title": "## 废弃章节"
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
注意:delete_range 模式不需要 markdown 参数。
|
|
199
|
+
|
|
200
|
+
## 同时更新标题和内容
|
|
201
|
+
|
|
202
|
+
可以在任何更新模式中添加 `new_title` 参数来同时更新文档标题:
|
|
203
|
+
|
|
204
|
+
```json
|
|
205
|
+
{
|
|
206
|
+
"doc_id": "文档ID或URL",
|
|
207
|
+
"mode": "overwrite",
|
|
208
|
+
"markdown": "# 项目文档 v2.0\n\n全新的内容...",
|
|
209
|
+
"new_title": "项目文档 v2.0"
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
{
|
|
215
|
+
"doc_id": "文档ID或URL",
|
|
216
|
+
"mode": "append",
|
|
217
|
+
"markdown": "## 更新日志\n\n2025-12-18: 新增功能...",
|
|
218
|
+
"new_title": "项目文档(已更新)"
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## overwrite - 完全覆盖
|
|
223
|
+
|
|
224
|
+
⚠️ 会清空文档后重写,可能丢失图片、评论等,仅在需要完全重建文档时使用。
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"doc_id": "文档ID或URL",
|
|
229
|
+
"mode": "overwrite",
|
|
230
|
+
"markdown": "# 新文档\n\n全新的内容..."
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
# 最佳实践
|
|
237
|
+
|
|
238
|
+
## 小粒度精确替换
|
|
239
|
+
|
|
240
|
+
修改文档内容时,**定位范围越小越安全**。尤其是表格、分栏等嵌套块,应精确定位到需要修改的文本,避免影响其他内容。
|
|
241
|
+
|
|
242
|
+
**示例**:表格单元格中有图片和文字,只需修改文字
|
|
243
|
+
- ❌ 替换整个表格或整行 → 可能破坏图片引用
|
|
244
|
+
- ✅ 只定位需要修改的文本 → 图片等其他内容不受影响
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
## 保护不可重建的内容
|
|
248
|
+
|
|
249
|
+
图片、画板、电子表格、多维表格、任务等内容以 token 形式存储,**无法读出后原样写入**。
|
|
250
|
+
|
|
251
|
+
**保护策略**:
|
|
252
|
+
- 替换时避开包含这些内容的区域
|
|
253
|
+
- 精确定位到纯文本部分进行修改
|
|
254
|
+
|
|
255
|
+
## 分步更新优于整体覆盖
|
|
256
|
+
|
|
257
|
+
修改多处内容时:
|
|
258
|
+
- ✅ 多次小范围替换,逐步修改
|
|
259
|
+
- ⚠️ 谨慎使用 `overwrite` 重写整个文档, 除非你认为风险完全可控
|
|
260
|
+
|
|
261
|
+
**原因**:局部更新保留原有媒体、评论、协作历史,更安全可靠。
|
|
262
|
+
|
|
263
|
+
## insert 模式扩大定位范围时注意插入位置
|
|
264
|
+
|
|
265
|
+
使用 `insert_before` 或 `insert_after` 时,如果目标内容重复出现,需要扩大 `selection_with_ellipsis` 范围来唯一定位。
|
|
266
|
+
|
|
267
|
+
**关键**:插入位置基于匹配范围的**边界**:
|
|
268
|
+
- `insert_after` → 插入在匹配范围的**结尾**之后
|
|
269
|
+
- `insert_before` → 插入在匹配范围的**开头**之前
|
|
270
|
+
|
|
271
|
+
扩大范围时,确保边界仍然是期望的插入点。
|
|
272
|
+
|
|
273
|
+
## 修复画板语法错误
|
|
274
|
+
|
|
275
|
+
当 create-doc 或 update-doc 返回画板写入失败的 warning 时:
|
|
276
|
+
1. warning 中包含 whiteboard 标签(如 `<whiteboard token="xxx"/>`)
|
|
277
|
+
2. 分析错误信息,修正 Mermaid/PlantUML 语法
|
|
278
|
+
3. 用 `replace_range` 替换:`selection_with_ellipsis` 使用 warning 中的 whiteboard 标签,`markdown` 提供修正后的代码块
|
|
279
|
+
4. 重新提交验证
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
# 注意事项
|
|
284
|
+
|
|
285
|
+
- **Markdown 语法**:支持飞书扩展语法,详见 create-doc 工具文档
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { optimizeMarkdownStyle } from "./markdown-style";
|
|
2
|
+
const STREAMING_ELEMENT_ID = "streaming_content";
|
|
3
|
+
const REASONING_ELEMENT_ID = "reasoning_content";
|
|
4
|
+
const REASONING_PREFIX = "Reasoning:\n";
|
|
5
|
+
function splitReasoningText(text) {
|
|
6
|
+
if (typeof text !== "string" || !text.trim()) return {};
|
|
7
|
+
const trimmed = text.trim();
|
|
8
|
+
if (trimmed.startsWith(REASONING_PREFIX) && trimmed.length > REASONING_PREFIX.length) {
|
|
9
|
+
return { reasoningText: cleanReasoningPrefix(trimmed) };
|
|
10
|
+
}
|
|
11
|
+
const taggedReasoning = extractThinkingContent(text);
|
|
12
|
+
const strippedAnswer = stripReasoningTags(text);
|
|
13
|
+
if (!taggedReasoning && strippedAnswer === text) {
|
|
14
|
+
return { answerText: text };
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
reasoningText: taggedReasoning || void 0,
|
|
18
|
+
answerText: strippedAnswer || void 0
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function extractThinkingContent(text) {
|
|
22
|
+
if (!text) return "";
|
|
23
|
+
const scanRe = /<\s*(\/?)\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi;
|
|
24
|
+
let result = "";
|
|
25
|
+
let lastIndex = 0;
|
|
26
|
+
let inThinking = false;
|
|
27
|
+
for (const match of text.matchAll(scanRe)) {
|
|
28
|
+
const idx = match.index ?? 0;
|
|
29
|
+
if (inThinking) {
|
|
30
|
+
result += text.slice(lastIndex, idx);
|
|
31
|
+
}
|
|
32
|
+
inThinking = match[1] !== "/";
|
|
33
|
+
lastIndex = idx + match[0].length;
|
|
34
|
+
}
|
|
35
|
+
if (inThinking) {
|
|
36
|
+
result += text.slice(lastIndex);
|
|
37
|
+
}
|
|
38
|
+
return result.trim();
|
|
39
|
+
}
|
|
40
|
+
function stripReasoningTags(text) {
|
|
41
|
+
let result = text.replace(
|
|
42
|
+
/<\s*(?:think(?:ing)?|thought|antthinking)\s*>[\s\S]*?<\s*\/\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi,
|
|
43
|
+
""
|
|
44
|
+
);
|
|
45
|
+
result = result.replace(/<\s*(?:think(?:ing)?|thought|antthinking)\s*>[\s\S]*$/gi, "");
|
|
46
|
+
result = result.replace(/<\s*\/\s*(?:think(?:ing)?|thought|antthinking)\s*>/gi, "");
|
|
47
|
+
return result.trim();
|
|
48
|
+
}
|
|
49
|
+
function cleanReasoningPrefix(text) {
|
|
50
|
+
let cleaned = text.replace(/^Reasoning:\s*/i, "");
|
|
51
|
+
cleaned = cleaned.split("\n").map((line) => line.replace(/^_(.+)_$/, "$1")).join("\n");
|
|
52
|
+
return cleaned.trim();
|
|
53
|
+
}
|
|
54
|
+
function formatReasoningDuration(ms) {
|
|
55
|
+
return `Thought for ${formatElapsed(ms)}`;
|
|
56
|
+
}
|
|
57
|
+
function formatElapsed(ms) {
|
|
58
|
+
const seconds = ms / 1e3;
|
|
59
|
+
return seconds < 60 ? `${seconds.toFixed(1)}s` : `${Math.floor(seconds / 60)}m ${Math.round(seconds % 60)}s`;
|
|
60
|
+
}
|
|
61
|
+
function buildFooter(text, isError) {
|
|
62
|
+
const content = isError ? `<font color='red'>${text}</font>` : text;
|
|
63
|
+
return [{ tag: "markdown", content, text_size: "notation" }];
|
|
64
|
+
}
|
|
65
|
+
function buildCardContent(state, data = {}) {
|
|
66
|
+
switch (state) {
|
|
67
|
+
case "thinking":
|
|
68
|
+
return buildThinkingCard();
|
|
69
|
+
case "streaming":
|
|
70
|
+
return buildStreamingCard(data.text ?? "", data.toolCalls ?? [], data.reasoningText);
|
|
71
|
+
case "complete":
|
|
72
|
+
return buildCompleteCard({
|
|
73
|
+
text: data.text ?? "",
|
|
74
|
+
toolCalls: data.toolCalls ?? [],
|
|
75
|
+
elapsedMs: data.elapsedMs,
|
|
76
|
+
isError: data.isError,
|
|
77
|
+
reasoningText: data.reasoningText,
|
|
78
|
+
reasoningElapsedMs: data.reasoningElapsedMs,
|
|
79
|
+
isAborted: data.isAborted,
|
|
80
|
+
footer: data.footer
|
|
81
|
+
});
|
|
82
|
+
case "confirm":
|
|
83
|
+
return buildConfirmCard(data.confirmData);
|
|
84
|
+
default:
|
|
85
|
+
throw new Error(`Unknown card state: ${state}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function buildThinkingCard() {
|
|
89
|
+
return {
|
|
90
|
+
config: { wide_screen_mode: true, update_multi: true },
|
|
91
|
+
elements: [
|
|
92
|
+
{
|
|
93
|
+
tag: "markdown",
|
|
94
|
+
content: "\u601D\u8003\u4E2D..."
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function buildStreamingCard(partialText, toolCalls, reasoningText) {
|
|
100
|
+
const elements = [];
|
|
101
|
+
if (!partialText && reasoningText) {
|
|
102
|
+
elements.push({
|
|
103
|
+
tag: "markdown",
|
|
104
|
+
content: `\u{1F4AD} **Thinking...**
|
|
105
|
+
|
|
106
|
+
${reasoningText}`,
|
|
107
|
+
text_size: "notation"
|
|
108
|
+
});
|
|
109
|
+
} else if (partialText) {
|
|
110
|
+
elements.push({
|
|
111
|
+
tag: "markdown",
|
|
112
|
+
content: optimizeMarkdownStyle(partialText)
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
if (toolCalls.length > 0) {
|
|
116
|
+
const toolLines = toolCalls.map((tc) => {
|
|
117
|
+
const statusIcon = tc.status === "running" ? "\u{1F504}" : tc.status === "complete" ? "\u2705" : "\u274C";
|
|
118
|
+
return `${statusIcon} ${tc.name} - ${tc.status}`;
|
|
119
|
+
});
|
|
120
|
+
elements.push({
|
|
121
|
+
tag: "markdown",
|
|
122
|
+
content: toolLines.join("\n"),
|
|
123
|
+
text_size: "notation"
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
config: { wide_screen_mode: true, update_multi: true },
|
|
128
|
+
elements
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function buildCompleteCard(params) {
|
|
132
|
+
const { text, toolCalls, elapsedMs, isError, reasoningText, reasoningElapsedMs, isAborted, footer } = params;
|
|
133
|
+
const elements = [];
|
|
134
|
+
if (reasoningText) {
|
|
135
|
+
const durationLabel = reasoningElapsedMs ? formatReasoningDuration(reasoningElapsedMs) : "Thought";
|
|
136
|
+
elements.push({
|
|
137
|
+
tag: "collapsible_panel",
|
|
138
|
+
expanded: false,
|
|
139
|
+
header: {
|
|
140
|
+
title: {
|
|
141
|
+
tag: "markdown",
|
|
142
|
+
content: `\u{1F4AD} ${durationLabel}`
|
|
143
|
+
},
|
|
144
|
+
vertical_align: "center",
|
|
145
|
+
icon: {
|
|
146
|
+
tag: "standard_icon",
|
|
147
|
+
token: "down-small-ccm_outlined",
|
|
148
|
+
size: "16px 16px"
|
|
149
|
+
},
|
|
150
|
+
icon_position: "follow_text",
|
|
151
|
+
icon_expanded_angle: -180
|
|
152
|
+
},
|
|
153
|
+
border: { color: "grey", corner_radius: "5px" },
|
|
154
|
+
vertical_spacing: "8px",
|
|
155
|
+
padding: "8px 8px 8px 8px",
|
|
156
|
+
elements: [
|
|
157
|
+
{
|
|
158
|
+
tag: "markdown",
|
|
159
|
+
content: reasoningText,
|
|
160
|
+
text_size: "notation"
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
elements.push({
|
|
166
|
+
tag: "markdown",
|
|
167
|
+
content: optimizeMarkdownStyle(text)
|
|
168
|
+
});
|
|
169
|
+
if (toolCalls.length > 0) {
|
|
170
|
+
const toolSummaryLines = toolCalls.map((tc) => {
|
|
171
|
+
const statusIcon = tc.status === "complete" ? "\u2705" : "\u274C";
|
|
172
|
+
return `${statusIcon} **${tc.name}** - ${tc.status}`;
|
|
173
|
+
});
|
|
174
|
+
elements.push({
|
|
175
|
+
tag: "markdown",
|
|
176
|
+
content: toolSummaryLines.join("\n"),
|
|
177
|
+
text_size: "notation"
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
const parts = [];
|
|
181
|
+
if (footer?.status) {
|
|
182
|
+
if (isError) {
|
|
183
|
+
parts.push("\u51FA\u9519");
|
|
184
|
+
} else if (isAborted) {
|
|
185
|
+
parts.push("\u5DF2\u505C\u6B62");
|
|
186
|
+
} else {
|
|
187
|
+
parts.push("\u5DF2\u5B8C\u6210");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (footer?.elapsed && elapsedMs != null) {
|
|
191
|
+
parts.push(`\u8017\u65F6 ${formatElapsed(elapsedMs)}`);
|
|
192
|
+
}
|
|
193
|
+
if (parts.length > 0) {
|
|
194
|
+
const footerText = parts.join(" \xB7 ");
|
|
195
|
+
elements.push(...buildFooter(footerText, isError));
|
|
196
|
+
}
|
|
197
|
+
const summaryText = text.replace(/[*_`#>\[\]()~]/g, "").trim();
|
|
198
|
+
const summary = summaryText ? { content: summaryText.slice(0, 120) } : void 0;
|
|
199
|
+
return {
|
|
200
|
+
config: { wide_screen_mode: true, update_multi: true, summary },
|
|
201
|
+
elements
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function buildConfirmCard(confirmData) {
|
|
205
|
+
const elements = [];
|
|
206
|
+
elements.push({
|
|
207
|
+
tag: "div",
|
|
208
|
+
text: {
|
|
209
|
+
tag: "lark_md",
|
|
210
|
+
content: confirmData.operationDescription
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
if (confirmData.preview) {
|
|
214
|
+
elements.push({ tag: "hr" });
|
|
215
|
+
elements.push({
|
|
216
|
+
tag: "div",
|
|
217
|
+
text: {
|
|
218
|
+
tag: "lark_md",
|
|
219
|
+
content: `**Preview:**
|
|
220
|
+
${confirmData.preview}`
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
elements.push({ tag: "hr" });
|
|
225
|
+
elements.push({
|
|
226
|
+
tag: "action",
|
|
227
|
+
actions: [
|
|
228
|
+
{
|
|
229
|
+
tag: "button",
|
|
230
|
+
text: { tag: "plain_text", content: "Confirm" },
|
|
231
|
+
type: "primary",
|
|
232
|
+
value: {
|
|
233
|
+
action: "confirm_write",
|
|
234
|
+
operation_id: confirmData.pendingOperationId
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
tag: "button",
|
|
239
|
+
text: { tag: "plain_text", content: "Reject" },
|
|
240
|
+
type: "danger",
|
|
241
|
+
value: {
|
|
242
|
+
action: "reject_write",
|
|
243
|
+
operation_id: confirmData.pendingOperationId
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
...confirmData.preview ? [] : [
|
|
247
|
+
{
|
|
248
|
+
tag: "button",
|
|
249
|
+
text: {
|
|
250
|
+
tag: "plain_text",
|
|
251
|
+
content: "Preview"
|
|
252
|
+
},
|
|
253
|
+
type: "default",
|
|
254
|
+
value: {
|
|
255
|
+
action: "preview_write",
|
|
256
|
+
operation_id: confirmData.pendingOperationId
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
]
|
|
260
|
+
]
|
|
261
|
+
});
|
|
262
|
+
return {
|
|
263
|
+
config: { wide_screen_mode: true, update_multi: true },
|
|
264
|
+
header: {
|
|
265
|
+
title: {
|
|
266
|
+
tag: "plain_text",
|
|
267
|
+
content: "\u{1F512} Confirmation Required"
|
|
268
|
+
},
|
|
269
|
+
template: "orange"
|
|
270
|
+
},
|
|
271
|
+
elements
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function toCardKit2(card) {
|
|
275
|
+
const result = {
|
|
276
|
+
schema: "2.0",
|
|
277
|
+
config: card.config,
|
|
278
|
+
body: { elements: card.elements }
|
|
279
|
+
};
|
|
280
|
+
if (card.header) result.header = card.header;
|
|
281
|
+
return result;
|
|
282
|
+
}
|
|
283
|
+
export {
|
|
284
|
+
REASONING_ELEMENT_ID,
|
|
285
|
+
STREAMING_ELEMENT_ID,
|
|
286
|
+
buildCardContent,
|
|
287
|
+
formatElapsed,
|
|
288
|
+
formatReasoningDuration,
|
|
289
|
+
splitReasoningText,
|
|
290
|
+
stripReasoningTags,
|
|
291
|
+
toCardKit2
|
|
292
|
+
};
|
|
293
|
+
//# sourceMappingURL=builder.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/card/builder.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * Interactive card building for Lark/Feishu.\n *\n * Provides utilities to construct Feishu Interactive Message Cards for\n * different agent response states (thinking, streaming, complete, confirm).\n */\n\nimport { optimizeMarkdownStyle } from './markdown-style';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Element ID used for the streaming text area in cards. The CardKit\n * `cardElement.content()` API targets this element for typewriter-effect\n * streaming updates.\n */\nexport const STREAMING_ELEMENT_ID = 'streaming_content';\nexport const REASONING_ELEMENT_ID = 'reasoning_content';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ToolCallInfo {\n name: string;\n status: 'running' | 'complete' | 'error';\n args?: Record<string, unknown>;\n result?: string;\n}\n\nexport interface CardElement {\n tag: string;\n [key: string]: unknown;\n}\n\nexport interface FeishuCard {\n config: {\n wide_screen_mode: boolean;\n update_multi?: boolean;\n summary?: { content: string };\n };\n header?: {\n title: { tag: 'plain_text'; content: string };\n template: string;\n };\n elements: CardElement[];\n}\n\nexport type CardState = 'thinking' | 'streaming' | 'complete' | 'confirm';\n\nexport interface ConfirmData {\n operationDescription: string;\n pendingOperationId: string;\n preview?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n// ---- Reasoning text utilities ----\n// Mirrors the logic in the framework's `splitTelegramReasoningText` and\n// related helpers from `plugin-sdk/telegram/reasoning-lane-coordinator`.\n// Those are not exported from the public plugin-sdk entry, so we replicate\n// the same detection/splitting logic here.\n\nconst REASONING_PREFIX = 'Reasoning:\\n';\n\n/**\n * Split a payload text into optional `reasoningText` and `answerText`.\n *\n * Handles two formats produced by the framework:\n * 1. \"Reasoning:\\n_italic line_\\n\u2026\" prefix (from `formatReasoningMessage`)\n * 2. `<think>\u2026</think>` / `<thinking>\u2026</thinking>` XML tags\n *\n * Equivalent to the framework's `splitTelegramReasoningText()`.\n */\nexport function splitReasoningText(text?: string): {\n reasoningText?: string;\n answerText?: string;\n} {\n if (typeof text !== 'string' || !text.trim()) return {};\n\n const trimmed = text.trim();\n\n // Case 1: \"Reasoning:\\n...\" prefix \u2014 the entire payload is reasoning\n if (trimmed.startsWith(REASONING_PREFIX) && trimmed.length > REASONING_PREFIX.length) {\n return { reasoningText: cleanReasoningPrefix(trimmed) };\n }\n\n // Case 2: XML thinking tags \u2014 extract content and strip from answer\n const taggedReasoning = extractThinkingContent(text);\n const strippedAnswer = stripReasoningTags(text);\n if (!taggedReasoning && strippedAnswer === text) {\n return { answerText: text };\n }\n return {\n reasoningText: taggedReasoning || undefined,\n answerText: strippedAnswer || undefined,\n };\n}\n\n/**\n * Extract content from `<think>`, `<thinking>`, `<thought>` blocks.\n * Handles both closed and unclosed (streaming) tags.\n */\nfunction extractThinkingContent(text: string): string {\n if (!text) return '';\n const scanRe = /<\\s*(\\/?)\\s*(?:think(?:ing)?|thought|antthinking)\\s*>/gi;\n let result = '';\n let lastIndex = 0;\n let inThinking = false;\n for (const match of text.matchAll(scanRe)) {\n const idx = match.index ?? 0;\n if (inThinking) {\n result += text.slice(lastIndex, idx);\n }\n inThinking = match[1] !== '/';\n lastIndex = idx + match[0].length;\n }\n // Handle unclosed tag (still streaming)\n if (inThinking) {\n result += text.slice(lastIndex);\n }\n return result.trim();\n}\n\n/**\n * Strip reasoning blocks \u2014 both XML tags with their content and any\n * \"Reasoning:\\n\" prefixed content.\n */\nexport function stripReasoningTags(text: string): string {\n // Strip complete XML blocks\n let result = text.replace(\n /<\\s*(?:think(?:ing)?|thought|antthinking)\\s*>[\\s\\S]*?<\\s*\\/\\s*(?:think(?:ing)?|thought|antthinking)\\s*>/gi,\n '',\n );\n // Strip unclosed tag at end (streaming)\n result = result.replace(/<\\s*(?:think(?:ing)?|thought|antthinking)\\s*>[\\s\\S]*$/gi, '');\n // Strip orphaned closing tags\n result = result.replace(/<\\s*\\/\\s*(?:think(?:ing)?|thought|antthinking)\\s*>/gi, '');\n return result.trim();\n}\n\n/**\n * Clean a \"Reasoning:\\n_italic_\" formatted message back to plain text.\n * Strips the prefix and per-line italic markdown wrappers.\n */\nfunction cleanReasoningPrefix(text: string): string {\n let cleaned = text.replace(/^Reasoning:\\s*/i, '');\n cleaned = cleaned\n .split('\\n')\n .map((line) => line.replace(/^_(.+)_$/, '$1'))\n .join('\\n');\n return cleaned.trim();\n}\n\n/**\n * Format reasoning duration into a human-readable string.\n * e.g. \"Thought for 3.2s\" or \"Thought for 1m 15s\"\n */\nexport function formatReasoningDuration(ms: number): string {\n return `Thought for ${formatElapsed(ms)}`;\n}\n\n/**\n * Format milliseconds into a human-readable duration string.\n */\nexport function formatElapsed(ms: number): string {\n const seconds = ms / 1000;\n return seconds < 60 ? `${seconds.toFixed(1)}s` : `${Math.floor(seconds / 60)}m ${Math.round(seconds % 60)}s`;\n}\n\n/**\n * Build footer meta-info: hr separator + notation-sized text.\n * Error text is rendered in red; normal text uses default grey (notation).\n */\nfunction buildFooter(text: string, isError?: boolean): CardElement[] {\n const content = isError ? `<font color='red'>${text}</font>` : text;\n return [{ tag: 'markdown', content, text_size: 'notation' }];\n}\n\n// ---------------------------------------------------------------------------\n// buildCardContent\n// ---------------------------------------------------------------------------\n\n/**\n * Build a full Feishu Interactive Message Card JSON object for the\n * given state.\n */\nexport function buildCardContent(\n state: CardState,\n data: {\n text?: string;\n reasoningText?: string;\n reasoningElapsedMs?: number;\n toolCalls?: ToolCallInfo[];\n confirmData?: ConfirmData;\n elapsedMs?: number;\n isError?: boolean;\n isAborted?: boolean;\n footer?: { status?: boolean; elapsed?: boolean };\n } = {},\n): FeishuCard {\n switch (state) {\n case 'thinking':\n return buildThinkingCard();\n case 'streaming':\n return buildStreamingCard(data.text ?? '', data.toolCalls ?? [], data.reasoningText);\n case 'complete':\n return buildCompleteCard({\n text: data.text ?? '',\n toolCalls: data.toolCalls ?? [],\n elapsedMs: data.elapsedMs,\n isError: data.isError,\n reasoningText: data.reasoningText,\n reasoningElapsedMs: data.reasoningElapsedMs,\n isAborted: data.isAborted,\n footer: data.footer,\n });\n case 'confirm':\n return buildConfirmCard(data.confirmData!);\n default:\n throw new Error(`Unknown card state: ${state}`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Private card builders\n// ---------------------------------------------------------------------------\n\nfunction buildThinkingCard(): FeishuCard {\n return {\n config: { wide_screen_mode: true, update_multi: true },\n elements: [\n {\n tag: 'markdown',\n content: '\u601D\u8003\u4E2D...',\n },\n ],\n };\n}\n\nfunction buildStreamingCard(partialText: string, toolCalls: ToolCallInfo[], reasoningText?: string): FeishuCard {\n const elements: CardElement[] = [];\n\n if (!partialText && reasoningText) {\n // Reasoning phase: show reasoning content in notation style\n elements.push({\n tag: 'markdown',\n content: `\uD83D\uDCAD **Thinking...**\\n\\n${reasoningText}`,\n text_size: 'notation',\n });\n } else if (partialText) {\n // Answer phase: show answer content only\n elements.push({\n tag: 'markdown',\n content: optimizeMarkdownStyle(partialText),\n });\n }\n\n // Tool calls in progress\n if (toolCalls.length > 0) {\n const toolLines = toolCalls.map((tc) => {\n const statusIcon = tc.status === 'running' ? '\\ud83d\\udd04' : tc.status === 'complete' ? '\\u2705' : '\\u274c';\n return `${statusIcon} ${tc.name} - ${tc.status}`;\n });\n elements.push({\n tag: 'markdown',\n content: toolLines.join('\\n'),\n text_size: 'notation',\n });\n }\n\n return {\n config: { wide_screen_mode: true, update_multi: true },\n elements,\n };\n}\n\nfunction buildCompleteCard(params: {\n text: string;\n toolCalls: ToolCallInfo[];\n elapsedMs?: number;\n isError?: boolean;\n reasoningText?: string;\n reasoningElapsedMs?: number;\n isAborted?: boolean;\n footer?: { status?: boolean; elapsed?: boolean };\n}): FeishuCard {\n const { text, toolCalls, elapsedMs, isError, reasoningText, reasoningElapsedMs, isAborted, footer } = params;\n const elements: CardElement[] = [];\n\n // Collapsible reasoning panel (before main content)\n if (reasoningText) {\n const durationLabel = reasoningElapsedMs ? formatReasoningDuration(reasoningElapsedMs) : 'Thought';\n elements.push({\n tag: 'collapsible_panel',\n expanded: false,\n header: {\n title: {\n tag: 'markdown',\n content: `\uD83D\uDCAD ${durationLabel}`,\n },\n vertical_align: 'center',\n icon: {\n tag: 'standard_icon',\n token: 'down-small-ccm_outlined',\n size: '16px 16px',\n },\n icon_position: 'follow_text',\n icon_expanded_angle: -180,\n },\n border: { color: 'grey', corner_radius: '5px' },\n vertical_spacing: '8px',\n padding: '8px 8px 8px 8px',\n elements: [\n {\n tag: 'markdown',\n content: reasoningText,\n text_size: 'notation',\n },\n ],\n });\n }\n\n // Full text content\n elements.push({\n tag: 'markdown',\n content: optimizeMarkdownStyle(text),\n });\n\n // Tool calls summary\n if (toolCalls.length > 0) {\n const toolSummaryLines = toolCalls.map((tc) => {\n const statusIcon = tc.status === 'complete' ? '\\u2705' : '\\u274c';\n return `${statusIcon} **${tc.name}** - ${tc.status}`;\n });\n\n elements.push({\n tag: 'markdown',\n content: toolSummaryLines.join('\\n'),\n text_size: 'notation',\n });\n }\n\n // Footer meta-info: each metadata item is independently controlled via\n // the `footer` config. Both status and elapsed default to hidden.\n const parts: string[] = [];\n\n if (footer?.status) {\n if (isError) {\n parts.push('\u51FA\u9519');\n } else if (isAborted) {\n parts.push('\u5DF2\u505C\u6B62');\n } else {\n parts.push('\u5DF2\u5B8C\u6210');\n }\n }\n\n if (footer?.elapsed && elapsedMs != null) {\n parts.push(`\u8017\u65F6 ${formatElapsed(elapsedMs)}`);\n }\n\n if (parts.length > 0) {\n const footerText = parts.join(' \u00B7 ');\n elements.push(...buildFooter(footerText, isError));\n }\n\n // Use the answer text (not reasoning) as the feed preview summary.\n // Strip markdown syntax so the preview reads as plain text.\n const summaryText = text.replace(/[*_`#>\\[\\]()~]/g, '').trim();\n const summary = summaryText ? { content: summaryText.slice(0, 120) } : undefined;\n\n return {\n config: { wide_screen_mode: true, update_multi: true, summary },\n elements,\n };\n}\n\nfunction buildConfirmCard(confirmData: ConfirmData): FeishuCard {\n const elements: CardElement[] = [];\n\n // Operation description\n elements.push({\n tag: 'div',\n text: {\n tag: 'lark_md',\n content: confirmData.operationDescription,\n },\n });\n\n // Preview (if available)\n if (confirmData.preview) {\n elements.push({ tag: 'hr' });\n elements.push({\n tag: 'div',\n text: {\n tag: 'lark_md',\n content: `**Preview:**\\n${confirmData.preview}`,\n },\n });\n }\n\n // Confirm / Reject / Preview buttons\n elements.push({ tag: 'hr' });\n elements.push({\n tag: 'action',\n actions: [\n {\n tag: 'button',\n text: { tag: 'plain_text', content: 'Confirm' },\n type: 'primary',\n value: {\n action: 'confirm_write',\n operation_id: confirmData.pendingOperationId,\n },\n },\n {\n tag: 'button',\n text: { tag: 'plain_text', content: 'Reject' },\n type: 'danger',\n value: {\n action: 'reject_write',\n operation_id: confirmData.pendingOperationId,\n },\n },\n ...(confirmData.preview\n ? []\n : [\n {\n tag: 'button' as const,\n text: {\n tag: 'plain_text' as const,\n content: 'Preview',\n },\n type: 'default' as const,\n value: {\n action: 'preview_write',\n operation_id: confirmData.pendingOperationId,\n },\n },\n ]),\n ],\n });\n\n return {\n config: { wide_screen_mode: true, update_multi: true },\n header: {\n title: {\n tag: 'plain_text',\n content: '\\ud83d\\udd12 Confirmation Required',\n },\n template: 'orange',\n },\n elements,\n };\n}\n\n// ---------------------------------------------------------------------------\n// toCardKit2\n// ---------------------------------------------------------------------------\n\n/**\n * Convert an old-format FeishuCard to CardKit JSON 2.0 format.\n * JSON 2.0 uses `body.elements` instead of top-level `elements`.\n */\nexport function toCardKit2(card: FeishuCard): Record<string, unknown> {\n const result: Record<string, unknown> = {\n schema: '2.0',\n config: card.config,\n body: { elements: card.elements },\n };\n if (card.header) result.header = card.header;\n return result;\n}\n"],
|
|
5
|
+
"mappings": "AAUA,SAAS,6BAA6B;AAW/B,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB;AAiDpC,MAAM,mBAAmB;AAWlB,SAAS,mBAAmB,MAGjC;AACA,MAAI,OAAO,SAAS,YAAY,CAAC,KAAK,KAAK,EAAG,QAAO,CAAC;AAEtD,QAAM,UAAU,KAAK,KAAK;AAG1B,MAAI,QAAQ,WAAW,gBAAgB,KAAK,QAAQ,SAAS,iBAAiB,QAAQ;AACpF,WAAO,EAAE,eAAe,qBAAqB,OAAO,EAAE;AAAA,EACxD;AAGA,QAAM,kBAAkB,uBAAuB,IAAI;AACnD,QAAM,iBAAiB,mBAAmB,IAAI;AAC9C,MAAI,CAAC,mBAAmB,mBAAmB,MAAM;AAC/C,WAAO,EAAE,YAAY,KAAK;AAAA,EAC5B;AACA,SAAO;AAAA,IACL,eAAe,mBAAmB;AAAA,IAClC,YAAY,kBAAkB;AAAA,EAChC;AACF;AAMA,SAAS,uBAAuB,MAAsB;AACpD,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,SAAS;AACf,MAAI,SAAS;AACb,MAAI,YAAY;AAChB,MAAI,aAAa;AACjB,aAAW,SAAS,KAAK,SAAS,MAAM,GAAG;AACzC,UAAM,MAAM,MAAM,SAAS;AAC3B,QAAI,YAAY;AACd,gBAAU,KAAK,MAAM,WAAW,GAAG;AAAA,IACrC;AACA,iBAAa,MAAM,CAAC,MAAM;AAC1B,gBAAY,MAAM,MAAM,CAAC,EAAE;AAAA,EAC7B;AAEA,MAAI,YAAY;AACd,cAAU,KAAK,MAAM,SAAS;AAAA,EAChC;AACA,SAAO,OAAO,KAAK;AACrB;AAMO,SAAS,mBAAmB,MAAsB;AAEvD,MAAI,SAAS,KAAK;AAAA,IAChB;AAAA,IACA;AAAA,EACF;AAEA,WAAS,OAAO,QAAQ,2DAA2D,EAAE;AAErF,WAAS,OAAO,QAAQ,wDAAwD,EAAE;AAClF,SAAO,OAAO,KAAK;AACrB;AAMA,SAAS,qBAAqB,MAAsB;AAClD,MAAI,UAAU,KAAK,QAAQ,mBAAmB,EAAE;AAChD,YAAU,QACP,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,KAAK,QAAQ,YAAY,IAAI,CAAC,EAC5C,KAAK,IAAI;AACZ,SAAO,QAAQ,KAAK;AACtB;AAMO,SAAS,wBAAwB,IAAoB;AAC1D,SAAO,eAAe,cAAc,EAAE,CAAC;AACzC;AAKO,SAAS,cAAc,IAAoB;AAChD,QAAM,UAAU,KAAK;AACrB,SAAO,UAAU,KAAK,GAAG,QAAQ,QAAQ,CAAC,CAAC,MAAM,GAAG,KAAK,MAAM,UAAU,EAAE,CAAC,KAAK,KAAK,MAAM,UAAU,EAAE,CAAC;AAC3G;AAMA,SAAS,YAAY,MAAc,SAAkC;AACnE,QAAM,UAAU,UAAU,qBAAqB,IAAI,YAAY;AAC/D,SAAO,CAAC,EAAE,KAAK,YAAY,SAAS,WAAW,WAAW,CAAC;AAC7D;AAUO,SAAS,iBACd,OACA,OAUI,CAAC,GACO;AACZ,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO,kBAAkB;AAAA,IAC3B,KAAK;AACH,aAAO,mBAAmB,KAAK,QAAQ,IAAI,KAAK,aAAa,CAAC,GAAG,KAAK,aAAa;AAAA,IACrF,KAAK;AACH,aAAO,kBAAkB;AAAA,QACvB,MAAM,KAAK,QAAQ;AAAA,QACnB,WAAW,KAAK,aAAa,CAAC;AAAA,QAC9B,WAAW,KAAK;AAAA,QAChB,SAAS,KAAK;AAAA,QACd,eAAe,KAAK;AAAA,QACpB,oBAAoB,KAAK;AAAA,QACzB,WAAW,KAAK;AAAA,QAChB,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,IACH,KAAK;AACH,aAAO,iBAAiB,KAAK,WAAY;AAAA,IAC3C;AACE,YAAM,IAAI,MAAM,uBAAuB,KAAK,EAAE;AAAA,EAClD;AACF;AAMA,SAAS,oBAAgC;AACvC,SAAO;AAAA,IACL,QAAQ,EAAE,kBAAkB,MAAM,cAAc,KAAK;AAAA,IACrD,UAAU;AAAA,MACR;AAAA,QACE,KAAK;AAAA,QACL,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,mBAAmB,aAAqB,WAA2B,eAAoC;AAC9G,QAAM,WAA0B,CAAC;AAEjC,MAAI,CAAC,eAAe,eAAe;AAEjC,aAAS,KAAK;AAAA,MACZ,KAAK;AAAA,MACL,SAAS;AAAA;AAAA,EAAyB,aAAa;AAAA,MAC/C,WAAW;AAAA,IACb,CAAC;AAAA,EACH,WAAW,aAAa;AAEtB,aAAS,KAAK;AAAA,MACZ,KAAK;AAAA,MACL,SAAS,sBAAsB,WAAW;AAAA,IAC5C,CAAC;AAAA,EACH;AAGA,MAAI,UAAU,SAAS,GAAG;AACxB,UAAM,YAAY,UAAU,IAAI,CAAC,OAAO;AACtC,YAAM,aAAa,GAAG,WAAW,YAAY,cAAiB,GAAG,WAAW,aAAa,WAAW;AACpG,aAAO,GAAG,UAAU,IAAI,GAAG,IAAI,MAAM,GAAG,MAAM;AAAA,IAChD,CAAC;AACD,aAAS,KAAK;AAAA,MACZ,KAAK;AAAA,MACL,SAAS,UAAU,KAAK,IAAI;AAAA,MAC5B,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,QAAQ,EAAE,kBAAkB,MAAM,cAAc,KAAK;AAAA,IACrD;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,QASZ;AACb,QAAM,EAAE,MAAM,WAAW,WAAW,SAAS,eAAe,oBAAoB,WAAW,OAAO,IAAI;AACtG,QAAM,WAA0B,CAAC;AAGjC,MAAI,eAAe;AACjB,UAAM,gBAAgB,qBAAqB,wBAAwB,kBAAkB,IAAI;AACzF,aAAS,KAAK;AAAA,MACZ,KAAK;AAAA,MACL,UAAU;AAAA,MACV,QAAQ;AAAA,QACN,OAAO;AAAA,UACL,KAAK;AAAA,UACL,SAAS,aAAM,aAAa;AAAA,QAC9B;AAAA,QACA,gBAAgB;AAAA,QAChB,MAAM;AAAA,UACJ,KAAK;AAAA,UACL,OAAO;AAAA,UACP,MAAM;AAAA,QACR;AAAA,QACA,eAAe;AAAA,QACf,qBAAqB;AAAA,MACvB;AAAA,MACA,QAAQ,EAAE,OAAO,QAAQ,eAAe,MAAM;AAAA,MAC9C,kBAAkB;AAAA,MAClB,SAAS;AAAA,MACT,UAAU;AAAA,QACR;AAAA,UACE,KAAK;AAAA,UACL,SAAS;AAAA,UACT,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAGA,WAAS,KAAK;AAAA,IACZ,KAAK;AAAA,IACL,SAAS,sBAAsB,IAAI;AAAA,EACrC,CAAC;AAGD,MAAI,UAAU,SAAS,GAAG;AACxB,UAAM,mBAAmB,UAAU,IAAI,CAAC,OAAO;AAC7C,YAAM,aAAa,GAAG,WAAW,aAAa,WAAW;AACzD,aAAO,GAAG,UAAU,MAAM,GAAG,IAAI,QAAQ,GAAG,MAAM;AAAA,IACpD,CAAC;AAED,aAAS,KAAK;AAAA,MACZ,KAAK;AAAA,MACL,SAAS,iBAAiB,KAAK,IAAI;AAAA,MACnC,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAIA,QAAM,QAAkB,CAAC;AAEzB,MAAI,QAAQ,QAAQ;AAClB,QAAI,SAAS;AACX,YAAM,KAAK,cAAI;AAAA,IACjB,WAAW,WAAW;AACpB,YAAM,KAAK,oBAAK;AAAA,IAClB,OAAO;AACL,YAAM,KAAK,oBAAK;AAAA,IAClB;AAAA,EACF;AAEA,MAAI,QAAQ,WAAW,aAAa,MAAM;AACxC,UAAM,KAAK,gBAAM,cAAc,SAAS,CAAC,EAAE;AAAA,EAC7C;AAEA,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,aAAa,MAAM,KAAK,QAAK;AACnC,aAAS,KAAK,GAAG,YAAY,YAAY,OAAO,CAAC;AAAA,EACnD;AAIA,QAAM,cAAc,KAAK,QAAQ,mBAAmB,EAAE,EAAE,KAAK;AAC7D,QAAM,UAAU,cAAc,EAAE,SAAS,YAAY,MAAM,GAAG,GAAG,EAAE,IAAI;AAEvE,SAAO;AAAA,IACL,QAAQ,EAAE,kBAAkB,MAAM,cAAc,MAAM,QAAQ;AAAA,IAC9D;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,aAAsC;AAC9D,QAAM,WAA0B,CAAC;AAGjC,WAAS,KAAK;AAAA,IACZ,KAAK;AAAA,IACL,MAAM;AAAA,MACJ,KAAK;AAAA,MACL,SAAS,YAAY;AAAA,IACvB;AAAA,EACF,CAAC;AAGD,MAAI,YAAY,SAAS;AACvB,aAAS,KAAK,EAAE,KAAK,KAAK,CAAC;AAC3B,aAAS,KAAK;AAAA,MACZ,KAAK;AAAA,MACL,MAAM;AAAA,QACJ,KAAK;AAAA,QACL,SAAS;AAAA,EAAiB,YAAY,OAAO;AAAA,MAC/C;AAAA,IACF,CAAC;AAAA,EACH;AAGA,WAAS,KAAK,EAAE,KAAK,KAAK,CAAC;AAC3B,WAAS,KAAK;AAAA,IACZ,KAAK;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,KAAK;AAAA,QACL,MAAM,EAAE,KAAK,cAAc,SAAS,UAAU;AAAA,QAC9C,MAAM;AAAA,QACN,OAAO;AAAA,UACL,QAAQ;AAAA,UACR,cAAc,YAAY;AAAA,QAC5B;AAAA,MACF;AAAA,MACA;AAAA,QACE,KAAK;AAAA,QACL,MAAM,EAAE,KAAK,cAAc,SAAS,SAAS;AAAA,QAC7C,MAAM;AAAA,QACN,OAAO;AAAA,UACL,QAAQ;AAAA,UACR,cAAc,YAAY;AAAA,QAC5B;AAAA,MACF;AAAA,MACA,GAAI,YAAY,UACZ,CAAC,IACD;AAAA,QACE;AAAA,UACE,KAAK;AAAA,UACL,MAAM;AAAA,YACJ,KAAK;AAAA,YACL,SAAS;AAAA,UACX;AAAA,UACA,MAAM;AAAA,UACN,OAAO;AAAA,YACL,QAAQ;AAAA,YACR,cAAc,YAAY;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAAA,IACN;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,QAAQ,EAAE,kBAAkB,MAAM,cAAc,KAAK;AAAA,IACrD,QAAQ;AAAA,MACN,OAAO;AAAA,QACL,KAAK;AAAA,QACL,SAAS;AAAA,MACX;AAAA,MACA,UAAU;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AACF;AAUO,SAAS,WAAW,MAA2C;AACpE,QAAM,SAAkC;AAAA,IACtC,QAAQ;AAAA,IACR,QAAQ,KAAK;AAAA,IACb,MAAM,EAAE,UAAU,KAAK,SAAS;AAAA,EAClC;AACA,MAAI,KAAK,OAAQ,QAAO,SAAS,KAAK;AACtC,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|