weaver-work-cli 0.1.20 → 0.1.22

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.
Files changed (77) hide show
  1. package/README.md +19 -11
  2. package/dist/core/refs.js +39 -36
  3. package/dist/internal/e10/auth/commands.js +33 -18
  4. package/dist/internal/e10/auth/session.js +60 -2
  5. package/dist/internal/e10/auth/xiaoe.js +253 -53
  6. package/dist/internal/e10/context.js +18 -6
  7. package/dist/internal/e10/request-runtime.js +3 -1
  8. package/dist/shortcuts/caizhilian/operations/confirm.js +1 -1
  9. package/dist/shortcuts/caizhilian/operations/handlers/file-collection.js +901 -20
  10. package/dist/shortcuts/caizhilian/operations/handlers/folder.js +55 -0
  11. package/dist/shortcuts/caizhilian/operations/handlers/setting-attach.js +4 -4
  12. package/dist/shortcuts/caizhilian/operations/specs.js +75 -0
  13. package/dist/shortcuts/hrm/manifest.js +16 -9
  14. package/dist/shortcuts/hrm/operations/registry.js +2 -0
  15. package/dist/shortcuts/hrm/operations/resolve.js +449 -0
  16. package/dist/shortcuts/invoice/host.js +5 -4
  17. package/dist/shortcuts/meeting/operations/eb/association.js +151 -0
  18. package/dist/shortcuts/meeting/operations/eb/attendance-summary.js +153 -0
  19. package/dist/shortcuts/meeting/operations/eb/catalog.js +185 -13
  20. package/dist/shortcuts/meeting/operations/eb/conflict.js +17 -11
  21. package/dist/shortcuts/meeting/operations/eb/decision.js +385 -0
  22. package/dist/shortcuts/meeting/operations/eb/factory.js +222 -35
  23. package/dist/shortcuts/meeting/operations/eb/index.js +18 -1
  24. package/dist/shortcuts/meeting/operations/eb/link.js +212 -0
  25. package/dist/shortcuts/meeting/operations/eb/task-progress.js +123 -0
  26. package/dist/shortcuts/meeting/operations/env.js +78 -61
  27. package/dist/shortcuts/meeting/operations/link.js +125 -0
  28. package/dist/shortcuts/meeting/operations/registry.js +2 -0
  29. package/dist/shortcuts/meeting/operations/shared.js +13 -0
  30. package/dist/shortcuts/workflow/host.js +5 -1
  31. package/dist/shortcuts/workflow/operations/form.js +95 -11
  32. package/dist/shortcuts/workflow/operations/read.js +785 -26
  33. package/docs/e10-auth.md +8 -2
  34. package/docs/hrm.md +34 -2
  35. package/docs/invoice.md +3 -0
  36. package/package.json +2 -2
  37. package/scripts/xiaoe_env.py +118 -0
  38. package/skill-template/domains/hrm.md +2 -1
  39. package/skill-template/skill-template.md +1 -1
  40. package/skills/weaver-e10-blog/SKILL.md +1 -1
  41. package/skills/weaver-e10-caizhilian/SKILL.md +5 -4
  42. package/skills/weaver-e10-caizhilian/references/file-collection.md +37 -0
  43. package/skills/weaver-e10-caizhilian/references/folder.md +5 -1
  44. package/skills/weaver-e10-caizhilian/references/setting-attach.md +35 -5
  45. package/skills/weaver-e10-caizhilian/references/source-manifest.json +620 -5
  46. package/skills/weaver-e10-calendar/SKILL.md +1 -1
  47. package/skills/weaver-e10-ebuilder-form/SKILL.md +1 -1
  48. package/skills/weaver-e10-esb/SKILL.md +1 -1
  49. package/skills/weaver-e10-hrm/SKILL.md +52 -5
  50. package/skills/weaver-e10-hrm/references/org.md +107 -1
  51. package/skills/weaver-e10-jinchengda/SKILL.md +2 -1
  52. package/skills/weaver-e10-jiuchuanhui/SKILL.md +1 -1
  53. package/skills/weaver-e10-jucailin/SKILL.md +1 -1
  54. package/skills/weaver-e10-mail/SKILL.md +1 -1
  55. package/skills/weaver-e10-meeting/SKILL.md +27 -11
  56. package/skills/weaver-e10-meeting/references/meeting-eb.md +162 -7
  57. package/skills/weaver-e10-meeting/references/meeting-verification.md +271 -0
  58. package/skills/weaver-e10-meeting.zip +0 -0
  59. package/skills/weaver-e10-okr/SKILL.md +1 -1
  60. package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
  61. package/skills/weaver-e10-plan/SKILL.md +1 -1
  62. package/skills/weaver-e10-qiyecheng/SKILL.md +1 -1
  63. package/skills/weaver-e10-shared/SKILL.md +10 -13
  64. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +11 -17
  65. package/skills/weaver-e10-shared/references/non-interactive-environment.md +21 -14
  66. package/skills/weaver-e10-shijingran/SKILL.md +1 -1
  67. package/skills/weaver-e10-skill-maker/SKILL.md +1 -1
  68. package/skills/weaver-e10-skill-maker/references/weaver-skill-style.md +1 -1
  69. package/skills/weaver-e10-wenshuding/SKILL.md +1 -1
  70. package/skills/weaver-e10-workflow/SKILL.md +19 -19
  71. package/skills/weaver-e10-workflow/references/source-manifest.json +13 -13
  72. package/skills/weaver-e10-workflow/references/workflow-create.md +11 -7
  73. package/skills/weaver-e10-workflow/references/workflow-query.md +9 -14
  74. package/skills/weaver-e10-yepiaotong/SKILL.md +1 -2
  75. package/skills/weaver-e10-yimiaoban/SKILL.md +1 -1
  76. package/skills/weaver-e10-yimiaoban/references/source-manifest.json +3 -3
  77. package/skills/weaver-e10-ziguanjia/SKILL.md +1 -1
