weaver-work-cli 0.1.2 → 0.1.5
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/README.md +176 -78
- package/dist/cmd/setup/index.js +5 -5
- package/dist/cmd/skills/index.js +1 -1
- package/dist/core/hooks.js +7 -0
- package/dist/index.js +0 -0
- package/dist/internal/e10/auth/commands.js +159 -54
- package/dist/internal/e10/auth/xiaoe.js +268 -0
- package/dist/internal/e10/context.js +16 -2
- package/dist/internal/e10/index.js +1 -0
- package/dist/internal/e10/request-runtime.js +345 -0
- package/dist/internal/skills/install.js +48 -6
- package/dist/internal/skills/reader.js +27 -0
- package/dist/shortcuts/archive/continuation.js +70 -0
- package/dist/shortcuts/archive/errors.js +53 -0
- package/dist/shortcuts/archive/host.js +197 -0
- package/dist/shortcuts/archive/index.js +363 -0
- package/dist/shortcuts/archive/manifest.js +45 -0
- package/dist/shortcuts/archive/operations/archive-info.js +55 -0
- package/dist/shortcuts/archive/operations/borrow-car.js +146 -0
- package/dist/shortcuts/archive/operations/borrow-list.js +200 -0
- package/dist/shortcuts/archive/operations/confirm.js +46 -0
- package/dist/shortcuts/archive/operations/download.js +238 -0
- package/dist/shortcuts/archive/operations/flow-url.js +240 -0
- package/dist/shortcuts/archive/operations/fonds.js +95 -0
- package/dist/shortcuts/archive/operations/getPageUrl.js +137 -0
- package/dist/shortcuts/archive/operations/registry.js +43 -0
- package/dist/shortcuts/archive/operations/search.js +88 -0
- package/dist/shortcuts/archive/operations/shared.js +120 -0
- package/dist/shortcuts/archive/operations/types.js +23 -0
- package/dist/shortcuts/archive/operations/upload.js +182 -0
- package/dist/shortcuts/archive/operations.js +13 -0
- package/dist/shortcuts/archive/render/search-format.js +276 -0
- package/dist/shortcuts/archive/render/search-view.js +125 -0
- package/dist/shortcuts/asset/continuation.js +70 -0
- package/dist/shortcuts/asset/errors.js +67 -0
- package/dist/shortcuts/asset/host.js +438 -0
- package/dist/shortcuts/asset/index.js +255 -0
- package/dist/shortcuts/asset/manifest.js +471 -0
- package/dist/shortcuts/asset/operations/query.js +249 -0
- package/dist/shortcuts/asset/operations/registry.js +85 -0
- package/dist/shortcuts/asset/operations/shared.js +100 -0
- package/dist/shortcuts/asset/operations/type-cache.js +49 -0
- package/dist/shortcuts/asset/operations/types.js +1 -0
- package/dist/shortcuts/asset/operations/viewlink.js +117 -0
- package/dist/shortcuts/asset/operations/write.js +435 -0
- package/dist/shortcuts/asset/operations.js +9 -0
- package/dist/shortcuts/calendar/continuation.js +70 -0
- package/dist/shortcuts/calendar/errors.js +53 -0
- package/dist/shortcuts/calendar/host.js +148 -0
- package/dist/shortcuts/calendar/index.js +125 -0
- package/dist/shortcuts/calendar/manifest.js +26 -0
- package/dist/shortcuts/calendar/operations/read.js +259 -0
- package/dist/shortcuts/calendar/operations/registry.js +31 -0
- package/dist/shortcuts/calendar/operations/shared.js +132 -0
- package/dist/shortcuts/calendar/operations/types.js +25 -0
- package/dist/shortcuts/calendar/operations/write.js +439 -0
- package/dist/shortcuts/calendar/operations.js +8 -0
- package/dist/shortcuts/ehr/continuation.js +70 -0
- package/dist/shortcuts/ehr/errors.js +53 -0
- package/dist/shortcuts/ehr/host.js +213 -0
- package/dist/shortcuts/ehr/index.js +205 -0
- package/dist/shortcuts/ehr/manifest.js +47 -0
- package/dist/shortcuts/ehr/operations/attend-read.js +373 -0
- package/dist/shortcuts/ehr/operations/attend-write.js +514 -0
- package/dist/shortcuts/ehr/operations/hr-contact.js +363 -0
- package/dist/shortcuts/ehr/operations/hr-ds.js +298 -0
- package/dist/shortcuts/ehr/operations/hr-report.js +386 -0
- package/dist/shortcuts/ehr/operations/recruit-write.js +1629 -0
- package/dist/shortcuts/ehr/operations/recruit.js +803 -0
- package/dist/shortcuts/ehr/operations/registry.js +43 -0
- package/dist/shortcuts/ehr/operations/salary.js +319 -0
- package/dist/shortcuts/ehr/operations/shared.js +246 -0
- package/dist/shortcuts/ehr/operations/types.js +25 -0
- package/dist/shortcuts/ehr/operations.js +25 -0
- package/dist/shortcuts/esb/continuation.js +70 -0
- package/dist/shortcuts/esb/errors.js +65 -0
- package/dist/shortcuts/esb/host.js +187 -0
- package/dist/shortcuts/esb/index.js +112 -0
- package/dist/shortcuts/esb/manifest.js +91 -0
- package/dist/shortcuts/esb/operations/input-format.js +31 -0
- package/dist/shortcuts/esb/operations/registry.js +48 -0
- package/dist/shortcuts/esb/operations/shared.js +152 -0
- package/dist/shortcuts/esb/operations/trigger.js +76 -0
- package/dist/shortcuts/esb/operations/types.js +21 -0
- package/dist/shortcuts/esb/operations.js +15 -0
- package/dist/shortcuts/fna/continuation.js +70 -0
- package/dist/shortcuts/fna/errors.js +59 -0
- package/dist/shortcuts/fna/host.js +146 -0
- package/dist/shortcuts/fna/index.js +111 -0
- package/dist/shortcuts/fna/manifest.js +41 -0
- package/dist/shortcuts/fna/operations/budget.js +124 -0
- package/dist/shortcuts/fna/operations/expense-center.js +148 -0
- package/dist/shortcuts/fna/operations/invoice-writeoff.js +212 -0
- package/dist/shortcuts/fna/operations/loan.js +195 -0
- package/dist/shortcuts/fna/operations/registry.js +35 -0
- package/dist/shortcuts/fna/operations/shared.js +210 -0
- package/dist/shortcuts/fna/operations/types.js +25 -0
- package/dist/shortcuts/fna/operations.js +19 -0
- package/dist/shortcuts/hrm/errors.js +38 -0
- package/dist/shortcuts/hrm/host.js +156 -0
- package/dist/shortcuts/hrm/index.js +111 -0
- package/dist/shortcuts/hrm/manifest.js +32 -0
- package/dist/shortcuts/hrm/operations/employee.js +338 -0
- package/dist/shortcuts/hrm/operations/org.js +110 -0
- package/dist/shortcuts/hrm/operations/position.js +176 -0
- package/dist/shortcuts/hrm/operations/registry.js +33 -0
- package/dist/shortcuts/hrm/operations/shared.js +143 -0
- package/dist/shortcuts/hrm/operations/types.js +23 -0
- package/dist/shortcuts/hrm/operations.js +19 -0
- package/dist/shortcuts/index.js +24 -0
- package/dist/shortcuts/invoice/host.js +99 -94
- package/dist/shortcuts/invoice/index.js +58 -59
- package/dist/shortcuts/invoice/manifest.js +200 -3
- package/dist/shortcuts/invoice/operations/browse-field.js +17 -0
- package/dist/shortcuts/invoice/operations/issuing.js +198 -0
- package/dist/shortcuts/invoice/operations/registry.js +17 -0
- package/dist/shortcuts/invoice/operations/reim.js +401 -0
- package/dist/shortcuts/invoice/operations/shared.js +247 -0
- package/dist/shortcuts/jiuchuanhui/cache.js +441 -0
- package/dist/shortcuts/jiuchuanhui/continuation.js +70 -0
- package/dist/shortcuts/jiuchuanhui/errors.js +59 -0
- package/dist/shortcuts/jiuchuanhui/host.js +159 -0
- package/dist/shortcuts/jiuchuanhui/index.js +109 -0
- package/dist/shortcuts/jiuchuanhui/manifest.js +469 -0
- package/dist/shortcuts/jiuchuanhui/operations/datajson.js +214 -0
- package/dist/shortcuts/jiuchuanhui/operations/esb.js +157 -0
- package/dist/shortcuts/jiuchuanhui/operations/generic.js +146 -0
- package/dist/shortcuts/jiuchuanhui/operations/registry.js +133 -0
- package/dist/shortcuts/jiuchuanhui/operations/shared.js +158 -0
- package/dist/shortcuts/jiuchuanhui/operations/types.js +1 -0
- package/dist/shortcuts/jiuchuanhui/operations.js +8 -0
- package/dist/shortcuts/mail/continuation.js +70 -0
- package/dist/shortcuts/mail/errors.js +53 -0
- package/dist/shortcuts/mail/host.js +182 -0
- package/dist/shortcuts/mail/index.js +519 -0
- package/dist/shortcuts/mail/manifest.js +38 -0
- package/dist/shortcuts/mail/operations/mail-blacklist.js +79 -0
- package/dist/shortcuts/mail/operations/mail-contacts.js +195 -0
- package/dist/shortcuts/mail/operations/mail-manage.js +335 -0
- package/dist/shortcuts/mail/operations/mail-read.js +508 -0
- package/dist/shortcuts/mail/operations/mail-send.js +474 -0
- package/dist/shortcuts/mail/operations/mail-sign.js +203 -0
- package/dist/shortcuts/mail/operations/mail-template.js +170 -0
- package/dist/shortcuts/mail/operations/registry.js +41 -0
- package/dist/shortcuts/mail/operations/shared.js +64 -0
- package/dist/shortcuts/mail/operations/types.js +27 -0
- package/dist/shortcuts/mail/operations.js +19 -0
- package/dist/shortcuts/meeting/continuation.js +70 -0
- package/dist/shortcuts/meeting/errors.js +63 -0
- package/dist/shortcuts/meeting/host.js +167 -0
- package/dist/shortcuts/meeting/index.js +123 -0
- package/dist/shortcuts/meeting/manifest.js +64 -0
- package/dist/shortcuts/meeting/operations/catalogs.js +58 -0
- package/dist/shortcuts/meeting/operations/change.js +242 -0
- package/dist/shortcuts/meeting/operations/conflicts.js +142 -0
- package/dist/shortcuts/meeting/operations/create.js +349 -0
- package/dist/shortcuts/meeting/operations/env.js +191 -0
- package/dist/shortcuts/meeting/operations/lifecycle.js +139 -0
- package/dist/shortcuts/meeting/operations/meetings.js +73 -0
- package/dist/shortcuts/meeting/operations/receipts.js +195 -0
- package/dist/shortcuts/meeting/operations/registry.js +47 -0
- package/dist/shortcuts/meeting/operations/rooms.js +132 -0
- package/dist/shortcuts/meeting/operations/shared.js +112 -0
- package/dist/shortcuts/meeting/operations/signs.js +41 -0
- package/dist/shortcuts/meeting/operations/types.js +25 -0
- package/dist/shortcuts/meeting/operations.js +19 -0
- package/dist/shortcuts/plan/continuation.js +70 -0
- package/dist/shortcuts/plan/errors.js +70 -0
- package/dist/shortcuts/plan/host.js +180 -0
- package/dist/shortcuts/plan/index.js +150 -0
- package/dist/shortcuts/plan/manifest.js +53 -0
- package/dist/shortcuts/plan/operations/link.js +256 -0
- package/dist/shortcuts/plan/operations/read.js +259 -0
- package/dist/shortcuts/plan/operations/registry.js +33 -0
- package/dist/shortcuts/plan/operations/shared.js +246 -0
- package/dist/shortcuts/plan/operations/types.js +49 -0
- package/dist/shortcuts/plan/operations/version.js +49 -0
- package/dist/shortcuts/plan/operations/write.js +710 -0
- package/dist/shortcuts/plan/operations.js +8 -0
- package/dist/shortcuts/yimiaoban/continuation.js +70 -0
- package/dist/shortcuts/yimiaoban/errors.js +61 -0
- package/dist/shortcuts/yimiaoban/host.js +469 -0
- package/dist/shortcuts/yimiaoban/index.js +271 -0
- package/dist/shortcuts/yimiaoban/manifest.js +28 -0
- package/dist/shortcuts/yimiaoban/operations/file-user.js +288 -0
- package/dist/shortcuts/yimiaoban/operations/group-read.js +477 -0
- package/dist/shortcuts/yimiaoban/operations/group-write.js +591 -0
- package/dist/shortcuts/yimiaoban/operations/msg-parse.js +429 -0
- package/dist/shortcuts/yimiaoban/operations/msg-sync.js +519 -0
- package/dist/shortcuts/yimiaoban/operations/msg-write.js +593 -0
- package/dist/shortcuts/yimiaoban/operations/person.js +102 -0
- package/dist/shortcuts/yimiaoban/operations/registry.js +38 -0
- package/dist/shortcuts/yimiaoban/operations/session.js +437 -0
- package/dist/shortcuts/yimiaoban/operations/shared.js +236 -0
- package/dist/shortcuts/yimiaoban/operations/types.js +27 -0
- package/dist/shortcuts/yimiaoban/operations/write-util.js +78 -0
- package/dist/shortcuts/yimiaoban/operations.js +8 -0
- package/docs/SKILL.md +11 -7
- package/docs/_catalog.md +28 -5
- package/docs/agent-invoice.md +19 -9
- package/docs/agent-skill-install.md +141 -22
- package/docs/calendar.md +87 -0
- package/docs/e10-auth.md +28 -9
- package/docs/ehr.md +186 -0
- package/docs/esb.md +64 -0
- package/docs/fna.md +72 -0
- package/docs/hrm.md +89 -0
- package/docs/invoice.md +61 -20
- package/docs/jiuchuanhui.md +131 -0
- package/docs/meeting.md +48 -0
- package/docs/operation-manual.md +443 -0
- package/docs/plan.md +82 -0
- package/docs/wenshuding.md +129 -0
- package/docs/yimiaoban.md +86 -0
- package/docs/ziguanjia.md +89 -0
- package/package.json +4 -4
- package/scripts/package-skill.mjs +127 -34
- package/scripts/postbuild.mjs +13 -0
- package/skill-template/business-info.json +16 -2
- package/skill-template/domains/calendar.md +15 -0
- package/skill-template/domains/esb.md +13 -0
- package/skill-template/domains/hrm.md +16 -0
- package/skill-template/domains/jiuchuanhui.md +23 -0
- package/skill-template/domains/jucailin.md +22 -0
- package/skill-template/domains/mail.md +21 -0
- package/skill-template/domains/meeting.md +3 -0
- package/skill-template/domains/plan.md +17 -0
- package/skill-template/domains/qiyecheng.md +17 -0
- package/skill-template/domains/shared.md +5 -3
- package/skill-template/domains/skill-maker.md +10 -0
- package/skill-template/domains/wenshuding.md +22 -0
- package/skill-template/domains/{invoice.md → yepiaotong.md} +4 -0
- package/skill-template/domains/yimiaoban.md +21 -0
- package/skill-template/domains/ziguanjia.md +21 -0
- package/skill-template/master-skill-template.md +12 -6
- package/skill-template/skill-template.md +26 -10
- package/skills/weaver-e10-calendar/SKILL.md +102 -0
- package/skills/weaver-e10-calendar/product.json +8 -0
- package/skills/weaver-e10-calendar/references/calendar-app-check.md +65 -0
- package/skills/weaver-e10-calendar/references/calendar-dict.md +55 -0
- package/skills/weaver-e10-calendar/references/calendar-query.md +70 -0
- package/skills/weaver-e10-calendar/references/calendar-write.md +97 -0
- package/skills/weaver-e10-calendar/references/source-manifest.json +54 -0
- package/skills/weaver-e10-esb/SKILL.md +103 -0
- package/skills/weaver-e10-esb/product.json +8 -0
- package/skills/weaver-e10-esb/references/input-format.md +52 -0
- package/skills/weaver-e10-esb/references/source-manifest.json +242 -0
- package/skills/weaver-e10-esb/references/trigger.md +99 -0
- package/skills/weaver-e10-hrm/SKILL.md +88 -0
- package/skills/weaver-e10-hrm/product.json +8 -0
- package/skills/weaver-e10-hrm/references/employee.md +109 -0
- package/skills/weaver-e10-hrm/references/org.md +95 -0
- package/skills/weaver-e10-hrm/references/position.md +95 -0
- package/skills/weaver-e10-hrm/references/source-manifest.json +121 -0
- package/skills/weaver-e10-jiuchuanhui/SKILL.md +175 -0
- package/skills/weaver-e10-jiuchuanhui/product.json +8 -0
- package/skills/weaver-e10-jiuchuanhui/references/cache.md +110 -0
- package/skills/weaver-e10-jiuchuanhui/references/clue.md +61 -0
- package/skills/weaver-e10-jiuchuanhui/references/contact-plan.md +56 -0
- package/skills/weaver-e10-jiuchuanhui/references/contact-records.md +48 -0
- package/skills/weaver-e10-jiuchuanhui/references/contact.md +56 -0
- package/skills/weaver-e10-jiuchuanhui/references/customer.md +69 -0
- package/skills/weaver-e10-jiuchuanhui/references/disabled-capabilities.md +24 -0
- package/skills/weaver-e10-jiuchuanhui/references/discovery-config.md +60 -0
- package/skills/weaver-e10-jiuchuanhui/references/general-helpers.md +59 -0
- package/skills/weaver-e10-jiuchuanhui/references/jiuchuanhui-entry.md +60 -0
- package/skills/weaver-e10-jiuchuanhui/references/sale.md +72 -0
- package/skills/weaver-e10-jiuchuanhui/references/source-manifest.json +2632 -0
- package/skills/weaver-e10-jucailin/SKILL.md +102 -0
- package/skills/weaver-e10-jucailin/product.json +8 -0
- package/skills/weaver-e10-jucailin/references/attend-read.md +73 -0
- package/skills/weaver-e10-jucailin/references/attend-write.md +82 -0
- package/skills/weaver-e10-jucailin/references/hr-contact.md +92 -0
- package/skills/weaver-e10-jucailin/references/hr-datasource.md +104 -0
- package/skills/weaver-e10-jucailin/references/hr-report.md +76 -0
- package/skills/weaver-e10-jucailin/references/recruit-read.md +76 -0
- package/skills/weaver-e10-jucailin/references/recruit-write.md +70 -0
- package/skills/weaver-e10-jucailin/references/safety-boundaries.md +35 -0
- package/skills/weaver-e10-jucailin/references/salary.md +110 -0
- package/skills/weaver-e10-jucailin/references/source-manifest.json +152 -0
- package/skills/weaver-e10-mail/SKILL.md +152 -0
- package/skills/weaver-e10-mail/product.json +8 -0
- package/skills/weaver-e10-mail/references/mail-agent-entry.md +47 -0
- package/skills/weaver-e10-mail/references/mail-attachment.md +30 -0
- package/skills/weaver-e10-mail/references/mail-blacklist.md +27 -0
- package/skills/weaver-e10-mail/references/mail-contacts.md +33 -0
- package/skills/weaver-e10-mail/references/mail-manage.md +44 -0
- package/skills/weaver-e10-mail/references/mail-read.md +76 -0
- package/skills/weaver-e10-mail/references/mail-send.md +43 -0
- package/skills/weaver-e10-mail/references/mail-sign.md +33 -0
- package/skills/weaver-e10-mail/references/mail-template.md +31 -0
- package/skills/weaver-e10-mail/references/safety-boundaries.md +32 -0
- package/skills/weaver-e10-meeting/SKILL.md +106 -0
- package/skills/weaver-e10-meeting/product.json +8 -0
- package/skills/weaver-e10-meeting/references/meeting-change.md +67 -0
- package/skills/weaver-e10-meeting/references/meeting-create.md +52 -0
- package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +57 -0
- package/skills/weaver-e10-meeting/references/meeting-queries.md +61 -0
- package/skills/weaver-e10-meeting/references/meeting-receipts-signs.md +48 -0
- package/skills/weaver-e10-meeting/references/meeting-update.md +7 -0
- package/skills/weaver-e10-meeting/references/source-manifest.json +50 -0
- package/skills/weaver-e10-plan/SKILL.md +140 -0
- package/skills/weaver-e10-plan/product.json +8 -0
- package/skills/weaver-e10-plan/references/plan-collect-and-compose.md +123 -0
- package/skills/weaver-e10-plan/references/plan-overview-and-routing.md +138 -0
- package/skills/weaver-e10-plan/references/plan-report-query.md +154 -0
- package/skills/weaver-e10-plan/references/plan-report-remind.md +104 -0
- package/skills/weaver-e10-plan/references/plan-report-write.md +162 -0
- package/skills/weaver-e10-plan/references/source-manifest.json +858 -0
- package/skills/weaver-e10-qiyecheng/SKILL.md +119 -0
- package/skills/weaver-e10-qiyecheng/product.json +8 -0
- package/skills/weaver-e10-qiyecheng/references/budget.md +65 -0
- package/skills/weaver-e10-qiyecheng/references/catalog.md +56 -0
- package/skills/weaver-e10-qiyecheng/references/expense-center.md +51 -0
- package/skills/weaver-e10-qiyecheng/references/invoice-writeoff.md +57 -0
- package/skills/weaver-e10-qiyecheng/references/loan-management.md +59 -0
- package/skills/weaver-e10-qiyecheng/references/source-manifest.json +698 -0
- package/skills/weaver-e10-shared/SKILL.md +90 -0
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +127 -0
- package/skills/{weaver-work-cli-shared → weaver-e10-shared}/references/json-output-contract.md +34 -0
- package/skills/weaver-e10-shared/references/weaver-e10-installation.md +110 -0
- package/skills/weaver-e10-skill-maker/SKILL.md +78 -0
- package/skills/weaver-e10-skill-maker/product.json +8 -0
- package/skills/weaver-e10-skill-maker/references/business-skill-generation.md +124 -0
- package/skills/weaver-e10-skill-maker/references/detector-validation.md +101 -0
- package/skills/weaver-e10-skill-maker/references/module-cli-generation.md +230 -0
- package/skills/weaver-e10-skill-maker/references/post-generation-install.md +105 -0
- package/skills/weaver-e10-skill-maker/references/source-update-detection.md +261 -0
- package/skills/weaver-e10-skill-maker/references/weaver-skill-style.md +141 -0
- package/skills/weaver-e10-wenshuding/SKILL.md +158 -0
- package/skills/weaver-e10-wenshuding/product.json +8 -0
- package/skills/weaver-e10-wenshuding/references/archive-agent-entry.md +63 -0
- package/skills/weaver-e10-wenshuding/references/archive-borrow-car.md +52 -0
- package/skills/weaver-e10-wenshuding/references/archive-borrow-list.md +52 -0
- package/skills/weaver-e10-wenshuding/references/archive-disabled-capabilities.md +22 -0
- package/skills/weaver-e10-wenshuding/references/archive-download.md +48 -0
- package/skills/weaver-e10-wenshuding/references/archive-flow.md +46 -0
- package/skills/weaver-e10-wenshuding/references/archive-fonds.md +34 -0
- package/skills/weaver-e10-wenshuding/references/archive-info.md +33 -0
- package/skills/weaver-e10-wenshuding/references/archive-search.md +52 -0
- package/skills/weaver-e10-wenshuding/references/archive-upload.md +41 -0
- package/skills/weaver-e10-wenshuding/references/source-manifest.json +517 -0
- package/skills/weaver-e10-yepiaotong/SKILL.md +184 -0
- package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-add.md +1 -1
- package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-agent-entry.md +16 -9
- package/skills/weaver-e10-yepiaotong/references/invoice-browse-field-data.md +204 -0
- package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-delete.md +1 -1
- package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-detail.md +13 -5
- package/skills/weaver-e10-yepiaotong/references/invoice-disabled-capabilities.md +28 -0
- package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-download.md +9 -2
- package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-enterprise-list.md +12 -4
- package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-file-upload.md +9 -2
- package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-import.md +16 -7
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +120 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-field-rules.md +161 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing.md +99 -0
- package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-ocr-preview.md +12 -4
- package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-personal-list.md +12 -4
- package/skills/weaver-e10-yepiaotong/references/invoice-red.md +261 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +97 -0
- package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-update.md +1 -1
- package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-validation-preview.md +9 -2
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +1340 -0
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +845 -0
- package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +94 -0
- package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +449 -0
- package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +266 -0
- package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +494 -0
- package/skills/weaver-e10-yepiaotong/references/source-manifest.json +1103 -0
- package/skills/weaver-e10-yimiaoban/SKILL.md +104 -0
- package/skills/weaver-e10-yimiaoban/product.json +8 -0
- package/skills/weaver-e10-yimiaoban/references/ding-write.md +68 -0
- package/skills/weaver-e10-yimiaoban/references/error-codes.md +85 -0
- package/skills/weaver-e10-yimiaoban/references/field-resolution.md +46 -0
- package/skills/weaver-e10-yimiaoban/references/file-user-i18n.md +54 -0
- package/skills/weaver-e10-yimiaoban/references/group-read.md +55 -0
- package/skills/weaver-e10-yimiaoban/references/group-write.md +72 -0
- package/skills/weaver-e10-yimiaoban/references/msg-read.md +59 -0
- package/skills/weaver-e10-yimiaoban/references/msg-write.md +64 -0
- package/skills/weaver-e10-yimiaoban/references/person.md +44 -0
- package/skills/weaver-e10-yimiaoban/references/safety-boundaries.md +61 -0
- package/skills/weaver-e10-yimiaoban/references/session-sysmsg.md +47 -0
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +485 -0
- package/skills/weaver-e10-ziguanjia/SKILL.md +163 -0
- package/skills/weaver-e10-ziguanjia/product.json +8 -0
- package/skills/weaver-e10-ziguanjia/references/source-manifest.json +147 -0
- package/skills/weaver-e10-ziguanjia/references/ziguanjia-agent-entry.md +65 -0
- package/skills/weaver-e10-ziguanjia/references/ziguanjia-create.md +45 -0
- package/skills/weaver-e10-ziguanjia/references/ziguanjia-depre.md +48 -0
- package/skills/weaver-e10-ziguanjia/references/ziguanjia-disabled-capabilities.md +22 -0
- package/skills/weaver-e10-ziguanjia/references/ziguanjia-purch.md +57 -0
- package/skills/weaver-e10-ziguanjia/references/ziguanjia-query.md +62 -0
- package/skills/weaver-e10-ziguanjia/references/ziguanjia-repair.md +83 -0
- package/skills/weaver-e10-ziguanjia/references/ziguanjia-resolve.md +49 -0
- package/skills/weaver-e10-ziguanjia/references/ziguanjia-return.md +70 -0
- package/skills/weaver-e10-ziguanjia/references/ziguanjia-update.md +45 -0
- package/skills/weaver-e10-ziguanjia/references/ziguanjia-use.md +60 -0
- package/skills/weaver-e10-ziguanjia/references/ziguanjia-viewlink.md +81 -0
- package/skills/weaver-work-cli-invoice/SKILL.md +0 -122
- package/skills/weaver-work-cli-invoice/references/invoice-disabled-capabilities.md +0 -26
- package/skills/weaver-work-cli-shared/SKILL.md +0 -63
- package/skills/weaver-work-cli-shared/references/e10-auth-and-session.md +0 -90
- package/skills/weaver-work-cli-shared/references/weaver-work-cli-installation.md +0 -73
- /package/skills/{weaver-work-cli-shared → weaver-e10-shared}/references/high-risk-write.md +0 -0
- /package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/product.json +0 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { mailValidationError } from '../errors.js';
|
|
2
|
+
import { WRITE, mailSuccess, schemaOf, SCHEMA_STRING } from './types.js';
|
|
3
|
+
const CONTINUATION_TTL_MS = 600_000;
|
|
4
|
+
const TEMPLATE_SCHEMA = schemaOf({
|
|
5
|
+
id: SCHEMA_STRING,
|
|
6
|
+
templateType: SCHEMA_STRING,
|
|
7
|
+
subject: SCHEMA_STRING,
|
|
8
|
+
mailSubject: SCHEMA_STRING,
|
|
9
|
+
clobContent: SCHEMA_STRING,
|
|
10
|
+
templateDesc: SCHEMA_STRING,
|
|
11
|
+
defaultUse: SCHEMA_STRING,
|
|
12
|
+
contentId: SCHEMA_STRING,
|
|
13
|
+
confirm: { type: 'boolean' },
|
|
14
|
+
continuation: SCHEMA_STRING,
|
|
15
|
+
}, { description: '模板保存(prepare/apply)' });
|
|
16
|
+
function buildTemplateBody(args) {
|
|
17
|
+
const subject = String(args.subject || '').trim();
|
|
18
|
+
const clobContent = String(args.clobContent || '').trim();
|
|
19
|
+
if (!subject)
|
|
20
|
+
throw new Error('subject(模板主题)必填');
|
|
21
|
+
if (!clobContent)
|
|
22
|
+
throw new Error('clobContent(Base64 编码的 HTML 内容)必填');
|
|
23
|
+
const body = {
|
|
24
|
+
templateType: args.templateType ? String(args.templateType) : 'personal',
|
|
25
|
+
subject,
|
|
26
|
+
mailSubject: args.mailSubject ? String(args.mailSubject) : subject,
|
|
27
|
+
clobContent,
|
|
28
|
+
templateDesc: args.templateDesc ? String(args.templateDesc) : '',
|
|
29
|
+
defaultUse: args.defaultUse !== undefined ? Number(args.defaultUse) : 0,
|
|
30
|
+
contentId: args.contentId ? String(args.contentId) : 'null',
|
|
31
|
+
id: 'null',
|
|
32
|
+
templateFile: [],
|
|
33
|
+
};
|
|
34
|
+
if (args.id)
|
|
35
|
+
body.id = String(args.id);
|
|
36
|
+
return body;
|
|
37
|
+
}
|
|
38
|
+
const opTemplateSavePrepare = {
|
|
39
|
+
name: 'mail.template.save.prepare',
|
|
40
|
+
resource: 'mail/base/setting/template/saveMailTemplate',
|
|
41
|
+
method: 'POST',
|
|
42
|
+
action: 'mail.template.save.prepare',
|
|
43
|
+
summary: '新增模板(prepare,不保存)',
|
|
44
|
+
risk: WRITE,
|
|
45
|
+
requiresConfirmation: true,
|
|
46
|
+
inputSchema: TEMPLATE_SCHEMA,
|
|
47
|
+
async handler(args, env) {
|
|
48
|
+
const body = buildTemplateBody(args);
|
|
49
|
+
const session = await env.host.getSession();
|
|
50
|
+
const continuation = await env.continuation.issue({
|
|
51
|
+
operation: 'mail.template.save.apply',
|
|
52
|
+
baseUrl: session.baseUrl,
|
|
53
|
+
profile: session.profile,
|
|
54
|
+
userId: session.userId,
|
|
55
|
+
body,
|
|
56
|
+
}, CONTINUATION_TTL_MS);
|
|
57
|
+
return mailSuccess('mail.template.save.prepare', {
|
|
58
|
+
subject: body.subject,
|
|
59
|
+
templateType: body.templateType,
|
|
60
|
+
defaultUse: body.defaultUse,
|
|
61
|
+
tip: '确认后以 mail template save --apply --continuation <token> --yes 执行保存',
|
|
62
|
+
}, { continuation });
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
const opTemplateSaveApply = {
|
|
66
|
+
name: 'mail.template.save.apply',
|
|
67
|
+
resource: 'mail/base/setting/template/saveMailTemplate',
|
|
68
|
+
method: 'POST',
|
|
69
|
+
action: 'mail.template.save.apply',
|
|
70
|
+
summary: '执行新增模板',
|
|
71
|
+
risk: WRITE,
|
|
72
|
+
requiresConfirmation: true,
|
|
73
|
+
inputSchema: TEMPLATE_SCHEMA,
|
|
74
|
+
async handler(args, env) {
|
|
75
|
+
if (args.confirm !== true)
|
|
76
|
+
throw new Error('mail.template.save.apply 必须传入 confirm=true 与 prepare 返回的 continuation');
|
|
77
|
+
if (!args.continuation)
|
|
78
|
+
throw new Error('mail.template.save.apply 必须传入 prepare 返回的 continuation');
|
|
79
|
+
const lease = await env.continuation.verify(String(args.continuation), 'mail.template.save.apply');
|
|
80
|
+
const session = await env.host.getSession();
|
|
81
|
+
if (lease.baseUrl !== session.baseUrl || lease.profile !== session.profile || lease.userId !== session.userId) {
|
|
82
|
+
throw mailValidationError('context_mismatch', '确认上下文已变化(租户或登录账号不同),请重新执行 prepare');
|
|
83
|
+
}
|
|
84
|
+
const value = (await env.host.request({ path: '/api/mail/base/setting/template/saveMailTemplate', method: 'POST', body: lease.body }));
|
|
85
|
+
return mailSuccess('mail.template.save.apply', { id: value?.data ?? 'SUCCESS' }, {});
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
const opTemplateUpdate = {
|
|
89
|
+
name: 'mail.template.update',
|
|
90
|
+
resource: 'mail/base/setting/template/updateMailTemplate',
|
|
91
|
+
method: 'POST',
|
|
92
|
+
action: 'mail.template.update',
|
|
93
|
+
summary: '编辑模板(GET 全量 + 保存)',
|
|
94
|
+
risk: WRITE,
|
|
95
|
+
inputSchema: schemaOf({
|
|
96
|
+
id: { type: 'string', description: '模板 id' },
|
|
97
|
+
subject: SCHEMA_STRING,
|
|
98
|
+
clobContent: SCHEMA_STRING,
|
|
99
|
+
templateDesc: SCHEMA_STRING,
|
|
100
|
+
defaultUse: SCHEMA_STRING,
|
|
101
|
+
templateType: SCHEMA_STRING,
|
|
102
|
+
}, { required: ['id'], description: '编辑模板' }),
|
|
103
|
+
async handler(args, env) {
|
|
104
|
+
const id = String(args.id || '').trim();
|
|
105
|
+
if (!id)
|
|
106
|
+
throw new Error('id(模板 id)必填');
|
|
107
|
+
const info = (await env.host.request({
|
|
108
|
+
path: '/api/mail/base/setting/template/getMailTemplateInfo',
|
|
109
|
+
method: 'POST',
|
|
110
|
+
form: { id, fromModule: 'mail' },
|
|
111
|
+
}));
|
|
112
|
+
const cur = info?.data || {};
|
|
113
|
+
const body = {
|
|
114
|
+
id,
|
|
115
|
+
templateType: args.templateType ? String(args.templateType) : (cur.templateType ?? 'personal'),
|
|
116
|
+
mailSubject: args.mailSubject ? String(args.mailSubject) : (cur.mailSubject ?? ''),
|
|
117
|
+
subject: args.subject ? String(args.subject) : (cur.subject ?? ''),
|
|
118
|
+
clobContent: args.clobContent ? String(args.clobContent) : (cur.clobContent ?? ''),
|
|
119
|
+
templateDesc: args.templateDesc ? String(args.templateDesc) : (cur.templateDesc ?? ''),
|
|
120
|
+
defaultUse: args.defaultUse !== undefined ? Number(args.defaultUse) : (cur.defaultUse ?? 0),
|
|
121
|
+
contentId: cur.contentId ?? 'null',
|
|
122
|
+
templateFile: cur.templateFile ?? [],
|
|
123
|
+
};
|
|
124
|
+
if (!body.subject)
|
|
125
|
+
throw new Error('模板主题为空(原值缺失且未提供 subject)');
|
|
126
|
+
if (!body.clobContent)
|
|
127
|
+
throw new Error('模板内容为空(原值缺失且未提供 clobContent)');
|
|
128
|
+
const value = (await env.host.request({ path: '/api/mail/base/setting/template/updateMailTemplate', method: 'POST', body }));
|
|
129
|
+
return mailSuccess('mail.template.update', value?.data ?? 'SUCCESS', { id });
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
const opTemplateDelete = {
|
|
133
|
+
name: 'mail.template.delete',
|
|
134
|
+
resource: 'mail/base/setting/template/deleteMailTemplate',
|
|
135
|
+
method: 'POST',
|
|
136
|
+
action: 'mail.template.delete',
|
|
137
|
+
summary: '删除模板',
|
|
138
|
+
risk: WRITE,
|
|
139
|
+
inputSchema: schemaOf({ id: { type: 'string', description: '模板 id' } }, { required: ['id'], description: '删除模板' }),
|
|
140
|
+
async handler(args, env) {
|
|
141
|
+
const id = String(args.id || '').trim();
|
|
142
|
+
if (!id)
|
|
143
|
+
throw new Error('id(模板 id)必填');
|
|
144
|
+
const value = (await env.host.request({ path: '/api/mail/base/setting/template/deleteMailTemplate', method: 'POST', body: { id } }));
|
|
145
|
+
return mailSuccess('mail.template.delete', value?.data ?? 'SUCCESS', { id });
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
const opTemplateDefault = {
|
|
149
|
+
name: 'mail.template.default',
|
|
150
|
+
resource: 'mail/base/setting/template/defaultMailTemplate',
|
|
151
|
+
method: 'POST',
|
|
152
|
+
action: 'mail.template.default',
|
|
153
|
+
summary: '设为默认模板',
|
|
154
|
+
risk: WRITE,
|
|
155
|
+
inputSchema: schemaOf({ id: { type: 'string', description: '模板 id' } }, { required: ['id'], description: '设默认模板' }),
|
|
156
|
+
async handler(args, env) {
|
|
157
|
+
const id = String(args.id || '').trim();
|
|
158
|
+
if (!id)
|
|
159
|
+
throw new Error('id(模板 id)必填');
|
|
160
|
+
const value = (await env.host.request({ path: '/api/mail/base/setting/template/defaultMailTemplate', method: 'POST', body: { id } }));
|
|
161
|
+
return mailSuccess('mail.template.default', value?.data ?? 'SUCCESS', { id });
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
export const mailTemplateOperations = [
|
|
165
|
+
opTemplateSavePrepare,
|
|
166
|
+
opTemplateSaveApply,
|
|
167
|
+
opTemplateUpdate,
|
|
168
|
+
opTemplateDelete,
|
|
169
|
+
opTemplateDefault,
|
|
170
|
+
];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { mailValidationError } from '../errors.js';
|
|
2
|
+
import { mailReadOperations } from './mail-read.js';
|
|
3
|
+
import { mailSendOperations } from './mail-send.js';
|
|
4
|
+
import { mailManageOperations } from './mail-manage.js';
|
|
5
|
+
import { mailContactsOperations } from './mail-contacts.js';
|
|
6
|
+
import { mailTemplateOperations } from './mail-template.js';
|
|
7
|
+
import { mailSignOperations } from './mail-sign.js';
|
|
8
|
+
import { mailBlacklistOperations } from './mail-blacklist.js';
|
|
9
|
+
function buildRegistry() {
|
|
10
|
+
const registry = new Map();
|
|
11
|
+
const definitions = [
|
|
12
|
+
...mailReadOperations,
|
|
13
|
+
...mailSendOperations,
|
|
14
|
+
...mailManageOperations,
|
|
15
|
+
...mailContactsOperations,
|
|
16
|
+
...mailTemplateOperations,
|
|
17
|
+
...mailSignOperations,
|
|
18
|
+
...mailBlacklistOperations,
|
|
19
|
+
];
|
|
20
|
+
for (const definition of definitions) {
|
|
21
|
+
if (registry.has(definition.name)) {
|
|
22
|
+
throw new Error(`duplicate mail operation: ${definition.name}`);
|
|
23
|
+
}
|
|
24
|
+
registry.set(definition.name, definition);
|
|
25
|
+
}
|
|
26
|
+
return registry;
|
|
27
|
+
}
|
|
28
|
+
const mailOperationRegistry = buildRegistry();
|
|
29
|
+
export function mailOperationDefinitions() {
|
|
30
|
+
return [...mailOperationRegistry.values()];
|
|
31
|
+
}
|
|
32
|
+
export function getMailOperation(operation) {
|
|
33
|
+
const definition = mailOperationRegistry.get(operation);
|
|
34
|
+
if (!definition) {
|
|
35
|
+
throw mailValidationError('operation_unknown', `邮件模块不支持操作:${operation}`);
|
|
36
|
+
}
|
|
37
|
+
return definition;
|
|
38
|
+
}
|
|
39
|
+
export function hasMailOperation(operation) {
|
|
40
|
+
return mailOperationRegistry.has(operation);
|
|
41
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { mailValidationError } from '../errors.js';
|
|
2
|
+
const FORBIDDEN_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
|
|
3
|
+
export function asObject(value) {
|
|
4
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
5
|
+
throw mailValidationError('input_not_object', '输入必须是 JSON 对象');
|
|
6
|
+
}
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
export function assertNoForbiddenKeys(input) {
|
|
10
|
+
for (const key of Object.keys(input)) {
|
|
11
|
+
if (FORBIDDEN_KEYS.has(key)) {
|
|
12
|
+
throw mailValidationError('forbidden_key', `输入包含非法字段:${key}`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** 移除值为 undefined 的键,避免把空值写进请求体。 */
|
|
17
|
+
export function compact(body) {
|
|
18
|
+
for (const key of Object.keys(body)) {
|
|
19
|
+
if (body[key] === undefined)
|
|
20
|
+
delete body[key];
|
|
21
|
+
}
|
|
22
|
+
return body;
|
|
23
|
+
}
|
|
24
|
+
export function toNumber(value, field) {
|
|
25
|
+
if (value === undefined || value === null || value === '')
|
|
26
|
+
return undefined;
|
|
27
|
+
const numeric = Number(value);
|
|
28
|
+
if (!Number.isFinite(numeric)) {
|
|
29
|
+
throw mailValidationError('number_invalid', `${field} 必须是数字`);
|
|
30
|
+
}
|
|
31
|
+
return numeric;
|
|
32
|
+
}
|
|
33
|
+
export function toPositiveInt(value, field) {
|
|
34
|
+
if (value === undefined || value === null || value === '')
|
|
35
|
+
return undefined;
|
|
36
|
+
const numeric = Number(value);
|
|
37
|
+
if (!Number.isFinite(numeric)) {
|
|
38
|
+
throw mailValidationError('number_invalid', `${field} 必须是数字`);
|
|
39
|
+
}
|
|
40
|
+
const truncated = Math.trunc(numeric);
|
|
41
|
+
if (truncated !== numeric || truncated <= 0) {
|
|
42
|
+
throw mailValidationError('number_invalid', `${field} 必须是正整数`);
|
|
43
|
+
}
|
|
44
|
+
return truncated;
|
|
45
|
+
}
|
|
46
|
+
/** ID 归一化为 string[](部分接口要求字符串 id,19 位 id 必须保持字符串防精度丢失)。 */
|
|
47
|
+
export function toStringIdList(value, field) {
|
|
48
|
+
if (value === undefined || value === null)
|
|
49
|
+
return undefined;
|
|
50
|
+
if (!Array.isArray(value))
|
|
51
|
+
throw mailValidationError('id_list_invalid', `${field} 必须是 ID 数组`);
|
|
52
|
+
return value.map((item, index) => {
|
|
53
|
+
if (item === undefined || item === null || item === '') {
|
|
54
|
+
throw mailValidationError('id_list_invalid', `${field}[${index}] 不能为空`);
|
|
55
|
+
}
|
|
56
|
+
return String(item);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/** 取响应中的业务数据。 */
|
|
60
|
+
export function unwrapData(response) {
|
|
61
|
+
if (!response || typeof response !== 'object')
|
|
62
|
+
return response;
|
|
63
|
+
return response.data;
|
|
64
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const READ = 'read';
|
|
2
|
+
export const WRITE = 'write';
|
|
3
|
+
export function mailSuccess(action, data, meta) {
|
|
4
|
+
const payload = { ok: true, action, data };
|
|
5
|
+
if (meta && Object.keys(meta).length > 0)
|
|
6
|
+
payload.meta = meta;
|
|
7
|
+
return payload;
|
|
8
|
+
}
|
|
9
|
+
/** 构造「对象类型 + 严格禁止额外字段」的 JSON Schema。 */
|
|
10
|
+
export function schemaOf(properties, options = {}) {
|
|
11
|
+
return {
|
|
12
|
+
type: 'object',
|
|
13
|
+
additionalProperties: false,
|
|
14
|
+
properties,
|
|
15
|
+
...(options.required?.length ? { required: options.required } : {}),
|
|
16
|
+
...(options.description ? { description: options.description } : {}),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export const SCHEMA_STRING = { type: 'string' };
|
|
20
|
+
export const SCHEMA_STRING_LIST = { type: 'array', items: { type: 'string' } };
|
|
21
|
+
export const SCHEMA_INTEGER = { type: 'integer' };
|
|
22
|
+
export const SCHEMA_BOOLEAN = { type: 'boolean' };
|
|
23
|
+
export const SCHEMA_POSITIVE_INT = { type: 'integer', minimum: 1 };
|
|
24
|
+
export const SCHEMA_ID = {
|
|
25
|
+
oneOf: [{ type: 'integer' }, { type: 'string', pattern: '^\\d+$' }],
|
|
26
|
+
};
|
|
27
|
+
export const SCHEMA_ID_LIST = { type: 'array', items: SCHEMA_ID };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { getMailOperation } from './operations/registry.js';
|
|
2
|
+
import { assertNoForbiddenKeys, asObject } from './operations/shared.js';
|
|
3
|
+
export async function executeMailOperation(operation, rawInput, context) {
|
|
4
|
+
const definition = getMailOperation(operation);
|
|
5
|
+
const input = asObject(rawInput);
|
|
6
|
+
assertNoForbiddenKeys(input);
|
|
7
|
+
const host = {
|
|
8
|
+
request(request) {
|
|
9
|
+
return context.host.request({
|
|
10
|
+
...request,
|
|
11
|
+
operation: request.operation || operation,
|
|
12
|
+
});
|
|
13
|
+
},
|
|
14
|
+
getSession() {
|
|
15
|
+
return context.host.getSession();
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
return definition.handler(input, { ...context, host });
|
|
19
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { chmod, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { resolve } from 'node:path';
|
|
6
|
+
import { meetingValidationError } from './errors.js';
|
|
7
|
+
function stateRoot(ctx) {
|
|
8
|
+
const configured = ctx?.config?.path();
|
|
9
|
+
if (configured)
|
|
10
|
+
return resolve(configured, '..');
|
|
11
|
+
return process.env.WEAVER_WORK_CLI_HOME || process.env.WORK_CLI_HOME || resolve(homedir(), '.weaver-work-cli');
|
|
12
|
+
}
|
|
13
|
+
async function loadKey(ctx) {
|
|
14
|
+
const keysDir = resolve(stateRoot(ctx), 'keys');
|
|
15
|
+
const filename = resolve(keysDir, 'meeting-continuation.key');
|
|
16
|
+
await mkdir(keysDir, { recursive: true, mode: 0o700 });
|
|
17
|
+
if (existsSync(filename))
|
|
18
|
+
return readFile(filename);
|
|
19
|
+
const key = randomBytes(32);
|
|
20
|
+
try {
|
|
21
|
+
await writeFile(filename, key, { flag: 'wx', mode: 0o600 });
|
|
22
|
+
if (process.platform !== 'win32')
|
|
23
|
+
await chmod(filename, 0o600).catch(() => undefined);
|
|
24
|
+
return key;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return readFile(filename);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function encode(value) {
|
|
31
|
+
return Buffer.from(JSON.stringify(value)).toString('base64url');
|
|
32
|
+
}
|
|
33
|
+
function signature(payload, key) {
|
|
34
|
+
return createHmac('sha256', key).update(payload).digest('base64url');
|
|
35
|
+
}
|
|
36
|
+
export function createMeetingContinuationSigner(ctx) {
|
|
37
|
+
return {
|
|
38
|
+
async issue(payload, ttlMs = 10 * 60_000) {
|
|
39
|
+
const issuedAt = Date.now();
|
|
40
|
+
const body = encode({ ...payload, issuedAt, expiresAt: issuedAt + ttlMs });
|
|
41
|
+
const sig = signature(body, await loadKey(ctx));
|
|
42
|
+
return `${body}.${sig}`;
|
|
43
|
+
},
|
|
44
|
+
async verify(token, expectedOperation) {
|
|
45
|
+
if (typeof token !== 'string' || !token.includes('.')) {
|
|
46
|
+
throw meetingValidationError('continuation_invalid', 'continuation 无效');
|
|
47
|
+
}
|
|
48
|
+
const [body, provided] = token.split('.');
|
|
49
|
+
const expected = signature(body, await loadKey(ctx));
|
|
50
|
+
const valid = provided.length === expected.length
|
|
51
|
+
&& timingSafeEqual(Buffer.from(provided), Buffer.from(expected));
|
|
52
|
+
if (!valid)
|
|
53
|
+
throw meetingValidationError('continuation_invalid', 'continuation 签名校验失败');
|
|
54
|
+
let value;
|
|
55
|
+
try {
|
|
56
|
+
value = JSON.parse(Buffer.from(body, 'base64url').toString('utf8'));
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
throw meetingValidationError('continuation_invalid', 'continuation 内容无法解析');
|
|
60
|
+
}
|
|
61
|
+
if (value.operation !== expectedOperation) {
|
|
62
|
+
throw meetingValidationError('continuation_mismatch', 'continuation 不属于当前操作');
|
|
63
|
+
}
|
|
64
|
+
if (!Number.isSafeInteger(value.expiresAt) || value.expiresAt < Date.now()) {
|
|
65
|
+
throw meetingValidationError('continuation_expired', 'continuation 已过期');
|
|
66
|
+
}
|
|
67
|
+
return value;
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { CliError, ExitCode } from '../../core/errors.js';
|
|
2
|
+
export class MeetingCliError extends CliError {
|
|
3
|
+
type;
|
|
4
|
+
subtype;
|
|
5
|
+
code;
|
|
6
|
+
retryable;
|
|
7
|
+
stage;
|
|
8
|
+
details;
|
|
9
|
+
partialData;
|
|
10
|
+
constructor(type, subtype, message, options = {}) {
|
|
11
|
+
super(message, options.exitCode ?? ExitCode.InternalError);
|
|
12
|
+
this.name = 'MeetingCliError';
|
|
13
|
+
this.type = type;
|
|
14
|
+
this.subtype = subtype;
|
|
15
|
+
this.code = options.code;
|
|
16
|
+
this.retryable = options.retryable ?? false;
|
|
17
|
+
this.stage = options.stage;
|
|
18
|
+
this.details = options.details;
|
|
19
|
+
this.partialData = options.partialData;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function meetingValidationError(subtype, message, details) {
|
|
23
|
+
return new MeetingCliError('validation', subtype, message, {
|
|
24
|
+
details,
|
|
25
|
+
exitCode: ExitCode.UsageError,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export function meetingAuthError(subtype, message, details) {
|
|
29
|
+
return new MeetingCliError('authentication', subtype, message, {
|
|
30
|
+
details,
|
|
31
|
+
exitCode: ExitCode.AuthError,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export function meetingNetworkError(subtype, message, options = {}) {
|
|
35
|
+
return new MeetingCliError('network', subtype, message, {
|
|
36
|
+
...options,
|
|
37
|
+
retryable: options.retryable ?? true,
|
|
38
|
+
exitCode: ExitCode.NetworkError,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
export function meetingConfirmationError(action, details) {
|
|
42
|
+
return new MeetingCliError('confirmation', 'required', '该操作需要明确确认', {
|
|
43
|
+
details: { action, ...details },
|
|
44
|
+
exitCode: ExitCode.ConfirmationRequired,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export function meetingPartialError(message, partialData, details) {
|
|
48
|
+
return new MeetingCliError('partial', 'write_uncertain', message, {
|
|
49
|
+
details,
|
|
50
|
+
partialData,
|
|
51
|
+
exitCode: ExitCode.Partial,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 冲突命中(cansub=false 禁止提交)或冲突检测接口失败:一律拒绝建会。
|
|
56
|
+
* 与业务规范一致:禁止提交 → 直接拒绝;仅提醒 → 由调用方看 warnings。
|
|
57
|
+
*/
|
|
58
|
+
export function meetingConflictError(subtype, message, details) {
|
|
59
|
+
return new MeetingCliError('policy', subtype, message, {
|
|
60
|
+
details,
|
|
61
|
+
exitCode: ExitCode.ConfirmationRequired,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { requireE10Session } from '../../internal/e10/context.js';
|
|
2
|
+
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
3
|
+
import { E10ApiError, createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
4
|
+
import { MeetingCliError, meetingAuthError, meetingNetworkError, meetingValidationError } from './errors.js';
|
|
5
|
+
function inferProfile(ctx) {
|
|
6
|
+
const options = ctx.getGlobalOptions();
|
|
7
|
+
return options.profile || getActiveProfile();
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* E10 标准版(Java REST)与 EB 版(eBuilder formdata)响应契约:
|
|
11
|
+
* `code=200` 成功;或 `status=true` 成功(EB formdata 与部分标准接口)。
|
|
12
|
+
*/
|
|
13
|
+
export function isBusinessSuccess(value) {
|
|
14
|
+
if (!value || typeof value !== 'object')
|
|
15
|
+
return false;
|
|
16
|
+
if (typeof value.status === 'boolean')
|
|
17
|
+
return value.status;
|
|
18
|
+
if (value.code !== undefined && value.code !== null)
|
|
19
|
+
return Number(value.code) === 200;
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
export function businessMessage(value) {
|
|
23
|
+
if (!value || typeof value !== 'object')
|
|
24
|
+
return '泛微接口返回业务失败';
|
|
25
|
+
// actionMsg.message 是服务端权限/业务提示的常见载体(如"您没有变更权限!"),
|
|
26
|
+
// 必须优先保留原文,供 Agent 原样告知用户。
|
|
27
|
+
const candidates = [
|
|
28
|
+
value.msg,
|
|
29
|
+
value.message,
|
|
30
|
+
value.errMsg,
|
|
31
|
+
value.actionMsg?.message,
|
|
32
|
+
value.actionMsg?.msg,
|
|
33
|
+
value.data?.message,
|
|
34
|
+
value.data?.msg,
|
|
35
|
+
];
|
|
36
|
+
for (const item of candidates) {
|
|
37
|
+
if (typeof item === 'string' && item.trim())
|
|
38
|
+
return item;
|
|
39
|
+
}
|
|
40
|
+
return '泛微接口返回业务失败';
|
|
41
|
+
}
|
|
42
|
+
function businessCode(value) {
|
|
43
|
+
if (!value || typeof value !== 'object')
|
|
44
|
+
return undefined;
|
|
45
|
+
const code = value.code ?? value.status;
|
|
46
|
+
if (typeof code === 'string' || typeof code === 'number')
|
|
47
|
+
return code;
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
function assertPath(requestPath) {
|
|
51
|
+
if (typeof requestPath !== 'string' || !requestPath.startsWith('/') || requestPath.startsWith('//')) {
|
|
52
|
+
throw meetingValidationError('path_invalid', '请求路径必须是相对绝对路径');
|
|
53
|
+
}
|
|
54
|
+
if (/^https?:/i.test(requestPath) || /[\r\n]/.test(requestPath) || requestPath.includes('/../')) {
|
|
55
|
+
throw meetingValidationError('path_invalid', '请求路径不允许跨域或路径逃逸');
|
|
56
|
+
}
|
|
57
|
+
if (!requestPath.startsWith('/api/')) {
|
|
58
|
+
throw meetingValidationError('path_not_allowed', '会议模块只能调用 /api/ 路径');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function omitEmptyQueryValues(query) {
|
|
62
|
+
if (!query)
|
|
63
|
+
return undefined;
|
|
64
|
+
return Object.fromEntries(Object.entries(query).filter(([, value]) => value !== '' && value !== undefined));
|
|
65
|
+
}
|
|
66
|
+
function mapRuntimeNetworkError(error) {
|
|
67
|
+
if (error instanceof E10ApiError && error.type === 'network') {
|
|
68
|
+
throw meetingNetworkError(error.subtype, error.message, {
|
|
69
|
+
retryable: error.retryable,
|
|
70
|
+
details: error.details,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
export function createMeetingHost(ctx, dependencies = {}) {
|
|
76
|
+
let e10Session = null;
|
|
77
|
+
let sessionContext = null;
|
|
78
|
+
const requireSession = dependencies.requireSession || requireE10Session;
|
|
79
|
+
async function ensureSession() {
|
|
80
|
+
if (!e10Session) {
|
|
81
|
+
e10Session = await requireSession(ctx);
|
|
82
|
+
sessionContext = {
|
|
83
|
+
baseUrl: e10Session.getBaseUrl(),
|
|
84
|
+
profile: inferProfile(ctx),
|
|
85
|
+
userId: e10Session.userId,
|
|
86
|
+
tenantKey: e10Session.tenantKey,
|
|
87
|
+
eteamsId: e10Session.eteamsId,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return e10Session;
|
|
91
|
+
}
|
|
92
|
+
async function getSession() {
|
|
93
|
+
await ensureSession();
|
|
94
|
+
return sessionContext;
|
|
95
|
+
}
|
|
96
|
+
async function runtime() {
|
|
97
|
+
return createE10RequestRuntime(ctx, await ensureSession(), {
|
|
98
|
+
interceptors: dependencies.interceptors,
|
|
99
|
+
fetch: dependencies.fetch,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
async function request(request) {
|
|
103
|
+
const { method, path, query, body, operation, headers: extraHeaders = {}, timeoutMs = 30_000 } = request;
|
|
104
|
+
assertPath(path);
|
|
105
|
+
// 标准版会议接口硬性约定(standalone skill 实测):不能带 workflow 专用头
|
|
106
|
+
// (Referer: /workflow/newflow 等),否则 400 系统错误;等价于 standalone
|
|
107
|
+
// 执行器的 --simple-header(仅 Content-Type + Cookie,由 runtime 托管)。
|
|
108
|
+
const resolvedMethod = method || (body === undefined ? 'GET' : 'POST');
|
|
109
|
+
let response;
|
|
110
|
+
try {
|
|
111
|
+
response = await (await runtime()).requestJson({
|
|
112
|
+
module: 'meeting',
|
|
113
|
+
operation,
|
|
114
|
+
method: resolvedMethod,
|
|
115
|
+
path,
|
|
116
|
+
query: omitEmptyQueryValues(query),
|
|
117
|
+
body,
|
|
118
|
+
headers: { ...extraHeaders },
|
|
119
|
+
// 会议接口存在裸数字长 ID(如 meetingExtend.mtId / creater),超 2^53 会被
|
|
120
|
+
// JSON.parse 舍入;开启大整数保护后按字符串保留,保证 ID 回查不失真。
|
|
121
|
+
bigIntStrings: true,
|
|
122
|
+
timeoutMs,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
mapRuntimeNetworkError(error);
|
|
127
|
+
}
|
|
128
|
+
if (response.status === 401 || response.status === 302) {
|
|
129
|
+
throw meetingAuthError('session_expired', 'E10 登录态已失效,请先向用户确认 E10 登录域名,再运行 weaver-work-cli auth login --base-url <域名> 完成登录', { httpStatus: response.status });
|
|
130
|
+
}
|
|
131
|
+
if (response.parseError) {
|
|
132
|
+
if (response.status < 200 || response.status >= 300) {
|
|
133
|
+
throw new MeetingCliError('api', 'http_error', `泛微接口 HTTP ${response.status}`, {
|
|
134
|
+
code: response.status,
|
|
135
|
+
details: { status: response.status },
|
|
136
|
+
exitCode: 1,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
throw meetingNetworkError('protocol', `接口返回不是合法 JSON(HTTP ${response.status})`, { retryable: false });
|
|
140
|
+
}
|
|
141
|
+
if (response.status < 200 || response.status >= 300) {
|
|
142
|
+
throw new MeetingCliError('api', 'http_error', `泛微接口 HTTP ${response.status}`, {
|
|
143
|
+
code: response.status,
|
|
144
|
+
details: { status: response.status, message: businessMessage(response.value) },
|
|
145
|
+
exitCode: 1,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
if (!isBusinessSuccess(response.value)) {
|
|
149
|
+
const code = businessCode(response.value);
|
|
150
|
+
const message = businessMessage(response.value);
|
|
151
|
+
if (code === 403) {
|
|
152
|
+
throw new MeetingCliError('api', 'permission_denied', message || '当前租户未开放该会议接口权限,请联系管理员', {
|
|
153
|
+
code,
|
|
154
|
+
details: { code, message },
|
|
155
|
+
exitCode: 1,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
throw new MeetingCliError('api', 'business_error', message, {
|
|
159
|
+
code,
|
|
160
|
+
details: { code, message },
|
|
161
|
+
exitCode: 1,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return response.value;
|
|
165
|
+
}
|
|
166
|
+
return { request, getSession };
|
|
167
|
+
}
|