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,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 { esbValidationError } 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, 'esb-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 createEsbContinuationSigner(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 esbValidationError('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 esbValidationError('continuation_invalid', 'continuation 签名校验失败');
|
|
54
|
+
let value;
|
|
55
|
+
try {
|
|
56
|
+
value = JSON.parse(Buffer.from(body, 'base64url').toString('utf8'));
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
throw esbValidationError('continuation_invalid', 'continuation 内容无法解析');
|
|
60
|
+
}
|
|
61
|
+
if (value.operation !== expectedOperation) {
|
|
62
|
+
throw esbValidationError('continuation_mismatch', 'continuation 不属于当前操作');
|
|
63
|
+
}
|
|
64
|
+
if (!Number.isSafeInteger(value.expiresAt) || value.expiresAt < Date.now()) {
|
|
65
|
+
throw esbValidationError('continuation_expired', 'continuation 已过期');
|
|
66
|
+
}
|
|
67
|
+
return value;
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { CliError, ExitCode } from '../../core/errors.js';
|
|
2
|
+
export class EsbCliError extends CliError {
|
|
3
|
+
type;
|
|
4
|
+
subtype;
|
|
5
|
+
code;
|
|
6
|
+
retryable;
|
|
7
|
+
stage;
|
|
8
|
+
details;
|
|
9
|
+
constructor(type, subtype, message, options = {}) {
|
|
10
|
+
super(message, options.exitCode ?? ExitCode.InternalError);
|
|
11
|
+
this.name = 'EsbCliError';
|
|
12
|
+
this.type = type;
|
|
13
|
+
this.subtype = subtype;
|
|
14
|
+
this.code = options.code;
|
|
15
|
+
this.retryable = options.retryable ?? false;
|
|
16
|
+
this.stage = options.stage;
|
|
17
|
+
this.details = options.details;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function esbValidationError(subtype, message, details) {
|
|
21
|
+
return new EsbCliError('validation', subtype, message, {
|
|
22
|
+
details,
|
|
23
|
+
exitCode: ExitCode.UsageError,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export function esbAuthError(subtype, message, details) {
|
|
27
|
+
return new EsbCliError('authentication', subtype, message, {
|
|
28
|
+
details,
|
|
29
|
+
exitCode: ExitCode.AuthError,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export function esbNetworkError(subtype, message, options = {}) {
|
|
33
|
+
return new EsbCliError('network', subtype, message, {
|
|
34
|
+
...options,
|
|
35
|
+
retryable: options.retryable ?? true,
|
|
36
|
+
exitCode: ExitCode.NetworkError,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/** 服务端返回的业务失败(HTTP 已成功、resultCode 非 200)。 */
|
|
40
|
+
export function esbApiError(subtype, message, options = {}) {
|
|
41
|
+
return new EsbCliError('api', subtype, message, {
|
|
42
|
+
...options,
|
|
43
|
+
retryable: options.retryable ?? false,
|
|
44
|
+
exitCode: ExitCode.GeneralError,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 触发动作流是写操作:请求已发出但结果未知(网络中断、超时、连接被中断)时,
|
|
49
|
+
* 无法判断动作流是否已经执行,必须标记为结果不确定并禁止自动重试。
|
|
50
|
+
*/
|
|
51
|
+
export function esbWriteUncertain(message, details) {
|
|
52
|
+
return new EsbCliError('partial', 'write_uncertain', message, {
|
|
53
|
+
retryable: false,
|
|
54
|
+
exitCode: ExitCode.Partial,
|
|
55
|
+
details,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/** 权限/租户类业务失败,单独给出 subtype 便于 Agent 直接给出处置建议。 */
|
|
59
|
+
export function esbPermissionError(subtype, message, options = {}) {
|
|
60
|
+
return new EsbCliError('api', subtype, message, {
|
|
61
|
+
...options,
|
|
62
|
+
retryable: false,
|
|
63
|
+
exitCode: ExitCode.GeneralError,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
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 { EsbCliError, esbApiError, esbAuthError, esbNetworkError, esbPermissionError, esbValidationError, esbWriteUncertain, } from './errors.js';
|
|
5
|
+
/** 源接口文档给出的去域名路径;域名与认证由 E10 会话层托管。 */
|
|
6
|
+
export const ESB_PATHS = {
|
|
7
|
+
inputFormat: '/api/bs/esb/setting/customData/application/copyCustomData',
|
|
8
|
+
trigger: '/api/esb/server/event/triggerActionFlow',
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* triggerActionFlow 的 resultCode 语义,逐条取自源接口文档「错误码对照表」。
|
|
12
|
+
* 未列出的码回落到 business_error,并把服务端 resultMsg 原样带出。
|
|
13
|
+
*/
|
|
14
|
+
const TRIGGER_RESULT_CODES = {
|
|
15
|
+
100: { subtype: 'parameter_invalid' },
|
|
16
|
+
101: { subtype: 'batch_key_invalid' },
|
|
17
|
+
201: { subtype: 'flow_not_bound' },
|
|
18
|
+
202: { subtype: 'execute_failed' },
|
|
19
|
+
203: { subtype: 'execute_timeout', retryable: true },
|
|
20
|
+
204: { subtype: 'permission_denied', permission: true },
|
|
21
|
+
400: { subtype: 'license_required' },
|
|
22
|
+
401: { subtype: 'tenant_permission_denied', permission: true },
|
|
23
|
+
402: { subtype: 'flow_disabled' },
|
|
24
|
+
403: { subtype: 'tenant_missing', permission: true },
|
|
25
|
+
404: { subtype: 'flow_not_found' },
|
|
26
|
+
500: { subtype: 'execute_failed' },
|
|
27
|
+
501: { subtype: 'result_fetch_failed', retryable: true },
|
|
28
|
+
502: { subtype: 'result_fetch_timeout', retryable: true },
|
|
29
|
+
505: { subtype: 'flow_running', retryable: true },
|
|
30
|
+
506: { subtype: 'execution_loop_conflict' },
|
|
31
|
+
507: { subtype: 'throttled', retryable: true },
|
|
32
|
+
508: { subtype: 'throttled', retryable: true },
|
|
33
|
+
509: { subtype: 'execution_terminated' },
|
|
34
|
+
510: { subtype: 'memory_exceeded' },
|
|
35
|
+
511: { subtype: 'throttled', retryable: true },
|
|
36
|
+
512: { subtype: 'flow_in_recycle_bin' },
|
|
37
|
+
};
|
|
38
|
+
/** 「目标动作流本身不可用」的错误:prepare 阶段回查命中时必须阻断。 */
|
|
39
|
+
export const TARGET_FATAL_SUBTYPES = new Set([
|
|
40
|
+
'flow_not_found',
|
|
41
|
+
'flow_not_bound',
|
|
42
|
+
'flow_disabled',
|
|
43
|
+
'flow_in_recycle_bin',
|
|
44
|
+
'parameter_invalid',
|
|
45
|
+
]);
|
|
46
|
+
export function isEsbFlowUnavailable(error) {
|
|
47
|
+
return error instanceof EsbCliError && TARGET_FATAL_SUBTYPES.has(error.subtype);
|
|
48
|
+
}
|
|
49
|
+
export function triggerResultCode(value) {
|
|
50
|
+
if (!value || typeof value !== 'object')
|
|
51
|
+
return undefined;
|
|
52
|
+
const raw = value.resultCode;
|
|
53
|
+
if (raw === undefined || raw === null || raw === '')
|
|
54
|
+
return undefined;
|
|
55
|
+
const numeric = Number(raw);
|
|
56
|
+
return Number.isFinite(numeric) ? numeric : undefined;
|
|
57
|
+
}
|
|
58
|
+
function assertPath(requestPath) {
|
|
59
|
+
if (typeof requestPath !== 'string' || !requestPath.startsWith('/') || requestPath.startsWith('//')) {
|
|
60
|
+
throw esbValidationError('path_invalid', '请求路径必须是相对绝对路径');
|
|
61
|
+
}
|
|
62
|
+
if (/^https?:/i.test(requestPath) || /[\r\n]/.test(requestPath) || requestPath.includes('/../')) {
|
|
63
|
+
throw esbValidationError('path_invalid', '请求路径不允许跨域或路径逃逸');
|
|
64
|
+
}
|
|
65
|
+
if (!requestPath.startsWith('/api/')) {
|
|
66
|
+
throw esbValidationError('path_not_allowed', 'ESB 动作流只能调用 /api/ 路径');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function mapRuntimeNetworkError(error) {
|
|
70
|
+
if (error instanceof E10ApiError && error.type === 'network') {
|
|
71
|
+
throw esbNetworkError(error.subtype, error.message, {
|
|
72
|
+
retryable: error.retryable,
|
|
73
|
+
details: error.details,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
export function createEsbHost(ctx, dependencies = {}) {
|
|
79
|
+
let e10Session = null;
|
|
80
|
+
let sessionContext = null;
|
|
81
|
+
const requireSession = dependencies.requireSession || requireE10Session;
|
|
82
|
+
async function ensureSession() {
|
|
83
|
+
if (!e10Session) {
|
|
84
|
+
e10Session = await requireSession(ctx);
|
|
85
|
+
sessionContext = {
|
|
86
|
+
baseUrl: e10Session.getBaseUrl(),
|
|
87
|
+
profile: ctx.getGlobalOptions().profile || getActiveProfile(),
|
|
88
|
+
userId: e10Session.userId,
|
|
89
|
+
tenantKey: e10Session.tenantKey,
|
|
90
|
+
eteamsId: e10Session.eteamsId,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
return e10Session;
|
|
94
|
+
}
|
|
95
|
+
async function getSession() {
|
|
96
|
+
await ensureSession();
|
|
97
|
+
return sessionContext;
|
|
98
|
+
}
|
|
99
|
+
async function runtime() {
|
|
100
|
+
return createE10RequestRuntime(ctx, await ensureSession(), { fetch: dependencies.fetch });
|
|
101
|
+
}
|
|
102
|
+
async function send(operation, path, body) {
|
|
103
|
+
assertPath(path);
|
|
104
|
+
let response;
|
|
105
|
+
try {
|
|
106
|
+
response = await (await runtime()).requestJson({
|
|
107
|
+
module: 'esb',
|
|
108
|
+
operation,
|
|
109
|
+
method: 'POST',
|
|
110
|
+
path,
|
|
111
|
+
body,
|
|
112
|
+
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
|
113
|
+
timeoutMs: 60_000,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
mapRuntimeNetworkError(error);
|
|
118
|
+
}
|
|
119
|
+
if (response.status === 401 || response.status === 302) {
|
|
120
|
+
throw esbAuthError('session_expired', 'E10 登录态已失效,请先确认 E10 登录域名,再运行 weaver-work-cli auth login --base-url <域名> 完成登录', { httpStatus: response.status });
|
|
121
|
+
}
|
|
122
|
+
if (response.parseError) {
|
|
123
|
+
if (response.status < 200 || response.status >= 300) {
|
|
124
|
+
throw esbApiError('http_error', `泛微接口 HTTP ${response.status}`, {
|
|
125
|
+
code: response.status,
|
|
126
|
+
details: { status: response.status },
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
throw esbNetworkError('protocol', `接口返回不是合法 JSON(HTTP ${response.status})`, { retryable: false });
|
|
130
|
+
}
|
|
131
|
+
if (response.status < 200 || response.status >= 300) {
|
|
132
|
+
throw esbApiError('http_error', `泛微接口 HTTP ${response.status}`, {
|
|
133
|
+
code: response.status,
|
|
134
|
+
details: { status: response.status },
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
return response.value;
|
|
138
|
+
}
|
|
139
|
+
function assertTriggerSuccess(value, operation) {
|
|
140
|
+
const code = triggerResultCode(value);
|
|
141
|
+
const record = (value && typeof value === 'object' ? value : {});
|
|
142
|
+
const serverMessage = typeof record.resultMsg === 'string' ? record.resultMsg.trim() : '';
|
|
143
|
+
if (code === undefined) {
|
|
144
|
+
throw esbNetworkError('protocol', '触发接口未返回 resultCode,无法判定执行结果', {
|
|
145
|
+
retryable: false,
|
|
146
|
+
details: { operation },
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
if (code === 200)
|
|
150
|
+
return value;
|
|
151
|
+
const rule = TRIGGER_RESULT_CODES[code] || { subtype: 'business_error' };
|
|
152
|
+
const message = serverMessage || `动作流执行失败(resultCode=${code})`;
|
|
153
|
+
const options = {
|
|
154
|
+
code,
|
|
155
|
+
retryable: rule.retryable ?? false,
|
|
156
|
+
details: { operation, resultCode: code, resultMsg: serverMessage },
|
|
157
|
+
};
|
|
158
|
+
if (rule.permission)
|
|
159
|
+
throw esbPermissionError(rule.subtype, message, options);
|
|
160
|
+
throw esbApiError(rule.subtype, message, options);
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
async inputFormat(applicationId) {
|
|
164
|
+
const value = await send('esb.input-format', ESB_PATHS.inputFormat, { applicationId });
|
|
165
|
+
const code = triggerResultCode(value);
|
|
166
|
+
// 该接口正常返回模板对象(无 resultCode 信封);若平台改为统一错误信封则按错误码处理。
|
|
167
|
+
if (code !== undefined && code !== 200)
|
|
168
|
+
assertTriggerSuccess(value, 'esb.input-format');
|
|
169
|
+
return value;
|
|
170
|
+
},
|
|
171
|
+
async trigger(payload) {
|
|
172
|
+
let value;
|
|
173
|
+
try {
|
|
174
|
+
value = await send('esb.trigger.apply', ESB_PATHS.trigger, payload);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
// 写操作已发出但结果未知:不得判定为「未执行」,也不得自动重试。
|
|
178
|
+
if (error instanceof EsbCliError && error.type === 'network') {
|
|
179
|
+
throw esbWriteUncertain(`触发请求已发出但未取得结果(${error.subtype}):无法确认动作流是否已执行,请先在 ESB 中心查看动作流运行日志后再决定是否重试`, { cause: error.message });
|
|
180
|
+
}
|
|
181
|
+
throw error;
|
|
182
|
+
}
|
|
183
|
+
return assertTriggerSuccess(value, 'esb.trigger.apply');
|
|
184
|
+
},
|
|
185
|
+
getSession,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { ExitCode, isCliError, toErrorEnvelope } from '../../core/errors.js';
|
|
3
|
+
import { createEsbContinuationSigner } from './continuation.js';
|
|
4
|
+
import { createEsbHost } from './host.js';
|
|
5
|
+
import { esbManifest } from './manifest.js';
|
|
6
|
+
import { executeEsbOperation } from './operations.js';
|
|
7
|
+
import { esbValidationError } from './errors.js';
|
|
8
|
+
function asOptions(value) {
|
|
9
|
+
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
10
|
+
}
|
|
11
|
+
async function readStdin() {
|
|
12
|
+
const chunks = [];
|
|
13
|
+
for await (const chunk of process.stdin) {
|
|
14
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
15
|
+
}
|
|
16
|
+
return Buffer.concat(chunks).toString('utf8');
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Windows PowerShell 的管道与 Set-Content -Encoding utf8 会在内容前写入 UTF-8 BOM,
|
|
20
|
+
* 且可能重复写入多次;JSON.parse 不接受前导 BOM,必须先剥离。
|
|
21
|
+
*/
|
|
22
|
+
function stripBom(value) {
|
|
23
|
+
return value.replace(/^\uFEFF+/, '');
|
|
24
|
+
}
|
|
25
|
+
export async function inputFrom(options, extra = {}) {
|
|
26
|
+
const opts = asOptions(options);
|
|
27
|
+
let input = {};
|
|
28
|
+
if (opts.input && opts.inputJson) {
|
|
29
|
+
throw esbValidationError('input_conflict', '不能同时传 --input 和 --input-json');
|
|
30
|
+
}
|
|
31
|
+
if (opts.inputJson) {
|
|
32
|
+
input = parseJsonInput(String(opts.inputJson), '--input-json');
|
|
33
|
+
}
|
|
34
|
+
if (opts.input) {
|
|
35
|
+
let raw;
|
|
36
|
+
try {
|
|
37
|
+
raw = stripBom(opts.input === '-' ? await readStdin() : await readFile(String(opts.input), 'utf8'));
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
throw esbValidationError('input_unreadable', `无法读取 --input:${String(opts.input)}`);
|
|
41
|
+
}
|
|
42
|
+
input = parseJsonInput(raw, '--input');
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
...input,
|
|
46
|
+
...Object.fromEntries(Object.entries(extra).filter(([, value]) => value !== undefined && value !== '')),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function parseJsonInput(raw, label) {
|
|
50
|
+
try {
|
|
51
|
+
const parsed = JSON.parse(stripBom(raw));
|
|
52
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
53
|
+
throw new Error('input must be an object');
|
|
54
|
+
}
|
|
55
|
+
return parsed;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
throw esbValidationError('input_invalid', `${label} 不是合法 JSON 对象`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export function successEnvelope(operation, result) {
|
|
62
|
+
return {
|
|
63
|
+
schemaVersion: 1,
|
|
64
|
+
ok: true,
|
|
65
|
+
operation,
|
|
66
|
+
data: result.data === undefined ? null : result.data,
|
|
67
|
+
...(result.meta ? { meta: result.meta } : {}),
|
|
68
|
+
warnings: result.warnings ?? [],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function failureEnvelope(error) {
|
|
72
|
+
return {
|
|
73
|
+
schemaVersion: 1,
|
|
74
|
+
ok: false,
|
|
75
|
+
error: toErrorEnvelope(error),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async function executeAndPrint(ctx, operation, input) {
|
|
79
|
+
try {
|
|
80
|
+
const result = await executeEsbOperation(operation, input, {
|
|
81
|
+
ctx,
|
|
82
|
+
host: createEsbHost(ctx),
|
|
83
|
+
continuation: createEsbContinuationSigner(ctx),
|
|
84
|
+
});
|
|
85
|
+
ctx.output.write(successEnvelope(operation, result), { json: true });
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
console.error(JSON.stringify(failureEnvelope(error), null, 2));
|
|
89
|
+
process.exitCode = isCliError(error) ? error.exitCode : ExitCode.GeneralError;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export const esbShortcut = {
|
|
93
|
+
name: 'esb',
|
|
94
|
+
description: '泛微E10 ESB 中心自定义触发动作流 CLI',
|
|
95
|
+
category: 'shortcut',
|
|
96
|
+
register({ program, action }) {
|
|
97
|
+
const esb = program.command('esb').description('泛微E10 ESB 中心自定义触发动作流(取入参模板 / 确认后触发)');
|
|
98
|
+
esb.command('schema')
|
|
99
|
+
.description('Print esb operation manifest for agents')
|
|
100
|
+
.action(action((ctx) => {
|
|
101
|
+
ctx.output.write(esbManifest, { json: true });
|
|
102
|
+
}));
|
|
103
|
+
esb.command('run')
|
|
104
|
+
.description('Run an esb operation with JSON input')
|
|
105
|
+
.argument('<operation>', 'operation name, e.g. esb.trigger.prepare')
|
|
106
|
+
.option('--input <path>', 'JSON input file, or - for stdin')
|
|
107
|
+
.option('--input-json <json>', 'inline JSON input object')
|
|
108
|
+
.action(action(async (ctx, operation, options) => {
|
|
109
|
+
await executeAndPrint(ctx, String(operation), await inputFrom(options));
|
|
110
|
+
}));
|
|
111
|
+
},
|
|
112
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/** 动作流 ID 在源资料示例中为长整型数字串,一律按字符串传递,避免精度丢失。 */
|
|
2
|
+
const flowId = { type: 'string', pattern: '^\\d+$', minLength: 1, maxLength: 32 };
|
|
3
|
+
/**
|
|
4
|
+
* customParams 及 mainTable 的子字段名由目标动作流定义(主表字段、detail1/detail2 明细表),
|
|
5
|
+
* 无法在 schema 中穷举,因此这两层不设 additionalProperties: false;顶层输入仍然严格禁止额外字段。
|
|
6
|
+
*/
|
|
7
|
+
const customParams = {
|
|
8
|
+
type: 'object',
|
|
9
|
+
minProperties: 1,
|
|
10
|
+
properties: {
|
|
11
|
+
mainTable: { type: 'object' },
|
|
12
|
+
},
|
|
13
|
+
required: ['mainTable'],
|
|
14
|
+
description: '动作流自定义输入参数,须包含 mainTable;主表与明细表字段以 esb.input-format 返回的模板为准',
|
|
15
|
+
};
|
|
16
|
+
const triggerProperties = {
|
|
17
|
+
esbFlowId: { ...flowId, description: '普通触发:动作流 ID(esbFlowId)' },
|
|
18
|
+
uniqueIndent: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
minLength: 1,
|
|
21
|
+
maxLength: 128,
|
|
22
|
+
description: '唯一值触发:动作流唯一值,取值为 esb_application.primary_key(需在 esb_setting 库查得后传入)',
|
|
23
|
+
},
|
|
24
|
+
employeeId: { type: 'string', minLength: 1, maxLength: 64, description: '触发人员 ID(必填)' },
|
|
25
|
+
customParams,
|
|
26
|
+
moduleSource: { type: 'string', minLength: 1, maxLength: 64, description: '触发来源标识,默认不要传;仅二开场景传 ecode' },
|
|
27
|
+
};
|
|
28
|
+
export const esbOperations = [
|
|
29
|
+
{
|
|
30
|
+
name: 'esb.input-format',
|
|
31
|
+
summary: '按 applicationId 获取自定义触发动作流的入参模板(只读,无副作用)',
|
|
32
|
+
risk: 'read',
|
|
33
|
+
inputSchema: {
|
|
34
|
+
type: 'object',
|
|
35
|
+
additionalProperties: false,
|
|
36
|
+
properties: {
|
|
37
|
+
applicationId: { ...flowId, description: '动作流 ID(与触发接口的 esbFlowId 指向同一动作流)' },
|
|
38
|
+
},
|
|
39
|
+
required: ['applicationId'],
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'esb.trigger.prepare',
|
|
44
|
+
summary: '触发前的只读回查与请求体组装,签发 apply 所需的 continuation(不产生业务副作用)',
|
|
45
|
+
risk: 'read-before-write',
|
|
46
|
+
inputSchema: {
|
|
47
|
+
type: 'object',
|
|
48
|
+
additionalProperties: false,
|
|
49
|
+
properties: triggerProperties,
|
|
50
|
+
required: ['employeeId', 'customParams'],
|
|
51
|
+
oneOf: [{ required: ['esbFlowId'] }, { required: ['uniqueIndent'] }],
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'esb.trigger.apply',
|
|
56
|
+
summary: '按 continuation 执行动作流触发(高风险写操作,可能产生业务副作用)',
|
|
57
|
+
risk: 'high-risk-write',
|
|
58
|
+
inputSchema: {
|
|
59
|
+
type: 'object',
|
|
60
|
+
additionalProperties: false,
|
|
61
|
+
properties: {
|
|
62
|
+
continuation: { type: 'string', minLength: 1, description: 'esb.trigger.prepare 返回的 continuation,有效期 10 分钟' },
|
|
63
|
+
confirm: { const: true, description: '必须显式为 true,表示用户已确认执行该动作流' },
|
|
64
|
+
},
|
|
65
|
+
required: ['continuation', 'confirm'],
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
export const esbManifest = {
|
|
70
|
+
schemaVersion: 1,
|
|
71
|
+
name: 'esb',
|
|
72
|
+
title: '泛微E10 ESB动作流执行',
|
|
73
|
+
version: '0.1.0',
|
|
74
|
+
host: 'e10-esb',
|
|
75
|
+
status: 'builtin',
|
|
76
|
+
sourceSkill: 'weaver-e10-customesb-execute',
|
|
77
|
+
operations: esbOperations,
|
|
78
|
+
withheldOperations: [
|
|
79
|
+
{
|
|
80
|
+
name: 'esb.actionflow.resolve',
|
|
81
|
+
reason: '按动作流名称解析 esbFlowId 需要 ESB 中心动作流列表查询接口,源资料未给出该接口的路径、请求字段与返回结构,无法安全实现;请用户直接提供动作流 ID。',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'esb.unique-indent.resolve',
|
|
85
|
+
reason: '唯一值触发所需的 primary_key 需直接查询 esb_setting 库(SELECT primary_key FROM esb_application WHERE id = ?),CLI 没有数据库通道,只能由调用方查得后通过 uniqueIndent 传入。',
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
export function hasEsbOperation(operation) {
|
|
90
|
+
return esbOperations.some((item) => item.name === operation);
|
|
91
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { esbSuccess } from './types.js';
|
|
2
|
+
import { collectPlaceholders, flowIdString } from './shared.js';
|
|
3
|
+
function normalizeTemplate(raw, applicationId) {
|
|
4
|
+
const record = raw && typeof raw === 'object' && !Array.isArray(raw) ? raw : {};
|
|
5
|
+
const customParams = record.customParams ?? null;
|
|
6
|
+
const esbFlowId = record.esbFlowId === undefined || record.esbFlowId === null
|
|
7
|
+
? applicationId
|
|
8
|
+
: String(record.esbFlowId);
|
|
9
|
+
const moduleSource = typeof record.moduleSource === 'string' && record.moduleSource.trim()
|
|
10
|
+
? record.moduleSource.trim()
|
|
11
|
+
: 'AISKILL';
|
|
12
|
+
const optionalFields = collectPlaceholders(customParams);
|
|
13
|
+
const warnings = [];
|
|
14
|
+
if (customParams === null) {
|
|
15
|
+
warnings.push('接口未返回 customParams:请确认该动作流是否配置了自定义入参模板,未配置时按目标动作流要求直接组装 mainTable');
|
|
16
|
+
}
|
|
17
|
+
if (optionalFields.length > 0) {
|
|
18
|
+
warnings.push(`模板含 ${optionalFields.length} 个 #可选 占位字段,触发时替换为真实业务值或删除不需要的字段`);
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
template: { applicationId, esbFlowId, moduleSource, customParams, optionalFields },
|
|
22
|
+
warnings,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export const esbInputFormatHandlers = {
|
|
26
|
+
'esb.input-format': async (input, { host }) => {
|
|
27
|
+
const applicationId = flowIdString(input.applicationId, 'applicationId');
|
|
28
|
+
const { template, warnings } = normalizeTemplate(await host.inputFormat(applicationId), applicationId);
|
|
29
|
+
return esbSuccess('esb.input-format', template, { status: 'COMPLETE' }, warnings);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { esbManifest } from '../manifest.js';
|
|
2
|
+
import { esbValidationError } from '../errors.js';
|
|
3
|
+
import { esbInputFormatHandlers } from './input-format.js';
|
|
4
|
+
import { esbTriggerHandlers } from './trigger.js';
|
|
5
|
+
function mergeHandlers(maps) {
|
|
6
|
+
const merged = {};
|
|
7
|
+
for (const map of maps) {
|
|
8
|
+
for (const [name, handler] of Object.entries(map)) {
|
|
9
|
+
if (merged[name])
|
|
10
|
+
throw new Error(`duplicate esb operation handler: ${name}`);
|
|
11
|
+
merged[name] = handler;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return merged;
|
|
15
|
+
}
|
|
16
|
+
const esbHandlers = mergeHandlers([esbInputFormatHandlers, esbTriggerHandlers]);
|
|
17
|
+
/**
|
|
18
|
+
* manifest 提供 WHAT(name/summary/risk/inputSchema),handler 提供 HOW。
|
|
19
|
+
* 两侧必须严格一一对应:任一侧多出条目都直接抛错,避免 schema 与实际能力漂移。
|
|
20
|
+
*/
|
|
21
|
+
function buildRegistry() {
|
|
22
|
+
const registry = new Map();
|
|
23
|
+
for (const contract of esbManifest.operations) {
|
|
24
|
+
const handler = esbHandlers[contract.name];
|
|
25
|
+
if (!handler)
|
|
26
|
+
throw new Error(`esb operation ${contract.name} has no handler`);
|
|
27
|
+
registry.set(contract.name, { ...contract, handler });
|
|
28
|
+
}
|
|
29
|
+
for (const name of Object.keys(esbHandlers)) {
|
|
30
|
+
if (!registry.has(name))
|
|
31
|
+
throw new Error(`esb handler ${name} is not declared in manifest`);
|
|
32
|
+
}
|
|
33
|
+
return registry;
|
|
34
|
+
}
|
|
35
|
+
const esbOperationRegistry = buildRegistry();
|
|
36
|
+
export function esbOperationDefinitions() {
|
|
37
|
+
return [...esbOperationRegistry.values()];
|
|
38
|
+
}
|
|
39
|
+
export function getEsbOperation(operation) {
|
|
40
|
+
const definition = esbOperationRegistry.get(operation);
|
|
41
|
+
if (!definition) {
|
|
42
|
+
throw esbValidationError('operation_unknown', `ESB 动作流不支持操作:${operation}`);
|
|
43
|
+
}
|
|
44
|
+
return definition;
|
|
45
|
+
}
|
|
46
|
+
export function hasEsbOperation(operation) {
|
|
47
|
+
return esbOperationRegistry.has(operation);
|
|
48
|
+
}
|