@@ -857,6 +857,60 @@ async function permissionDetail(args, env) {
857
857
  const result = await fetchFolderPermissionEntries(env, folderId, settingTypeRaw, action);
858
858
  return caizhilianSuccess(action, { title, items: result.shares });
859
859
  }
860
+ // ── caizhilian.folder.permission.sync-setting ─────────────
861
+ const SYNC_FOLDER_SETTING_PATH = '/api/doc/folderSetting/syncFolderSetting';
862
+ function planSyncSetting(args) {
863
+ const folderId = requireId(args.id, '文件夹 ID');
864
+ const keepOldSettingForAllFolders = typeof args.keepOldSettingForAllFolders === 'boolean'
865
+ ? args.keepOldSettingForAllFolders
866
+ : false;
867
+ return {
868
+ folderId,
869
+ keepOldSettingForAllFolders,
870
+ body: {
871
+ type: 'settingPermission',
872
+ id: folderId,
873
+ keepOldShare: true,
874
+ keepOldSettingForAllFolders,
875
+ },
876
+ };
877
+ }
878
+ const PERMISSION_SYNC_SETTING_APPLY = 'caizhilian.folder.permission.sync-setting.apply';
879
+ const permissionSyncSettingHandler = {
880
+ targetKeys: ['id'],
881
+ async prepare(args, env) {
882
+ const action = 'caizhilian.folder.permission.sync-setting';
883
+ const plan = planSyncSetting(args);
884
+ const lease = await issueWriteLease(env, PERMISSION_SYNC_SETTING_APPLY, args, {
885
+ id: plan.folderId,
886
+ keepOldSettingForAllFolders: plan.keepOldSettingForAllFolders,
887
+ body_fingerprint: fingerprint(plan.body),
888
+ });
889
+ return caizhilianPrepared(action, {
890
+ id: plan.folderId,
891
+ keepOldSettingForAllFolders: plan.keepOldSettingForAllFolders,
892
+ request: { method: 'POST', path: SYNC_FOLDER_SETTING_PATH, body: plan.body },
893
+ }, lease);
894
+ },
895
+ async apply(args, env, lease) {
896
+ const action = PERMISSION_SYNC_SETTING_APPLY;
897
+ const plan = planSyncSetting(args);
898
+ const expected = typeof lease.body_fingerprint === 'string' ? lease.body_fingerprint : '';
899
+ if (expected && expected !== fingerprint(plan.body)) {
900
+ throw caizhilianValidationError('plan_changed', `${action} 的请求体与 prepare 时不一致,请重新执行 prepare`);
901
+ }
902
+ const response = await env.host.request({
903
+ method: 'POST',
904
+ path: SYNC_FOLDER_SETTING_PATH,
905
+ body: plan.body,
906
+ operation: action,
907
+ });
908
+ const data = asRecord(response);
909
+ assertToleratedBusinessSuccess(data, action);
910
+ const existChildFolder = asRecord(data.data).existChildFolder ?? false;
911
+ return caizhilianSuccess(action, { existChildFolder });
912
+ },
913
+ };
860
914
  // ── caizhilian.folder.permission.query ────────────────────
