weaver-work-cli 0.1.8 → 0.1.20
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 +11 -11
- package/dist/cmd/action.js +76 -0
- package/dist/cmd/index.js +2 -0
- package/dist/cmd/refs/index.js +103 -0
- package/dist/cmd/register.js +31 -0
- package/dist/cmd/root.js +1 -0
- package/dist/cmd/setup/index.js +25 -5
- package/dist/cmd/skills/index.js +37 -5
- package/dist/core/connector.js +54 -0
- package/dist/core/context.js +2 -1
- package/dist/core/input.js +48 -0
- package/dist/core/output.js +298 -3
- package/dist/core/refs.js +432 -0
- package/dist/core/state.js +26 -0
- package/dist/internal/e10/auth/commands.js +2 -2
- package/dist/internal/e10/auth/session.js +14 -0
- package/dist/internal/e10/auth/xiaoe.js +116 -51
- package/dist/internal/e10/request-runtime.js +5 -0
- package/dist/internal/skills/install.js +148 -28
- package/dist/internal/skills/reader.js +12 -9
- package/dist/shortcuts/blog/continuation.js +74 -0
- package/dist/shortcuts/blog/errors.js +60 -0
- package/dist/shortcuts/blog/host.js +175 -0
- package/dist/shortcuts/blog/index.js +324 -0
- package/dist/shortcuts/blog/manifest.js +415 -0
- package/dist/shortcuts/blog/operations/comment.js +125 -0
- package/dist/shortcuts/blog/operations/comments.js +31 -0
- package/dist/shortcuts/blog/operations/edit.js +131 -0
- package/dist/shortcuts/blog/operations/export.js +46 -0
- package/dist/shortcuts/blog/operations/like.js +80 -0
- package/dist/shortcuts/blog/operations/publish.js +157 -0
- package/dist/shortcuts/blog/operations/query-user.js +58 -0
- package/dist/shortcuts/blog/operations/query.js +96 -0
- package/dist/shortcuts/blog/operations/registry.js +54 -0
- package/dist/shortcuts/blog/operations/remind.js +176 -0
- package/dist/shortcuts/blog/operations/shared.js +330 -0
- package/dist/shortcuts/blog/operations/types.js +16 -0
- package/dist/shortcuts/blog/operations.js +9 -0
- package/dist/shortcuts/caizhilian/continuation.js +70 -0
- package/dist/shortcuts/caizhilian/errors.js +53 -0
- package/dist/shortcuts/caizhilian/host.js +190 -0
- package/dist/shortcuts/caizhilian/index.js +186 -0
- package/dist/shortcuts/caizhilian/manifest.js +42 -0
- package/dist/shortcuts/caizhilian/operations/api.js +801 -0
- package/dist/shortcuts/caizhilian/operations/confirm.js +75 -0
- package/dist/shortcuts/caizhilian/operations/files.js +306 -0
- package/dist/shortcuts/caizhilian/operations/form.js +170 -0
- package/dist/shortcuts/caizhilian/operations/handlers/collab.js +611 -0
- package/dist/shortcuts/caizhilian/operations/handlers/document.js +890 -0
- package/dist/shortcuts/caizhilian/operations/handlers/file-collection.js +346 -0
- package/dist/shortcuts/caizhilian/operations/handlers/file-upload.js +192 -0
- package/dist/shortcuts/caizhilian/operations/handlers/fileops.js +570 -0
- package/dist/shortcuts/caizhilian/operations/handlers/folder.js +969 -0
- package/dist/shortcuts/caizhilian/operations/handlers/search.js +318 -0
- package/dist/shortcuts/caizhilian/operations/handlers/setting-attach.js +294 -0
- package/dist/shortcuts/caizhilian/operations/handlers/setting-backup.js +423 -0
- package/dist/shortcuts/caizhilian/operations/handlers/setting-encrypt.js +238 -0
- package/dist/shortcuts/caizhilian/operations/handlers/setting-storage.js +364 -0
- package/dist/shortcuts/caizhilian/operations/handlers/system.js +106 -0
- package/dist/shortcuts/caizhilian/operations/registry.js +151 -0
- package/dist/shortcuts/caizhilian/operations/shared.js +408 -0
- package/dist/shortcuts/caizhilian/operations/specs.js +623 -0
- package/dist/shortcuts/caizhilian/operations/types.js +57 -0
- package/dist/shortcuts/caizhilian/operations.js +21 -0
- package/dist/shortcuts/contract/continuation.js +70 -0
- package/dist/shortcuts/contract/errors.js +62 -0
- package/dist/shortcuts/contract/host.js +205 -0
- package/dist/shortcuts/contract/index.js +318 -0
- package/dist/shortcuts/contract/manifest.js +596 -0
- package/dist/shortcuts/contract/operations/clause-reference.js +78 -0
- package/dist/shortcuts/contract/operations/form-info.js +371 -0
- package/dist/shortcuts/contract/operations/read.js +118 -0
- package/dist/shortcuts/contract/operations/registry.js +43 -0
- package/dist/shortcuts/contract/operations/request.js +300 -0
- package/dist/shortcuts/contract/operations/shared.js +133 -0
- package/dist/shortcuts/contract/operations/subject.js +157 -0
- package/dist/shortcuts/contract/operations/template.js +81 -0
- package/dist/shortcuts/contract/operations/types.js +7 -0
- package/dist/shortcuts/contract/operations/workflow.js +52 -0
- package/dist/shortcuts/contract/operations/write.js +131 -0
- package/dist/shortcuts/contract/operations.js +8 -0
- package/dist/shortcuts/hrm/index.js +83 -2
- package/dist/shortcuts/hrm/operations/employee.js +160 -30
- package/dist/shortcuts/hrm/operations/org.js +17 -3
- package/dist/shortcuts/hrm/operations/position.js +18 -2
- package/dist/shortcuts/index.js +5 -1
- package/dist/shortcuts/invoice/index.js +74 -36
- package/dist/shortcuts/invoice/manifest.js +674 -4
- package/dist/shortcuts/invoice/markdown.js +172 -0
- package/dist/shortcuts/invoice/operations/add.js +3 -3
- package/dist/shortcuts/invoice/operations/delete.js +2 -2
- package/dist/shortcuts/invoice/operations/get.js +10 -2
- package/dist/shortcuts/invoice/operations/import.js +2 -2
- package/dist/shortcuts/invoice/operations/registry.js +8 -1
- package/dist/shortcuts/invoice/operations/reim-auto.js +719 -0
- package/dist/shortcuts/invoice/operations/reim.js +85 -2
- package/dist/shortcuts/invoice/operations/shared.js +75 -8
- package/dist/shortcuts/invoice/operations/update.js +2 -2
- package/dist/shortcuts/invoice/operations/upload-and-validate.js +93 -0
- package/dist/shortcuts/invoice/operations/validate-preview.js +2 -1
- package/dist/shortcuts/invoice/projection.js +328 -0
- package/dist/shortcuts/meeting/host.js +18 -1
- package/dist/shortcuts/meeting/manifest.js +30 -18
- package/dist/shortcuts/meeting/operations/eb/catalog.js +390 -0
- package/dist/shortcuts/meeting/operations/eb/conflict.js +389 -0
- package/dist/shortcuts/meeting/operations/eb/factory.js +389 -0
- package/dist/shortcuts/meeting/operations/eb/index.js +22 -0
- package/dist/shortcuts/meeting/operations/env.js +8 -1
- package/dist/shortcuts/meeting/operations/registry.js +2 -0
- package/dist/shortcuts/meeting/operations/signs.js +216 -2
- package/dist/shortcuts/workflow/endpoints.js +2 -1
- package/dist/shortcuts/workflow/errors.js +8 -2
- package/dist/shortcuts/workflow/host.js +6 -3
- package/dist/shortcuts/workflow/operations/form.js +931 -589
- package/dist/shortcuts/workflow/operations/read.js +128 -205
- package/dist/shortcuts/workflow/operations/shared.js +21 -0
- package/dist/shortcuts/workflow/operations/write.js +750 -52
- package/dist/shortcuts/workflow/operations.js +36 -10
- package/docs/_catalog.md +6 -0
- package/docs/agent-invoice.md +5 -1
- package/docs/agent-io-channel-design.md +468 -0
- package/docs/agent-skill-install.md +9 -4
- package/docs/blog.md +123 -0
- package/docs/caizhilian.md +304 -0
- package/docs/contract.md +91 -0
- package/docs/e10-auth.md +2 -2
- package/docs/hrm.md +19 -9
- package/docs/invoice.md +5 -1
- package/docs/meeting.md +1 -1
- package/docs/operation-manual.md +15 -3
- package/docs/skill-review-2026-09-19.md +2 -2
- package/package.json +2 -2
- package/scripts/package-skill.mjs +32 -20
- package/skill-template/business-info.json +113 -14
- package/skill-template/domains/blog.md +24 -0
- package/skill-template/domains/caizhilian.md +22 -0
- package/skill-template/domains/jinchengda.md +23 -0
- package/skill-template/domains/meeting.md +1 -1
- package/skill-template/domains/workflow.md +1 -1
- package/skill-template/skill-template.md +1 -1
- package/skills/weaver-e10-blog/SKILL.md +111 -0
- package/skills/weaver-e10-blog/references/blog-comment.md +51 -0
- package/skills/weaver-e10-blog/references/blog-comments.md +39 -0
- package/skills/weaver-e10-blog/references/blog-default-permission.md +38 -0
- package/skills/weaver-e10-blog/references/blog-disabled-capabilities.md +11 -0
- package/skills/weaver-e10-blog/references/blog-edit.md +51 -0
- package/skills/weaver-e10-blog/references/blog-export.md +42 -0
- package/skills/weaver-e10-blog/references/blog-like.md +50 -0
- package/skills/weaver-e10-blog/references/blog-publish.md +52 -0
- package/skills/weaver-e10-blog/references/blog-query-user.md +45 -0
- package/skills/weaver-e10-blog/references/blog-query.md +49 -0
- package/skills/weaver-e10-blog/references/blog-remind.md +51 -0
- package/skills/weaver-e10-blog/references/blog-resolve-users.md +38 -0
- package/skills/weaver-e10-blog/references/source-manifest.json +1540 -0
- package/skills/weaver-e10-caizhilian/SKILL.md +216 -0
- package/skills/weaver-e10-caizhilian/references/agent-entry.md +106 -0
- package/skills/weaver-e10-caizhilian/references/collaboration.md +112 -0
- package/skills/weaver-e10-caizhilian/references/document.md +111 -0
- package/skills/weaver-e10-caizhilian/references/file-collection.md +136 -0
- package/skills/weaver-e10-caizhilian/references/file-upload.md +309 -0
- package/skills/weaver-e10-caizhilian/references/files.md +120 -0
- package/skills/weaver-e10-caizhilian/references/folder.md +118 -0
- package/skills/weaver-e10-caizhilian/references/org-browser.md +104 -0
- package/skills/weaver-e10-caizhilian/references/setting-attach.md +410 -0
- package/skills/weaver-e10-caizhilian/references/setting-backup.md +372 -0
- package/skills/weaver-e10-caizhilian/references/setting-encrypt.md +399 -0
- package/skills/weaver-e10-caizhilian/references/setting-storage.md +603 -0
- package/skills/weaver-e10-caizhilian/references/source-manifest.json +5079 -0
- package/skills/weaver-e10-caizhilian/references/withheld.md +93 -0
- package/skills/weaver-e10-caizhilian/references/write-protocol.md +120 -0
- package/skills/weaver-e10-calendar/SKILL.md +4 -3
- package/skills/weaver-e10-ebuilder-form/SKILL.md +4 -9
- package/skills/weaver-e10-ebuilder-form/references/context-routing.md +0 -9
- package/skills/weaver-e10-ebuilder-form/references/custom-api.md +1 -5
- package/skills/weaver-e10-ebuilder-form/references/fields-browser.md +1 -5
- package/skills/weaver-e10-ebuilder-form/references/list-nlist.md +1 -5
- package/skills/weaver-e10-ebuilder-form/references/openapi-read.md +1 -5
- package/skills/weaver-e10-ebuilder-form/references/openapi-write.md +1 -5
- package/skills/weaver-e10-esb/SKILL.md +2 -2
- package/skills/weaver-e10-esb/references/source-manifest.json +9 -9
- package/skills/weaver-e10-hrm/SKILL.md +54 -6
- package/skills/weaver-e10-hrm/references/employee.md +89 -15
- package/skills/weaver-e10-hrm/references/org.md +7 -4
- package/skills/weaver-e10-hrm/references/position.md +14 -7
- package/skills/weaver-e10-hrm/references/source-manifest.json +1 -1
- package/skills/weaver-e10-jinchengda/SKILL.md +166 -0
- package/skills/weaver-e10-jinchengda/references/contract-agent-entry.md +82 -0
- package/skills/weaver-e10-jinchengda/references/contract-clause-recommender.md +69 -0
- package/skills/weaver-e10-jinchengda/references/contract-clause-reference-save.md +78 -0
- package/skills/weaver-e10-jinchengda/references/contract-disabled-capabilities.md +27 -0
- package/skills/weaver-e10-jinchengda/references/contract-request-status.md +71 -0
- package/skills/weaver-e10-jinchengda/references/contract-request-write.md +94 -0
- package/skills/weaver-e10-jinchengda/references/contract-signing-subjects.md +89 -0
- package/skills/weaver-e10-jinchengda/references/contract-subject-create.md +77 -0
- package/skills/weaver-e10-jinchengda/references/contract-template-selector.md +66 -0
- package/skills/weaver-e10-jinchengda/references/contract-workflow-discovery.md +94 -0
- package/skills/weaver-e10-jinchengda/references/source-manifest.json +259 -0
- package/skills/weaver-e10-jiuchuanhui/SKILL.md +5 -11
- package/skills/weaver-e10-jucailin/SKILL.md +4 -3
- package/skills/weaver-e10-mail/SKILL.md +4 -11
- package/skills/weaver-e10-meeting/SKILL.md +66 -32
- package/skills/weaver-e10-meeting/references/meeting-change.md +5 -2
- package/skills/weaver-e10-meeting/references/meeting-create.md +2 -1
- package/skills/weaver-e10-meeting/references/meeting-eb.md +114 -0
- package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +9 -8
- package/skills/weaver-e10-meeting/references/meeting-receipts-signs.md +35 -7
- package/skills/weaver-e10-meeting/references/meeting-update.md +1 -1
- package/skills/weaver-e10-okr/SKILL.md +6 -11
- package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
- package/skills/weaver-e10-plan/SKILL.md +3 -3
- package/skills/weaver-e10-plan/references/plan-collect-and-compose.md +1 -1
- package/skills/weaver-e10-plan/references/plan-overview-and-routing.md +1 -1
- package/skills/weaver-e10-plan/references/source-manifest.json +13 -13
- package/skills/weaver-e10-qiyecheng/SKILL.md +4 -10
- package/skills/weaver-e10-qiyecheng/references/source-manifest.json +9 -9
- package/skills/weaver-e10-shared/SKILL.md +36 -25
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +10 -31
- package/skills/weaver-e10-shared/references/json-output-contract.md +20 -11
- package/skills/weaver-e10-shijingran/SKILL.md +2 -1
- package/skills/weaver-e10-shijingran/references/source-manifest.json +9 -9
- package/skills/weaver-e10-skill-maker/SKILL.md +4 -10
- package/skills/weaver-e10-skill-maker/references/business-skill-generation.md +5 -3
- package/skills/weaver-e10-skill-maker/references/module-cli-generation.md +12 -27
- package/skills/weaver-e10-skill-maker/references/module-gap-audit-and-repair.md +17 -5
- package/skills/weaver-e10-skill-maker/references/source-update-detection.md +4 -27
- package/skills/weaver-e10-wenshuding/SKILL.md +5 -16
- package/skills/weaver-e10-wenshuding/references/source-manifest.json +7 -7
- package/skills/weaver-e10-workflow/SKILL.md +32 -37
- package/skills/weaver-e10-workflow/references/source-manifest.json +39 -75
- package/skills/weaver-e10-workflow/references/workflow-batch.md +90 -29
- package/skills/weaver-e10-workflow/references/workflow-create.md +79 -109
- package/skills/weaver-e10-workflow/references/workflow-memory.md +19 -9
- package/skills/weaver-e10-workflow/references/workflow-operate.md +2 -2
- package/skills/weaver-e10-workflow/references/workflow-query.md +38 -20
- package/skills/weaver-e10-workflow/references/workflow-share.md +18 -2
- package/skills/weaver-e10-workflow/references/workflow-view.md +3 -4
- package/skills/weaver-e10-yepiaotong/SKILL.md +75 -39
- package/skills/weaver-e10-yepiaotong/references/invoice-detail.md +22 -1
- package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +3 -1
- package/skills/weaver-e10-yepiaotong/references/invoice-output-view.md +135 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +15 -3
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +1 -1
- package/skills/weaver-e10-yepiaotong/references/invoice-summarize.py +217 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-upload-and-validate.md +88 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-validation-preview.md +7 -2
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +89 -9
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +1 -0
- package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +70 -49
- package/skills/weaver-e10-yepiaotong/references/reim-fast-path.md +119 -0
- package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +55 -36
- package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +4 -0
- package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +149 -0
- package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +125 -5
- package/skills/weaver-e10-yepiaotong/references/source-manifest.json +430 -63
- package/skills/weaver-e10-yimiaoban/SKILL.md +4 -12
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +3 -3
- package/skills/weaver-e10-ziguanjia/SKILL.md +2 -1
- package/skills/weaver-e10-ziguanjia/references/ziguanjia-agent-entry.md +3 -3
- package/tools/weaver-skill-detector-1.0.13/SKILL.md +9 -9
- package/tools/weaver-skill-detector-1.0.13/references/checklist.md +3 -3
- package/tools/weaver-skill-detector-1.0.13/scripts/__pycache__/validate_skill.cpython-313.pyc +0 -0
- package/tools/weaver-skill-detector-1.0.13/scripts/validate_skill.py +98 -91
- package/scripts/sync-connector-skills.mjs +0 -172
|
@@ -0,0 +1,190 @@
|
|
|
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 { CaizhilianCliError, caizhilianAuthError, caizhilianNetworkError, caizhilianValidationError, } from './errors.js';
|
|
5
|
+
/** 业务请求默认超时(源 assets/config.json:http.timeout = 12 秒)。 */
|
|
6
|
+
export const CAIZHILAN_TIMEOUT_MS = 12_000;
|
|
7
|
+
/** 上传/下载专用超时(源 _plugin_helpers.UPLOAD_DOWNLOAD_TIMEOUT = 120 秒)。 */
|
|
8
|
+
export const CAIZHILAN_TRANSFER_TIMEOUT_MS = 120_000;
|
|
9
|
+
/** 附件下载体积上限(源 assets/config.json:http.download.max_size_mb = 100)。 */
|
|
10
|
+
export const CAIZHILAN_MAX_DOWNLOAD_BYTES = 100 * 1024 * 1024;
|
|
11
|
+
function inferProfile(ctx) {
|
|
12
|
+
const options = ctx.getGlobalOptions();
|
|
13
|
+
return options.profile || getActiveProfile();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 判断响应是否业务成功。采知连(E10 文档中心)响应约定:
|
|
17
|
+
* 源 assets/config.json 的 response_convention 为 success_path=code / success_value=200,
|
|
18
|
+
* 少数 folderpermission 接口改回 status/success 布尔字段,这里按「先看 code,再看布尔」兜底。
|
|
19
|
+
*/
|
|
20
|
+
export function isCaizhilianBusinessSuccess(value) {
|
|
21
|
+
if (!value || typeof value !== 'object')
|
|
22
|
+
return false;
|
|
23
|
+
if (value.code !== undefined && value.code !== null)
|
|
24
|
+
return Number(value.code) === 200;
|
|
25
|
+
if (typeof value.success === 'boolean')
|
|
26
|
+
return value.success;
|
|
27
|
+
if (typeof value.status === 'boolean')
|
|
28
|
+
return value.status;
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
export function caizhilianBusinessMessage(value) {
|
|
32
|
+
if (!value || typeof value !== 'object')
|
|
33
|
+
return '采知连接口返回业务失败';
|
|
34
|
+
const candidates = [value.msg, value.message, value.errMsg, value.data?.msg, value.data?.message];
|
|
35
|
+
for (const item of candidates) {
|
|
36
|
+
if (typeof item === 'string' && item.trim())
|
|
37
|
+
return item;
|
|
38
|
+
}
|
|
39
|
+
return '采知连接口返回业务失败';
|
|
40
|
+
}
|
|
41
|
+
function caizhilianBusinessCode(value) {
|
|
42
|
+
if (!value || typeof value !== 'object')
|
|
43
|
+
return undefined;
|
|
44
|
+
const code = value.code ?? value.status;
|
|
45
|
+
if (typeof code === 'string' || typeof code === 'number')
|
|
46
|
+
return code;
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
export function assertCaizhilianPath(requestPath) {
|
|
50
|
+
if (typeof requestPath !== 'string' || !requestPath.startsWith('/') || requestPath.startsWith('//')) {
|
|
51
|
+
throw caizhilianValidationError('path_invalid', '请求路径必须是相对绝对路径');
|
|
52
|
+
}
|
|
53
|
+
if (/^https?:/i.test(requestPath) || /[\r\n]/.test(requestPath) || requestPath.includes('/../')) {
|
|
54
|
+
throw caizhilianValidationError('path_invalid', '请求路径不允许跨域或路径逃逸');
|
|
55
|
+
}
|
|
56
|
+
if (!requestPath.startsWith('/api/')) {
|
|
57
|
+
throw caizhilianValidationError('path_not_allowed', '采知连模块只能调用 /api/ 路径');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function formBody(form) {
|
|
61
|
+
if (!form)
|
|
62
|
+
return undefined;
|
|
63
|
+
const params = new URLSearchParams();
|
|
64
|
+
for (const [key, value] of Object.entries(form)) {
|
|
65
|
+
if (value === undefined || value === null)
|
|
66
|
+
continue;
|
|
67
|
+
params.set(key, typeof value === 'string' ? value : JSON.stringify(value));
|
|
68
|
+
}
|
|
69
|
+
return params;
|
|
70
|
+
}
|
|
71
|
+
function omitEmptyQueryValues(query) {
|
|
72
|
+
if (!query)
|
|
73
|
+
return undefined;
|
|
74
|
+
return Object.fromEntries(Object.entries(query).filter(([, value]) => value !== ''));
|
|
75
|
+
}
|
|
76
|
+
function mapRuntimeNetworkError(error) {
|
|
77
|
+
if (error instanceof E10ApiError && error.type === 'network') {
|
|
78
|
+
throw caizhilianNetworkError(error.subtype, error.message, {
|
|
79
|
+
retryable: error.retryable,
|
|
80
|
+
details: error.details,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
export function createCaizhilianHost(ctx, dependencies = {}) {
|
|
86
|
+
let e10Session = null;
|
|
87
|
+
let sessionContext = null;
|
|
88
|
+
const requireSession = dependencies.requireSession || requireE10Session;
|
|
89
|
+
async function ensureSession() {
|
|
90
|
+
if (!e10Session) {
|
|
91
|
+
e10Session = await requireSession(ctx);
|
|
92
|
+
sessionContext = {
|
|
93
|
+
baseUrl: e10Session.getBaseUrl(),
|
|
94
|
+
profile: inferProfile(ctx),
|
|
95
|
+
userId: e10Session.userId,
|
|
96
|
+
tenantKey: e10Session.tenantKey,
|
|
97
|
+
eteamsId: e10Session.eteamsId,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return e10Session;
|
|
101
|
+
}
|
|
102
|
+
async function getSession() {
|
|
103
|
+
await ensureSession();
|
|
104
|
+
return sessionContext;
|
|
105
|
+
}
|
|
106
|
+
async function runtime() {
|
|
107
|
+
return createE10RequestRuntime(ctx, await ensureSession(), {
|
|
108
|
+
interceptors: dependencies.interceptors,
|
|
109
|
+
fetch: dependencies.fetch,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
async function doRequest(request, binary) {
|
|
113
|
+
const { method, path, query, body, operation, form, multipart, headers: extraHeaders = {}, timeoutMs = CAIZHILAN_TIMEOUT_MS, } = request;
|
|
114
|
+
assertCaizhilianPath(path);
|
|
115
|
+
const resolvedMethod = method || (body === undefined && form === undefined && multipart === undefined ? 'GET' : 'POST');
|
|
116
|
+
const rt = await runtime();
|
|
117
|
+
const response = binary
|
|
118
|
+
? await rt.requestBinary({
|
|
119
|
+
module: 'caizhilian',
|
|
120
|
+
operation,
|
|
121
|
+
method: resolvedMethod,
|
|
122
|
+
path,
|
|
123
|
+
query: omitEmptyQueryValues(query),
|
|
124
|
+
body: multipart === undefined ? body : undefined,
|
|
125
|
+
form: multipart === undefined && form === undefined ? undefined : formBody(form ?? {}),
|
|
126
|
+
formData: multipart,
|
|
127
|
+
headers: { 'X-Requested-With': 'XMLHttpRequest', ...extraHeaders },
|
|
128
|
+
timeoutMs,
|
|
129
|
+
})
|
|
130
|
+
: await rt.requestJson({
|
|
131
|
+
module: 'caizhilian',
|
|
132
|
+
operation,
|
|
133
|
+
method: resolvedMethod,
|
|
134
|
+
path,
|
|
135
|
+
query: omitEmptyQueryValues(query),
|
|
136
|
+
body: multipart === undefined ? body : undefined,
|
|
137
|
+
form: multipart === undefined && form === undefined ? undefined : formBody(form ?? {}),
|
|
138
|
+
formData: multipart,
|
|
139
|
+
headers: { 'X-Requested-With': 'XMLHttpRequest', ...extraHeaders },
|
|
140
|
+
timeoutMs,
|
|
141
|
+
});
|
|
142
|
+
return response;
|
|
143
|
+
}
|
|
144
|
+
async function request(request) {
|
|
145
|
+
const response = await doRequest(request, false).catch((error) => mapRuntimeNetworkError(error));
|
|
146
|
+
if (response.status === 401 || response.status === 302) {
|
|
147
|
+
throw caizhilianAuthError('session_expired', 'E10 登录态已失效,请先向用户确认 E10 登录域名,再运行 weaver-work-cli auth login --base-url <域名> 完成登录', { httpStatus: response.status });
|
|
148
|
+
}
|
|
149
|
+
if (response.parseError) {
|
|
150
|
+
if (response.status < 200 || response.status >= 300) {
|
|
151
|
+
throw new CaizhilianCliError('api', 'http_error', `采知连接口 HTTP ${response.status}`, {
|
|
152
|
+
code: response.status,
|
|
153
|
+
details: { status: response.status },
|
|
154
|
+
exitCode: 1,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
throw caizhilianNetworkError('protocol', `接口返回不是合法 JSON(HTTP ${response.status})`, { retryable: false });
|
|
158
|
+
}
|
|
159
|
+
if (response.status < 200 || response.status >= 300) {
|
|
160
|
+
throw new CaizhilianCliError('api', 'http_error', `采知连接口 HTTP ${response.status}`, {
|
|
161
|
+
code: response.status,
|
|
162
|
+
details: { status: response.status, message: caizhilianBusinessMessage(response.value) },
|
|
163
|
+
exitCode: 1,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
if (!request.tolerateBusinessError && !isCaizhilianBusinessSuccess(response.value)) {
|
|
167
|
+
throw new CaizhilianCliError('api', 'business_error', caizhilianBusinessMessage(response.value), {
|
|
168
|
+
code: caizhilianBusinessCode(response.value),
|
|
169
|
+
details: { code: caizhilianBusinessCode(response.value), message: caizhilianBusinessMessage(response.value) },
|
|
170
|
+
exitCode: 1,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
return response.value;
|
|
174
|
+
}
|
|
175
|
+
async function requestBinary(request) {
|
|
176
|
+
const response = await doRequest(request, true).catch((error) => mapRuntimeNetworkError(error));
|
|
177
|
+
if (response.status === 401 || response.status === 302) {
|
|
178
|
+
throw caizhilianAuthError('session_expired', 'E10 登录态已失效,请先登录', { httpStatus: response.status });
|
|
179
|
+
}
|
|
180
|
+
if (response.status < 200 || response.status >= 300) {
|
|
181
|
+
throw new CaizhilianCliError('api', 'http_error', `采知连下载 HTTP ${response.status}`, {
|
|
182
|
+
code: response.status,
|
|
183
|
+
details: { status: response.status },
|
|
184
|
+
exitCode: 1,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
return { status: response.status, contentType: response.contentType, content: response.content, headers: response.headers };
|
|
188
|
+
}
|
|
189
|
+
return { request, requestBinary, getSession };
|
|
190
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { ExitCode, isCliError, toErrorEnvelope } from '../../core/errors.js';
|
|
3
|
+
import { createCaizhilianContinuationSigner } from './continuation.js';
|
|
4
|
+
import { caizhilianValidationError } from './errors.js';
|
|
5
|
+
import { createCaizhilianHost } from './host.js';
|
|
6
|
+
import { caizhilianManifest } from './manifest.js';
|
|
7
|
+
import { executeCaizhilianOperation } from './operations.js';
|
|
8
|
+
import { caizhilianOperationDefinitions } from './operations/registry.js';
|
|
9
|
+
function asOptions(value) {
|
|
10
|
+
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
11
|
+
}
|
|
12
|
+
async function readStdin() {
|
|
13
|
+
const chunks = [];
|
|
14
|
+
for await (const chunk of process.stdin) {
|
|
15
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
16
|
+
}
|
|
17
|
+
return Buffer.concat(chunks).toString('utf8');
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Windows PowerShell 的管道与 Set-Content -Encoding utf8 会在内容前写入 UTF-8 BOM,
|
|
21
|
+
* 且可能重复写入多次;JSON.parse 不接受前导 BOM,必须先剥离。
|
|
22
|
+
*/
|
|
23
|
+
function stripBom(value) {
|
|
24
|
+
return value.replace(/^\uFEFF+/, '');
|
|
25
|
+
}
|
|
26
|
+
function parseJsonInput(raw, label) {
|
|
27
|
+
try {
|
|
28
|
+
const parsed = JSON.parse(stripBom(raw));
|
|
29
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
30
|
+
throw new Error('input must be an object');
|
|
31
|
+
}
|
|
32
|
+
return parsed;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
throw caizhilianValidationError('input_invalid', `${label} 不是合法 JSON 对象`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export async function inputFrom(options, extra = {}) {
|
|
39
|
+
const opts = asOptions(options);
|
|
40
|
+
let input = {};
|
|
41
|
+
if (opts.input && opts.inputJson) {
|
|
42
|
+
throw caizhilianValidationError('input_conflict', '不能同时传 --input 和 --input-json');
|
|
43
|
+
}
|
|
44
|
+
if (opts.inputJson) {
|
|
45
|
+
input = parseJsonInput(String(opts.inputJson), '--input-json');
|
|
46
|
+
}
|
|
47
|
+
if (opts.input) {
|
|
48
|
+
let raw;
|
|
49
|
+
try {
|
|
50
|
+
raw = stripBom(opts.input === '-' ? await readStdin() : await readFile(String(opts.input), 'utf8'));
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
throw caizhilianValidationError('input_unreadable', `无法读取 --input:${String(opts.input)}`);
|
|
54
|
+
}
|
|
55
|
+
input = parseJsonInput(raw, '--input');
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
...input,
|
|
59
|
+
...Object.fromEntries(Object.entries(extra).filter(([, value]) => value !== undefined && value !== '')),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export function successEnvelope(operation, result) {
|
|
63
|
+
return {
|
|
64
|
+
schemaVersion: 1,
|
|
65
|
+
ok: true,
|
|
66
|
+
operation,
|
|
67
|
+
data: result.data === undefined ? null : result.data,
|
|
68
|
+
...(result.meta ? { meta: result.meta } : {}),
|
|
69
|
+
warnings: result.warnings ?? [],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function failureEnvelope(error) {
|
|
73
|
+
const structured = error;
|
|
74
|
+
return {
|
|
75
|
+
schemaVersion: 1,
|
|
76
|
+
ok: false,
|
|
77
|
+
...(structured?.partialData === undefined ? {} : { data: structured.partialData }),
|
|
78
|
+
error: toErrorEnvelope(error),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
async function executeAndPrint(ctx, operation, input) {
|
|
82
|
+
try {
|
|
83
|
+
const result = await executeCaizhilianOperation(operation, input, {
|
|
84
|
+
ctx,
|
|
85
|
+
host: createCaizhilianHost(ctx),
|
|
86
|
+
continuation: createCaizhilianContinuationSigner(ctx),
|
|
87
|
+
});
|
|
88
|
+
ctx.output.write(successEnvelope(operation, result), { json: true });
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
console.error(JSON.stringify(failureEnvelope(error), null, 2));
|
|
92
|
+
process.exitCode = isCliError(error) ? error.exitCode : ExitCode.GeneralError;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/** 按 resource 分组的操作清单(87 条对外 operation,便于 Agent 检索)。 */
|
|
96
|
+
function operationsCatalog() {
|
|
97
|
+
const groups = new Map();
|
|
98
|
+
for (const definition of caizhilianOperationDefinitions()) {
|
|
99
|
+
const list = groups.get(definition.resource) ?? [];
|
|
100
|
+
list.push({
|
|
101
|
+
name: definition.name,
|
|
102
|
+
summary: definition.summary,
|
|
103
|
+
risk: definition.risk,
|
|
104
|
+
...(definition.requiresConfirmation ? { requiresConfirmation: true } : {}),
|
|
105
|
+
sourceOperation: definition.sourceOperation,
|
|
106
|
+
});
|
|
107
|
+
groups.set(definition.resource, list);
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
schemaVersion: 1,
|
|
111
|
+
ok: true,
|
|
112
|
+
module: caizhilianManifest.name,
|
|
113
|
+
sourceSkill: caizhilianManifest.sourceSkill,
|
|
114
|
+
total: caizhilianOperationDefinitions().length,
|
|
115
|
+
groups: [...groups.entries()].map(([resource, operations]) => ({ resource, operations })),
|
|
116
|
+
withheldOperations: caizhilianManifest.withheldOperations,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function withJsonInputOptions(command) {
|
|
120
|
+
return command
|
|
121
|
+
.option('--input <path>', 'JSON input file, or - for stdin')
|
|
122
|
+
.option('--input-json <json>', 'inline JSON input object');
|
|
123
|
+
}
|
|
124
|
+
export const caizhilianShortcut = {
|
|
125
|
+
name: 'caizhilian',
|
|
126
|
+
description: '泛微E10采知连(文档中心)CLI',
|
|
127
|
+
category: 'shortcut',
|
|
128
|
+
register({ program, action }) {
|
|
129
|
+
const caizhilian = program
|
|
130
|
+
.command('caizhilian')
|
|
131
|
+
.description('泛微E10采知连文档中心(文档/文件夹/权限共享/标签/参与人/附件/封面/文档比对)');
|
|
132
|
+
caizhilian
|
|
133
|
+
.command('schema')
|
|
134
|
+
.description('Print caizhilian operation manifest for agents')
|
|
135
|
+
.action(action((ctx) => {
|
|
136
|
+
ctx.output.write(caizhilianManifest, { json: true });
|
|
137
|
+
}));
|
|
138
|
+
caizhilian
|
|
139
|
+
.command('operations')
|
|
140
|
+
.description('List caizhilian operations grouped by resource')
|
|
141
|
+
.action(action((ctx) => {
|
|
142
|
+
ctx.output.write(operationsCatalog(), { json: true });
|
|
143
|
+
}));
|
|
144
|
+
withJsonInputOptions(caizhilian
|
|
145
|
+
.command('run')
|
|
146
|
+
.description('Run a caizhilian operation with JSON input')
|
|
147
|
+
.argument('<operation>', 'operation name, e.g. caizhilian.document.search / caizhilian.tag.add.apply')
|
|
148
|
+
.option('--continuation <token>', 'prepare 返回的确认票据(apply 必填)')
|
|
149
|
+
.option('--yes', 'confirm the write operation(apply 必填)')).action(action(async (ctx, operation, options) => {
|
|
150
|
+
const opts = asOptions(options);
|
|
151
|
+
await executeAndPrint(ctx, String(operation), await inputFrom(options, {
|
|
152
|
+
continuation: opts.continuation,
|
|
153
|
+
confirm: opts.yes === true ? true : undefined,
|
|
154
|
+
}));
|
|
155
|
+
}));
|
|
156
|
+
// ---- 高频便捷命令 ----
|
|
157
|
+
withJsonInputOptions(caizhilian
|
|
158
|
+
.command('search')
|
|
159
|
+
.description('检索文档(caizhilian.document.search 薄包装)')
|
|
160
|
+
.option('--keywords <kw>', '检索关键词')
|
|
161
|
+
.option('--folder-id <id>', '文件夹 ID:100=系统,200=公共,300=个人')
|
|
162
|
+
.option('--page-no <n>', '页码(1-indexed)')
|
|
163
|
+
.option('--page-size <n>', '每页条数')).action(action(async (ctx, options) => {
|
|
164
|
+
const opts = asOptions(options);
|
|
165
|
+
await executeAndPrint(ctx, 'caizhilian.document.search', await inputFrom(options, {
|
|
166
|
+
keywords: opts.keywords,
|
|
167
|
+
folder_id: opts.folderId,
|
|
168
|
+
page_no: opts.pageNo,
|
|
169
|
+
page_size: opts.pageSize,
|
|
170
|
+
}));
|
|
171
|
+
}));
|
|
172
|
+
withJsonInputOptions(caizhilian
|
|
173
|
+
.command('get')
|
|
174
|
+
.description('查询文档详情(caizhilian.document.get 薄包装)')
|
|
175
|
+
.option('--doc-id <id>', '文档 ID(必填)')).action(action(async (ctx, options) => {
|
|
176
|
+
const opts = asOptions(options);
|
|
177
|
+
await executeAndPrint(ctx, 'caizhilian.document.get', await inputFrom(options, { doc_id: opts.docId }));
|
|
178
|
+
}));
|
|
179
|
+
caizhilian
|
|
180
|
+
.command('health')
|
|
181
|
+
.description('采知连接口连通性与登录态自检(caizhilian.system.health 薄包装)')
|
|
182
|
+
.action(action(async (ctx) => {
|
|
183
|
+
await executeAndPrint(ctx, 'caizhilian.system.health', {});
|
|
184
|
+
}));
|
|
185
|
+
},
|
|
186
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { caizhilianOperationContracts } from './operations/registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* 禁用边界:源 Skill 的 64 个 operation 中,4 个属于「本地多环境配置」能力,
|
|
4
|
+
* 在 weaver-work-cli 里由框架层统一承担(config / e10 auth),模块 CLI 不重复实现,
|
|
5
|
+
* 因此不进入 operations,仅在此显式声明,避免 Agent 误以为能力缺失。
|
|
6
|
+
*/
|
|
7
|
+
const WITHHELD = [
|
|
8
|
+
{
|
|
9
|
+
name: 'caizhilian.system.list-systems',
|
|
10
|
+
reason: '源 list_systems 读取的是 Skill 自带 assets/config.json 的多环境配置与登录态;weaver-work-cli 的环境与登录态由框架统一管理,请用 `weaver-work-cli config list` 与 `weaver-work-cli auth status` 查看,连通性自检用 caizhilian.system.health。',
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
name: 'caizhilian.system.get-loaded-config',
|
|
14
|
+
reason: '源 get_loaded_config 会输出 Skill 本地 config.json 的生效内容(含 cookies 掩码、下载目录等);CLI 侧等价信息来自框架配置,请用 `weaver-work-cli config list`,不在业务模块内暴露配置快照。',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'caizhilian.system.reload-config',
|
|
18
|
+
reason: '源 reload_config 重新加载 Skill 本地 config.json;CLI 每次进程启动即读取框架配置,无进程内缓存需要刷新,故不提供该操作。',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'caizhilian.system.switch-config',
|
|
22
|
+
reason: '源 switch_config 在 Skill 本地多套环境配置间切换;CLI 的环境切换由 `weaver-work-cli config set` / `weaver-work-cli auth login --base-url <域名>` 承担,业务模块不做环境切换。',
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
function buildOperations() {
|
|
26
|
+
return caizhilianOperationContracts();
|
|
27
|
+
}
|
|
28
|
+
export const caizhilianManifest = {
|
|
29
|
+
schemaVersion: 1,
|
|
30
|
+
name: 'caizhilian',
|
|
31
|
+
title: '泛微E10采知连(文档中心:文档/文件夹/权限共享/标签/参与人/附件/封面/比对)',
|
|
32
|
+
version: '0.1.0',
|
|
33
|
+
host: 'e10-caizhilian',
|
|
34
|
+
status: 'builtin',
|
|
35
|
+
sourceSkill: 'weaver-e10-caizhilian',
|
|
36
|
+
capabilities: ['caizhilian'],
|
|
37
|
+
operations: buildOperations(),
|
|
38
|
+
withheldOperations: WITHHELD,
|
|
39
|
+
};
|
|
40
|
+
export function hasCaizhilianManifestOperation(operation) {
|
|
41
|
+
return caizhilianManifest.operations.some((item) => item.name === operation);
|
|
42
|
+
}
|