861
915
  async function permissionQuery(args, env) {
862
916
  const action = 'caizhilian.folder.permission.query';
@@ -964,6 +1018,7 @@ export const caizhilianFolderHandlers = {
964
1018
  'caizhilian.folder.permission.get-auth': { execute: permissionGetAuth },
965
1019
  'caizhilian.folder.permission.set-auth': permissionSetAuthHandler,
966
1020
  'caizhilian.folder.permission.detail': { execute: permissionDetail },
1021
+ 'caizhilian.folder.permission.sync-setting': permissionSyncSettingHandler,
967
1022
  'caizhilian.folder.permission.query': { execute: permissionQuery },
968
1023
  'caizhilian.folder.query-by-permission': { execute: queryFoldersByPermission },
969
1024
  };
@@ -30,7 +30,7 @@ const FIELD_MAP = {
30
30
  'attach-expand': { dtoKey: 'sysAttachmentListDefaultExpand', type: 'boolean' },
31
31
  'custom-msg': { dtoKey: 'sysUploadCustomMsgEnable', type: 'boolean' },
32
32
  'batch-download': { dtoKey: 'sysBatchDownload', type: 'boolean' },
33
- 'mobile-block': { dtoKey: 'sysAppDownload', type: 'boolean', parse: (v) => !parseBoolean(v) }, // 语义取反
33
+ 'mobile-block': { dtoKey: 'sysAppDownload', type: 'boolean' }, // CLI true → DTO true(禁止移动端下载)
34
34
  'download-pdf-types': { dtoKey: 'sysDownloadToPdfFileTypes', type: 'string' },
35
35
  'img-compress': { dtoKey: 'sysImgCompressEnable', type: 'boolean' },
36
36
  'img-compress-quality': { dtoKey: 'sysImgCompressQuality', type: 'string' },
@@ -92,7 +92,7 @@ async function getSettingAttach(args, env) {
92
92
  custom_msg_enable: settings.sysUploadCustomMsgEnable ?? false,
93
93
  custom_msg: settings.sysUploadCustomMsg || '',
94
94
  batch_download: settings.sysBatchDownload ?? true,
95
- mobile_block: !(settings.sysAppDownload ?? true), // 语义取反
95
+ mobile_block: settings.sysAppDownload ?? false, // CLI true ↔ DTO true(禁止移动端下载)
96
96
  download_pdf_types: settings.sysDownloadToPdfFileTypes || '',
97
97
  img_compress: settings.sysImgCompressEnable ?? false,
98
98
  img_compress_quality: settings.sysImgCompressQuality || 'medium',
@@ -189,7 +189,7 @@ async function setSettingAttachPrepare(args, env) {
189
189
  format_mode: current.sysFormatWhitesEnable ? 'whitelist' : 'blacklist',
190
190
  format_list: current.sysFormatWhitesEnable ? (current.sysFormatWhites || '*') : (current.sysFormatBlacks || ''),
191
191
  batch_download: current.sysBatchDownload ?? true,
192
- mobile_block: !(current.sysAppDownload ?? true),
192
+ mobile_block: current.sysAppDownload ?? false,
193
193
  },
194
194
  continuation: lease.continuation,
195
195
  expires_in_ms: lease.expiresInMs,
@@ -232,7 +232,7 @@ async function setSettingAttachApply(args, env, lease) {
232
232
  format_mode: verified.sysFormatWhitesEnable ? 'whitelist' : 'blacklist',
233
233
  format_list: verified.sysFormatWhitesEnable ? (verified.sysFormatWhites || '*') : (verified.sysFormatBlacks || ''),
234
234
  batch_download: verified.sysBatchDownload ?? true,
235
- mobile_block: !(verified.sysAppDownload ?? true),
235
+ mobile_block: verified.sysAppDownload ?? false,
236
236
  },
237
237
  });
238
238
  }
@@ -306,6 +306,10 @@ export const caizhilianOperationSpecs = [
306
306
  }),
307
307
  ...pageProps(20),
308
308
  }, ['permission_key', 'permissions']),
309
+ spec('folder', 'permission.sync-setting', 'sync_folder_setting_permission', 'high-risk-write', '将当前文件夹的"管理员"权限设置同步到下级子文件夹', {
310
+ id: ID('文件夹 ID'),
311
+ keepOldSettingForAllFolders: BOOL('是否保留原有管理员设置(true=保留,false=不保留)'),
312
+ }, ['id'], { requiresConfirmation: true }),
309
313
  // ── setting-attach ──────────────────────────────────────
310
314
  spec('setting-attach', 'get', 'get_setting_attach', 'read', '读取附件设置(文件设置 → 附件设置)', {}, [], {
311
315
  method: 'http_template',
@@ -436,6 +440,13 @@ export const caizhilianOperationSpecs = [
436
440
  spec('file-collection', 'task.form', 'get_collection_task_form', 'read', '获取采集任务表单', {
437
441
  id: ID('任务 ID(可选)'),
438
442
  }),
443
+ spec('file-collection', 'task.save', 'save_collection_task', 'high-risk-write', '保存采集任务', {
444
+ source_id: ID('FTP/SFTP 资源 ID'),
445
+ workflow_id: ID('动作流 ID'),
446
+ task_name: S('任务名称(可选,不传时自动生成)'),
447
+ retain_dir_struct: BOOL('是否维持原目录结构(默认 true)'),
448
+ task_file_path: S('采集路径(默认 /)'),
449
+ }, ['source_id', 'workflow_id'], { requiresConfirmation: true }),
439
450
  spec('file-collection', 'storage.check', 'check_collection_storage', 'read', '检查存储连接', {}, [], {
440
451
  method: 'http_template',
441
452
  }),
@@ -462,6 +473,70 @@ export const caizhilianOperationSpecs = [
462
473
  spec('file-collection', 'delete', 'delete_collection_task', 'high-risk-write', '删除采集任务', {
463
474
  task_id: ID('任务 ID'),
464
475
  }, ['task_id'], { requiresConfirmation: true }),
476
+ // ── file-collection: 任务管理补充 ─────────────────────────
477
+ spec('file-collection', 'task.switch', 'switch_collection_task', 'high-risk-write', '切换采集任务启用/禁用状态', {
478
+ task_id: ID('任务 ID'),
479
+ task_status: INT('任务状态码'),
480
+ task_switch: BOOL('是否启用'),
481
+ }, ['task_id', 'task_status', 'task_switch'], { requiresConfirmation: true }),
482
+ spec('file-collection', 'task.save-as', 'save_as_collection_task', 'high-risk-write', '另存为采集任务副本', {
483
+ task_id: ID('源任务 ID'),
484
+ }, ['task_id'], { requiresConfirmation: true }),
485
+ spec('file-collection', 'task.update-fonds', 'update_collection_task_fonds', 'high-risk-write', '更新采集任务的全宗 ID(用于归档分支)', {
486
+ task_id: ID('任务 ID'),
487
+ fonds_id: ID('全宗 ID'),
488
+ }, ['task_id', 'fonds_id'], { requiresConfirmation: true }),
489
+ // ── file-collection: 连接器/资源管理 ─────────────────────
490
+ spec('file-collection', 'connector.query', 'query_collection_connectors', 'read', '查询 FTP/SFTP 连接器列表及其资源', {
491
+ name: S('连接器名称过滤(可选)'),
492
+ protocol_type: S('协议类型过滤', { default: 'nas,ftp,sftp' }),
493
+ ...pageProps(20),
494
+ max_pages: INT('最大翻页数', { minimum: 1, default: 5 }),
495
+ }),
496
+ spec('file-collection', 'connector.create', 'create_collection_connector', 'high-risk-write', '创建 FTP 连接器', {
497
+ name: S('连接器名称(可选,不传时自动生成)'),
498
+ company: S('公司名称', { default: '文件采集' }),
499
+ }, [], { requiresConfirmation: true }),
500
+ spec('file-collection', 'resource.create', 'create_collection_resource', 'high-risk-write', '创建 FTP/SFTP 资源连接', {
501
+ system_pk: ID('连接器 ID(不传时自动创建连接器)'),
502
+ name: S('资源名称', { default: '文件采集FTP连接' }),
503
+ remote_host: S('FTP 服务器地址'),
504
+ remote_port: S('FTP 端口'),
505
+ remote_username: S('FTP 用户名'),
506
+ remote_password: S('FTP 密码'),
507
+ transfer_protocol: S('传输协议', { enum: ['FTP', 'SFTP'] }),
508
+ }, ['remote_host', 'remote_port', 'remote_username', 'remote_password', 'transfer_protocol'], { requiresConfirmation: true }),
509
+ // ── file-collection: 动作流管理 ─────────────────────────
510
+ spec('file-collection', 'workflow.search', 'search_collection_workflows', 'read', '搜索动作流应用列表', {
511
+ name_contains: S('名称过滤关键词(可选)'),
512
+ ...pageProps(50),
513
+ }),
514
+ spec('file-collection', 'workflow.inspect', 'inspect_collection_workflow', 'read', '检测动作流是否兼容文件采集', {
515
+ application_id: ID('动作流应用 ID'),
516
+ archive_required: BOOL('是否需要归档兼容', { default: false }),
517
+ retain_dir_struct: BOOL('是否维持原目录结构', { default: false }),
518
+ }, ['application_id']),
519
+ spec('file-collection', 'workflow.create', 'create_collection_workflow', 'high-risk-write', '动态创建文件采集动作流', {
520
+ name: S('动作流名称(可选,不传时自动生成)'),
521
+ archive_required: BOOL('是否需要归档兼容', { default: false }),
522
+ retain_dir_struct: BOOL('是否维持原目录结构', { default: false }),
523
+ }, [], { requiresConfirmation: true }),
524
+ spec('file-collection', 'workflow.enable', 'enable_collection_workflow', 'high-risk-write', '启用动作流应用', {
525
+ application_id: ID('动作流应用 ID'),
526
+ }, ['application_id'], { requiresConfirmation: true }),
527
+ spec('file-collection', 'workflow.update-task', 'update_collection_task_workflow', 'high-risk-write', '更新采集任务关联的动作流 ID', {
528
+ task_id: ID('任务 ID'),
529
+ workflow_id: ID('新动作流 ID'),
530
+ }, ['task_id', 'workflow_id'], { requiresConfirmation: true }),
531
+ // ── file-collection: 等待与结果验证 ─────────────────────
532
+ spec('file-collection', 'scan.wait', 'wait_scan_completion', 'read', '轮询扫描进度直到完成', {
533
+ runtime_id: S('扫描运行时 ID(来自 scan.apply 返回)'),
534
+ timeout_seconds: INT('超时秒数', { minimum: 1, default: 300 }),
535
+ interval_seconds: INT('轮询间隔秒数', { minimum: 1, default: 3 }),
536
+ }, ['runtime_id']),
537
+ spec('file-collection', 'run.result', 'get_collection_run_result', 'read', '查询采集运行结果并归一化', {
538
+ task_id: ID('任务 ID'),
539
+ }, ['task_id']),
465
540
  // ── file-upload ─────────────────────────────────────────
466
541
  spec('file-upload', 'contract', 'get_upload_contract', 'read', '获取上传接口合约', {}, [], {
467
542
  method: 'http_template',
@@ -1,9 +1,21 @@
1
1
  import { hrmOperationDefinitions } from './operations/registry.js';
2
2
  /**
3
- * 代理商查询(containsDls=true)禁用边界:仅泛微自用系统域名支持(自用域名白名单),
4
- * 客户/其他环境禁止触发。未实现,不得编造或绕过。
3
+ * 明确「不提供」的能力边界(不得编造、不得绕过):
4
+ * - `hrm.employee.dls`:代理商查询仅泛微自用系统域名支持(自用域名白名单),未实现。
5
+ * - `hrm.org.virtuals`:多维(组织维度)清单**不单独暴露**——维度获取与匹配已并入
6
+ * `hrm.org.resolve` 内部;「列出该租户有哪些多维」属暂不支持的诉求,
7
+ * 不要构造一个不存在的维度名去套 `availableVirtuals`,也不要绕过。
5
8
  */
6
- const DLS_WITHHELD = ['hrm.employee.dls'];
9
+ const WITHHELD = [
10
+ {
11
+ name: 'hrm.employee.dls',
12
+ reason: '代理商查询(containsDls=true)仅泛微自用系统域名支持(自用域名白名单),客户/其他环境禁止触发;未实现,不得编造或绕过。',
13
+ },
14
+ {
15
+ name: 'hrm.org.virtuals',
16
+ reason: '多维(组织维度)清单不单独暴露:维度获取与名称匹配已并入 hrm.org.resolve 内部(其 not_found 会顺带回 availableVirtuals 供纠错)。「列出该租户有哪些多维」暂不支持,不要构造不存在的维度名去套 availableVirtuals,也不要编造或绕过。',
17
+ },
18
+ ];
7
19
  function buildOperations() {
8
20
  return hrmOperationDefinitions().map((definition) => ({
9
21
  name: definition.name,
@@ -23,10 +35,5 @@ export const hrmManifest = {
23
35
  sourceSkill: 'weaver-e10-hrm',
24
36
  capabilities: ['employee', 'org', 'position'],
25
37
  operations: buildOperations(),
26
- withheldOperations: [
27
- ...DLS_WITHHELD.map((name) => ({
28
- name,
29
- reason: '代理商查询(containsDls=true)仅泛微自用系统域名支持(自用域名白名单),客户/其他环境禁止触发;未实现,不得编造或绕过。',
30
- })),
31
- ],
38
+ withheldOperations: WITHHELD,
32
39
  };
@@ -2,11 +2,13 @@ import { hrmValidationError } from '../errors.js';
2
2
  import { hrmEmployeeOperations } from './employee.js';
3
3
  import { hrmOrgOperations } from './org.js';
4
4
  import { hrmPositionOperations } from './position.js';
5
+ import { hrmResolveOperations } from './resolve.js';
5
6
  function buildRegistry() {
6
7
  const registry = new Map();
7
8
  const definitions = [
8
9
  ...hrmEmployeeOperations,
9
10
  ...hrmOrgOperations,
11
+ ...hrmResolveOperations,
10
12
  ...hrmPositionOperations,
11
13
  ];
12
14
  for (const definition of definitions) {