@thinkingai/ae-cli 6.0.54 → 6.0.56

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 (118) hide show
  1. package/README.md +24 -3
  2. package/README.zh.md +24 -3
  3. package/dist/{auth-MBWRZTB6.js → auth-U7MNUUEF.js} +37 -13
  4. package/dist/{automation-NWWVLWG2.js → automation-K32V2NKP.js} +94 -38
  5. package/dist/{capability-7SSN6PNZ.js → capability-VV7RHB3B.js} +8 -7
  6. package/dist/{chunk-CT7QDJS6.js → chunk-2IYIYSUO.js} +2 -2
  7. package/dist/{chunk-PLE722AJ.js → chunk-2UWS5CUP.js} +62 -35
  8. package/dist/{chunk-ZIQWCZTS.js → chunk-3TQA5RXE.js} +3 -3
  9. package/dist/{chunk-KFNMQTZI.js → chunk-ELCR235M.js} +26 -19
  10. package/dist/{chunk-FMNNGNYO.js → chunk-F6NIPIT5.js} +7 -6
  11. package/dist/{chunk-D6ACFILC.js → chunk-GI5BMEZO.js} +1 -1
  12. package/dist/chunk-JJJIP2XQ.js +105 -0
  13. package/dist/{chunk-5XJYLEVC.js → chunk-KHS64JZQ.js} +4 -4
  14. package/dist/{chunk-UQ77JXYH.js → chunk-LMCYSVVA.js} +12 -13
  15. package/dist/{chunk-EOYSKMXN.js → chunk-MXV3PYC3.js} +14 -6
  16. package/dist/{chunk-7QXISROD.js → chunk-P6VFCH3P.js} +4 -2
  17. package/dist/{chunk-GIK6EDUG.js → chunk-P7KL7IOH.js} +41 -13
  18. package/dist/{chunk-AP7YP2NX.js → chunk-QSAR3GHY.js} +2 -2
  19. package/dist/{chunk-S6M42KND.js → chunk-T44M3PLZ.js} +1 -1
  20. package/dist/{chunk-HVHR4SCP.js → chunk-UUD5RB36.js} +3 -3
  21. package/dist/{chunk-HBLK3ZHW.js → chunk-W2PTY5NN.js} +3 -3
  22. package/dist/chunk-X7DRLE62.js +233 -0
  23. package/dist/{chunk-WNGFSIOB.js → chunk-ZW4VMY5H.js} +103 -6
  24. package/dist/{community-report-client-PEERQCX2.js → community-report-client-S2K3A3Q6.js} +1 -1
  25. package/dist/{config-FF6YVJKI.js → config-ASSAAIOI.js} +10 -9
  26. package/dist/{context-YAE3QXP3.js → context-6RWLVOM5.js} +4 -4
  27. package/dist/{data-integration-HESZET7E.js → data-integration-EXSUPUDZ.js} +6 -6
  28. package/dist/evaluation-5YT4QLCL.js +3714 -0
  29. package/dist/index.js +93 -49
  30. package/dist/{local-data-upload-client-TWMHFLUA.js → local-data-upload-client-7HCPGIS3.js} +1 -1
  31. package/dist/{memory-62BJOULV.js → memory-VCYLVPMI.js} +6 -6
  32. package/dist/{metadata-7CUMWIB4.js → metadata-TIWIOFTU.js} +8 -8
  33. package/dist/{model-SBV2JFJI.js → model-DPJHSD73.js} +4 -4
  34. package/dist/{personal-semantic-preference-6SRCYPGE.js → personal-semantic-preference-SBKU2LOK.js} +6 -6
  35. package/dist/{project-semantic-YYEM4OSU.js → project-semantic-SKNWLH3I.js} +6 -6
  36. package/dist/{sync-SU33KYX7.js → sync-7PP6KQ75.js} +7 -7
  37. package/dist/{te-agent-F5QBZSQA.js → te-agent-L2BYNPHM.js} +753 -94
  38. package/dist/{te-analysis-U4I2W2WC.js → te-analysis-RJB6VJC4.js} +411 -79
  39. package/dist/{te-community-PFLDLPP4.js → te-community-QN3WMPNT.js} +6 -4
  40. package/dist/{te-dataops-FOQSRIAZ.js → te-dataops-UKD2XN3E.js} +8 -6
  41. package/dist/{te-engage-ZX76CNAB.js → te-engage-KPTN4N2U.js} +6 -6
  42. package/dist/{te-kb-MHDOST62.js → te-kb-SFZI3W5T.js} +7 -7
  43. package/dist/{te-system-J2FQF5ER.js → te-system-IE7NCKC3.js} +10 -9
  44. package/dist/{te-team-5UOZPTU3.js → te-team-4KHCFM2I.js} +63 -41
  45. package/dist/{things-VPPXXLHB.js → things-7JJUVAWL.js} +7 -7
  46. package/dist/{update-EEUTEI6R.js → update-AX66IFMJ.js} +4 -4
  47. package/dist/{workspace-O3EEIYQM.js → workspace-Q5NMEKEN.js} +6 -6
  48. package/package.json +11 -7
  49. package/skills/ae-agent/SKILL.md +22 -3
  50. package/skills/ae-agent/references/command_index.md +8 -0
  51. package/skills/ae-agent/references/resource-package.md +53 -0
  52. package/skills/ae-analysis/SKILL.md +12 -3
  53. package/skills/ae-analysis/references/adhoc_export.md +1 -1
  54. package/skills/ae-analysis/references/agent_review_preflight.md +4 -0
  55. package/skills/ae-analysis/references/agent_review_submit_to_page.md +4 -0
  56. package/skills/ae-analysis/references/ai_models/event.md +58 -2
  57. package/skills/ae-analysis/references/ai_models/rank_list.md +1 -0
  58. package/skills/ae-analysis/references/ai_models/retention.md +2 -0
  59. package/skills/ae-analysis/references/ai_models/revenue.md +2 -0
  60. package/skills/ae-analysis/references/analysis_data_export.md +11 -1
  61. package/skills/ae-analysis/references/asset_batch_info_export.md +2 -2
  62. package/skills/ae-analysis/references/asset_batch_sql_export.md +2 -2
  63. package/skills/ae-analysis/references/asset_export.md +1 -1
  64. package/skills/ae-analysis/references/bi_panel_page_data_export.md +1 -1
  65. package/skills/ae-analysis/references/check_export.md +1 -1
  66. package/skills/ae-analysis/references/command_index.md +34 -25
  67. package/skills/ae-analysis/references/dashboard_report_data_export.md +2 -0
  68. package/skills/ae-analysis/references/dashboard_report_get.md +6 -2
  69. package/skills/ae-analysis/references/dashboard_report_update.md +24 -5
  70. package/skills/ae-analysis/references/feedback_submit.md +1 -1
  71. package/skills/ae-analysis/references/governance_recommendation_export.md +10 -2
  72. package/skills/ae-analysis/references/live_data_export.md +1 -1
  73. package/skills/ae-analysis/references/metric_create.md +29 -0
  74. package/skills/ae-analysis/references/metric_get.md +2 -0
  75. package/skills/ae-analysis/references/metric_update.md +2 -0
  76. package/skills/ae-analysis/references/operation_record_export.md +1 -1
  77. package/skills/ae-analysis/references/plan_change_log_export.md +1 -1
  78. package/skills/ae-analysis/references/plan_export.md +1 -1
  79. package/skills/ae-analysis/references/project_info_get.md +4 -0
  80. package/skills/ae-analysis/references/project_member_group_add_members.md +35 -0
  81. package/skills/ae-analysis/references/project_member_group_create.md +25 -0
  82. package/skills/ae-analysis/references/project_member_group_delete.md +34 -0
  83. package/skills/ae-analysis/references/project_member_group_list.md +29 -0
  84. package/skills/ae-analysis/references/project_member_group_members.md +28 -0
  85. package/skills/ae-analysis/references/project_member_group_remove_members.md +35 -0
  86. package/skills/ae-analysis/references/project_member_group_rename.md +26 -0
  87. package/skills/ae-analysis/references/project_semantic_knowledge_wiki_plan_schema.md +6 -1
  88. package/skills/ae-analysis/references/report_data_export.md +1 -1
  89. package/skills/ae-analysis/references/scenario_append.md +25 -0
  90. package/skills/ae-analysis/references/scenario_collect.md +35 -0
  91. package/skills/ae-analysis/references/scenario_evaluation.md +30 -0
  92. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/build-project-semantic-wiki.mjs +73 -4
  93. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/default-compile-schema.md +5 -1
  94. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/execution-contract.mjs +173 -0
  95. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/generate-build-ir.mjs +109 -64
  96. package/skills/ae-automation/SKILL.md +2 -2
  97. package/skills/ae-automation/references/cli.md +18 -1
  98. package/skills/ae-capability/SKILL.md +7 -3
  99. package/skills/ae-evaluation/SKILL.md +83 -0
  100. package/skills/ae-evaluation/references/access-and-members.md +55 -0
  101. package/skills/ae-evaluation/references/connections.md +78 -0
  102. package/skills/ae-evaluation/references/datasets.md +57 -0
  103. package/skills/ae-evaluation/references/evaluators.md +81 -0
  104. package/skills/ae-evaluation/references/files.md +33 -0
  105. package/skills/ae-evaluation/references/integrations.md +39 -0
  106. package/skills/ae-evaluation/references/runs.md +160 -0
  107. package/skills/ae-evaluation/references/schedules.md +31 -0
  108. package/skills/ae-metadata/SKILL.md +2 -1
  109. package/skills/ae-metadata/references/metadata_data_table_download.md +7 -1
  110. package/skills/ae-metadata/references/metadata_data_table_get.md +2 -0
  111. package/skills/ae-team/SKILL.md +2 -2
  112. package/skills/ae-team/references/run-start.md +1 -0
  113. package/skills/ae-team/references/run-watch.md +7 -5
  114. package/skills/ae-things/SKILL.md +53 -51
  115. package/skills/ae-things/references/cli.md +56 -54
  116. package/skills/ae-things-progress/SKILL.md +20 -20
  117. package/skills/ae-things-review/SKILL.md +19 -19
  118. package/dist/chunk-4655PUNX.js +0 -43
@@ -11,7 +11,7 @@ import {
11
11
  workspaceResourcePath,
12
12
  workspaceTargetFlags,
13
13
  workspaceTargetPath
14
- } from "./chunk-HVHR4SCP.js";
14
+ } from "./chunk-UUD5RB36.js";
15
15
  import {
16
16
  currentAgentSpaceId
17
17
  } from "./chunk-RK6GLDGI.js";
@@ -19,24 +19,31 @@ import {
19
19
  deleteAgentApi,
20
20
  getAgentApi,
21
21
  getAgentBuffer,
22
+ isTransientResourcePackageError,
22
23
  patchAgentApi,
23
24
  postAgentApi,
24
25
  putAgentApi,
26
+ requestResourcePackageApi,
27
+ requestResourcePackageRaw,
28
+ resourcePackagePreflightChange,
25
29
  uploadAgentApi
26
- } from "./chunk-4655PUNX.js";
30
+ } from "./chunk-JJJIP2XQ.js";
27
31
  import {
32
+ TeAgentApiError,
28
33
  resolveTeClaudeBaseUrl
29
- } from "./chunk-PLE722AJ.js";
34
+ } from "./chunk-2UWS5CUP.js";
30
35
  import {
31
36
  buildCapabilityGatewayUrl,
32
37
  callCapabilityApi
33
- } from "./chunk-EOYSKMXN.js";
38
+ } from "./chunk-MXV3PYC3.js";
34
39
  import "./chunk-Y74WTIKJ.js";
35
- import "./chunk-GIK6EDUG.js";
36
- import "./chunk-UQ77JXYH.js";
40
+ import "./chunk-P7KL7IOH.js";
41
+ import {
42
+ getConfigDir
43
+ } from "./chunk-LMCYSVVA.js";
37
44
  import {
38
45
  CliValidationError
39
- } from "./chunk-WNGFSIOB.js";
46
+ } from "./chunk-ZW4VMY5H.js";
40
47
 
41
48
  // src/commands/te-agent/notifications.ts
42
49
  import { openSync, closeSync, fstatSync, readSync } from "fs";
@@ -44,14 +51,14 @@ import { openSync, closeSync, fstatSync, readSync } from "fs";
44
51
  // src/commands/te-agent/approval-cli-client.ts
45
52
  var APPROVAL_GATEWAY_DOMAIN = "approval";
46
53
  var resolveApprovalApiBaseUrl = resolveTeClaudeBaseUrl;
47
- function buildApprovalCliUrl(ctx, path) {
48
- return buildCapabilityGatewayUrl(resolveApprovalApiBaseUrl(ctx.host()), APPROVAL_GATEWAY_DOMAIN, path);
54
+ function buildApprovalCliUrl(ctx, path2) {
55
+ return buildCapabilityGatewayUrl(resolveApprovalApiBaseUrl(ctx.host()), APPROVAL_GATEWAY_DOMAIN, path2);
49
56
  }
50
- function requestApprovalCli(ctx, method, path, body, options = {}) {
57
+ function requestApprovalCli(ctx, method, path2, body, options = {}) {
51
58
  return callCapabilityApi(
52
59
  ctx.host(),
53
60
  APPROVAL_GATEWAY_DOMAIN,
54
- path,
61
+ path2,
55
62
  method,
56
63
  body,
57
64
  {
@@ -61,11 +68,11 @@ function requestApprovalCli(ctx, method, path, body, options = {}) {
61
68
  }
62
69
  );
63
70
  }
64
- function getApprovalCli(ctx, path) {
65
- return requestApprovalCli(ctx, "GET", path);
71
+ function getApprovalCli(ctx, path2) {
72
+ return requestApprovalCli(ctx, "GET", path2);
66
73
  }
67
- function postApprovalCli(ctx, path, body, options = {}) {
68
- return requestApprovalCli(ctx, "POST", path, body, options);
74
+ function postApprovalCli(ctx, path2, body, options = {}) {
75
+ return requestApprovalCli(ctx, "POST", path2, body, options);
69
76
  }
70
77
 
71
78
  // src/commands/te-agent/notifications.ts
@@ -204,7 +211,7 @@ function query(ctx, mode) {
204
211
  }
205
212
  return params.toString() ? `?${params}` : "";
206
213
  }
207
- function command(name, description, flags, method, path, body) {
214
+ function command(name, description, flags, method, path2, body) {
208
215
  return {
209
216
  service: "agent",
210
217
  resource: "notification",
@@ -214,7 +221,7 @@ function command(name, description, flags, method, path, body) {
214
221
  flags,
215
222
  risk: method === "GET" ? "read" : "write",
216
223
  validate(ctx) {
217
- path(ctx);
224
+ path2(ctx);
218
225
  body?.(ctx);
219
226
  },
220
227
  dryRun(ctx) {
@@ -224,7 +231,7 @@ function command(name, description, flags, method, path, body) {
224
231
  url: buildCapabilityGatewayUrl(
225
232
  resolveApprovalApiBaseUrl(ctx.host()),
226
233
  "agent",
227
- path(ctx)
234
+ path2(ctx)
228
235
  ),
229
236
  ...payload ? {
230
237
  body: name === "send" ? { ...payload, title: "[redacted]", body: "[redacted]" } : payload
@@ -235,7 +242,7 @@ function command(name, description, flags, method, path, body) {
235
242
  return callCapabilityApi(
236
243
  ctx.host(),
237
244
  "agent",
238
- path(ctx),
245
+ path2(ctx),
239
246
  method,
240
247
  body?.(ctx),
241
248
  {
@@ -355,9 +362,9 @@ var notificationCommands = [
355
362
  var BASE_PATH = "/api/sandbox/agent/agents";
356
363
  function buildQuery(ctx) {
357
364
  const params = new URLSearchParams();
358
- const scope = ctx.str("scope");
365
+ const scope2 = ctx.str("scope");
359
366
  const q = ctx.str("q");
360
- if (scope) params.set("scope", scope);
367
+ if (scope2) params.set("scope", scope2);
361
368
  if (q) params.set("q", q);
362
369
  const qs = params.toString();
363
370
  return qs ? `?${qs}` : "";
@@ -382,8 +389,8 @@ var listAgents = {
382
389
  ],
383
390
  risk: "read",
384
391
  validate: (ctx) => {
385
- const scope = ctx.str("scope");
386
- if (scope && !["personal", "company", "system"].includes(scope)) {
392
+ const scope2 = ctx.str("scope");
393
+ if (scope2 && !["personal", "company", "system"].includes(scope2)) {
387
394
  throw new Error("--scope \u5FC5\u987B\u662F personal\u3001company \u6216 system");
388
395
  }
389
396
  },
@@ -422,8 +429,8 @@ var createAgent = {
422
429
  if (!name || name.length < 1 || name.length > 100) {
423
430
  throw new Error("--name length must be between 1 and 100");
424
431
  }
425
- const scope = ctx.str("scope");
426
- if (scope && !["personal", "company"].includes(scope)) {
432
+ const scope2 = ctx.str("scope");
433
+ if (scope2 && !["personal", "company"].includes(scope2)) {
427
434
  throw new Error("--scope must be personal or company");
428
435
  }
429
436
  },
@@ -569,8 +576,8 @@ var getAgentContext = {
569
576
  ],
570
577
  risk: "read",
571
578
  validate: (ctx) => {
572
- const id = ctx.str("id");
573
- if (!id || id !== id.trim() || id.length > 191) {
579
+ const id2 = ctx.str("id");
580
+ if (!id2 || id2 !== id2.trim() || id2.length > 191) {
574
581
  throw new CliValidationError("--id must be a non-empty identifier of at most 191 characters");
575
582
  }
576
583
  },
@@ -601,11 +608,11 @@ function requireId(ctx, key, flag2) {
601
608
  }
602
609
  return value;
603
610
  }
604
- function url(ctx, path) {
605
- return buildCapabilityGatewayUrl(resolveApprovalApiBaseUrl(ctx.host()), "agent", path);
611
+ function url(ctx, path2) {
612
+ return buildCapabilityGatewayUrl(resolveApprovalApiBaseUrl(ctx.host()), "agent", path2);
606
613
  }
607
- function request(ctx, method, path, body) {
608
- return callCapabilityApi(ctx.host(), "agent", path, method, body, {
614
+ function request(ctx, method, path2, body) {
615
+ return callCapabilityApi(ctx.host(), "agent", path2, method, body, {
609
616
  apiBaseUrl: resolveApprovalApiBaseUrl(ctx.host()),
610
617
  retryOnInvalidTokenForbidden: false
611
618
  });
@@ -647,7 +654,7 @@ var expectedVersionFlag = {
647
654
  };
648
655
  function shareBody(ctx) {
649
656
  const recipients = ctx.json("toUserIds");
650
- if (!Array.isArray(recipients) || recipients.length < 1 || recipients.length > 50 || recipients.some((id) => typeof id !== "string" || !id || id.trim() !== id || id.length > 191) || new Set(recipients).size !== recipients.length) {
657
+ if (!Array.isArray(recipients) || recipients.length < 1 || recipients.length > 50 || recipients.some((id2) => typeof id2 !== "string" || !id2 || id2.trim() !== id2 || id2.length > 191) || new Set(recipients).size !== recipients.length) {
651
658
  throw new CliValidationError(
652
659
  "--to-user-ids must be a JSON array of 1-50 distinct non-empty user IDs"
653
660
  );
@@ -865,22 +872,22 @@ var listModels = {
865
872
  ],
866
873
  risk: "read",
867
874
  validate: (ctx) => {
868
- const scope = ctx.str("scope");
869
- if (scope && !["personal", "company", "system"].includes(scope)) {
875
+ const scope2 = ctx.str("scope");
876
+ if (scope2 && !["personal", "company", "system"].includes(scope2)) {
870
877
  throw new Error("--scope must be personal, company, or system");
871
878
  }
872
879
  },
873
880
  dryRun: (ctx) => {
874
- const scope = ctx.str("scope");
881
+ const scope2 = ctx.str("scope");
875
882
  const params = new URLSearchParams();
876
- if (scope) params.set("scope", scope);
883
+ if (scope2) params.set("scope", scope2);
877
884
  const qs = params.toString();
878
885
  return { method: "GET", url: `${BASE_PATH2}${qs ? `?${qs}` : ""}` };
879
886
  },
880
887
  execute: async (ctx) => {
881
- const scope = ctx.str("scope");
888
+ const scope2 = ctx.str("scope");
882
889
  const params = new URLSearchParams();
883
- if (scope) params.set("scope", scope);
890
+ if (scope2) params.set("scope", scope2);
884
891
  const qs = params.toString();
885
892
  const current = process.env.TE_AGENT_CURRENT_MODEL_ID?.trim();
886
893
  const data = await getAgentApi(
@@ -944,8 +951,8 @@ var addModel = {
944
951
  } catch {
945
952
  throw new Error("--base-url must be a valid URL");
946
953
  }
947
- const scope = ctx.str("scope");
948
- if (scope && !["personal", "company"].includes(scope)) {
954
+ const scope2 = ctx.str("scope");
955
+ if (scope2 && !["personal", "company"].includes(scope2)) {
949
956
  throw new Error("--scope must be personal or company");
950
957
  }
951
958
  },
@@ -997,19 +1004,19 @@ var delModel = {
997
1004
  ],
998
1005
  risk: "high-risk-write",
999
1006
  validate: (ctx) => {
1000
- const scope = ctx.str("scope");
1001
- if (scope && !["personal", "company"].includes(scope)) {
1007
+ const scope2 = ctx.str("scope");
1008
+ if (scope2 && !["personal", "company"].includes(scope2)) {
1002
1009
  throw new Error("--scope must be personal or company");
1003
1010
  }
1004
1011
  },
1005
1012
  dryRun: (ctx) => {
1006
- const scope = ctx.str("scope") || "personal";
1007
- const qs = `id=${encodeURIComponent(ctx.str("id"))}&scope=${encodeURIComponent(scope)}`;
1013
+ const scope2 = ctx.str("scope") || "personal";
1014
+ const qs = `id=${encodeURIComponent(ctx.str("id"))}&scope=${encodeURIComponent(scope2)}`;
1008
1015
  return { method: "DELETE", url: `${BASE_PATH2}?${qs}` };
1009
1016
  },
1010
1017
  execute: async (ctx) => {
1011
- const scope = ctx.str("scope") || "personal";
1012
- const qs = `id=${encodeURIComponent(ctx.str("id"))}&scope=${encodeURIComponent(scope)}`;
1018
+ const scope2 = ctx.str("scope") || "personal";
1019
+ const qs = `id=${encodeURIComponent(ctx.str("id"))}&scope=${encodeURIComponent(scope2)}`;
1013
1020
  return deleteAgentApi(ctx, `${BASE_PATH2}?${qs}`);
1014
1021
  }
1015
1022
  };
@@ -1069,8 +1076,8 @@ var updateModel = {
1069
1076
  } catch {
1070
1077
  throw new Error("--base-url must be a valid URL");
1071
1078
  }
1072
- const scope = ctx.str("scope");
1073
- if (scope && !["personal", "company"].includes(scope)) {
1079
+ const scope2 = ctx.str("scope");
1080
+ if (scope2 && !["personal", "company"].includes(scope2)) {
1074
1081
  throw new Error("--scope must be personal or company");
1075
1082
  }
1076
1083
  },
@@ -1144,8 +1151,8 @@ var testModel = {
1144
1151
  if (apiKey) body.apiKey = apiKey;
1145
1152
  const provider = ctx.str("provider");
1146
1153
  if (provider) body.provider = provider;
1147
- const id = ctx.str("id");
1148
- if (id) body.existingConfigId = id;
1154
+ const id2 = ctx.str("id");
1155
+ if (id2) body.existingConfigId = id2;
1149
1156
  return { method: "POST", url: `${BASE_PATH2}/test`, body };
1150
1157
  },
1151
1158
  execute: async (ctx) => {
@@ -1157,8 +1164,8 @@ var testModel = {
1157
1164
  if (apiKey) body.apiKey = apiKey;
1158
1165
  const provider = ctx.str("provider");
1159
1166
  if (provider) body.provider = provider;
1160
- const id = ctx.str("id");
1161
- if (id) body.existingConfigId = id;
1167
+ const id2 = ctx.str("id");
1168
+ if (id2) body.existingConfigId = id2;
1162
1169
  return postAgentApi(ctx, `${BASE_PATH2}/test`, body);
1163
1170
  }
1164
1171
  };
@@ -1220,19 +1227,19 @@ var listMcps = {
1220
1227
  ],
1221
1228
  risk: "read",
1222
1229
  validate: (ctx) => {
1223
- const scope = ctx.str("scope");
1224
- if (scope && !["personal", "company", "system"].includes(scope)) {
1230
+ const scope2 = ctx.str("scope");
1231
+ if (scope2 && !["personal", "company", "system"].includes(scope2)) {
1225
1232
  throw new Error("--scope must be personal, company, or system");
1226
1233
  }
1227
1234
  },
1228
1235
  dryRun: (ctx) => {
1229
- const scope = ctx.str("scope");
1230
- const qs = scope ? `?scope=${encodeURIComponent(scope)}` : "";
1236
+ const scope2 = ctx.str("scope");
1237
+ const qs = scope2 ? `?scope=${encodeURIComponent(scope2)}` : "";
1231
1238
  return { method: "GET", url: `${BASE_PATH3}${qs}` };
1232
1239
  },
1233
1240
  execute: async (ctx) => {
1234
- const scope = ctx.str("scope");
1235
- const qs = scope ? `?scope=${encodeURIComponent(scope)}` : "";
1241
+ const scope2 = ctx.str("scope");
1242
+ const qs = scope2 ? `?scope=${encodeURIComponent(scope2)}` : "";
1236
1243
  return getAgentApi(ctx, `${BASE_PATH3}${qs}`);
1237
1244
  }
1238
1245
  };
@@ -1277,8 +1284,8 @@ var addMcp = {
1277
1284
  if (category && !isValidMarketCategory(category)) {
1278
1285
  throw new Error(`--category must be one of: ${MARKET_CATEGORIES.join(", ")}`);
1279
1286
  }
1280
- const scope = ctx.str("scope");
1281
- if (scope && !["personal", "company"].includes(scope)) {
1287
+ const scope2 = ctx.str("scope");
1288
+ if (scope2 && !["personal", "company"].includes(scope2)) {
1282
1289
  throw new Error("--scope must be personal or company");
1283
1290
  }
1284
1291
  },
@@ -1306,11 +1313,11 @@ var addMcp = {
1306
1313
  headers: ctx.json("headers") || void 0,
1307
1314
  scope: ctx.str("scope") || "personal"
1308
1315
  });
1309
- const id = created?.item?.id;
1316
+ const id2 = created?.item?.id;
1310
1317
  const meta = buildMetaBody(ctx);
1311
- if (id && meta) {
1318
+ if (id2 && meta) {
1312
1319
  try {
1313
- await patchAgentApi(ctx, `${MARKET_BASE_PATH}/${encodeURIComponent(id)}/meta`, meta);
1320
+ await patchAgentApi(ctx, `${MARKET_BASE_PATH}/${encodeURIComponent(id2)}/meta`, meta);
1314
1321
  } catch (err) {
1315
1322
  process.stderr.write(`Warning: MCP created but meta update failed: ${err?.message ?? err}
1316
1323
  `);
@@ -1370,8 +1377,8 @@ var listMcpMarket = {
1370
1377
  ],
1371
1378
  risk: "read",
1372
1379
  validate: (ctx) => {
1373
- const scope = ctx.str("scope");
1374
- if (scope && !MARKET_SCOPES.includes(scope)) {
1380
+ const scope2 = ctx.str("scope");
1381
+ if (scope2 && !MARKET_SCOPES.includes(scope2)) {
1375
1382
  throw new Error(`--scope must be one of: ${MARKET_SCOPES.join(", ")}`);
1376
1383
  }
1377
1384
  const category = ctx.str("category");
@@ -1558,14 +1565,14 @@ var mcpAuthStart = {
1558
1565
  }
1559
1566
  );
1560
1567
  if (result?.authorizeUrl && (process.stderr.isTTY || process.stdout.isTTY)) {
1561
- const id = ctx.str("id");
1568
+ const id2 = ctx.str("id");
1562
1569
  process.stderr.write(
1563
1570
  `
1564
1571
  \u8BF7\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u4EE5\u4E0B URL \u5B8C\u6210\u6388\u6743\uFF1A
1565
1572
  ${result.authorizeUrl}
1566
1573
 
1567
1574
  \u6388\u6743\u5B8C\u6210\u540E\uFF0C\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u8F6E\u8BE2\u6388\u6743\u72B6\u6001\uFF1A
1568
- ae-cli agent +mcp-auth-status --id ${id}
1575
+ ae-cli agent +mcp-auth-status --id ${id2}
1569
1576
 
1570
1577
  `
1571
1578
  );
@@ -1752,19 +1759,19 @@ var listSkills = {
1752
1759
  ],
1753
1760
  risk: "read",
1754
1761
  validate: (ctx) => {
1755
- const scope = ctx.str("scope");
1756
- if (scope && !["personal", "company", "system"].includes(scope)) {
1762
+ const scope2 = ctx.str("scope");
1763
+ if (scope2 && !["personal", "company", "system"].includes(scope2)) {
1757
1764
  throw new Error("--scope must be personal, company, or system");
1758
1765
  }
1759
1766
  },
1760
1767
  dryRun: (ctx) => {
1761
- const scope = ctx.str("scope");
1762
- const qs = scope ? `?scope=${encodeURIComponent(scope)}` : "";
1768
+ const scope2 = ctx.str("scope");
1769
+ const qs = scope2 ? `?scope=${encodeURIComponent(scope2)}` : "";
1763
1770
  return { method: "GET", url: `${BASE_PATH4}${qs}` };
1764
1771
  },
1765
1772
  execute: async (ctx) => {
1766
- const scope = ctx.str("scope");
1767
- const qs = scope ? `?scope=${encodeURIComponent(scope)}` : "";
1773
+ const scope2 = ctx.str("scope");
1774
+ const qs = scope2 ? `?scope=${encodeURIComponent(scope2)}` : "";
1768
1775
  return getAgentApi(ctx, `${BASE_PATH4}${qs}`);
1769
1776
  }
1770
1777
  };
@@ -1839,8 +1846,8 @@ var addSkill = {
1839
1846
  if (category && !isValidMarketCategory(category)) {
1840
1847
  throw new Error(`--category must be one of: ${MARKET_CATEGORIES.join(", ")}`);
1841
1848
  }
1842
- const scope = ctx.str("scope");
1843
- if (scope && !["personal", "company"].includes(scope)) {
1849
+ const scope2 = ctx.str("scope");
1850
+ if (scope2 && !["personal", "company"].includes(scope2)) {
1844
1851
  throw new Error("--scope must be personal or company");
1845
1852
  }
1846
1853
  const version = ctx.str("version");
@@ -1869,11 +1876,11 @@ var addSkill = {
1869
1876
  scope: ctx.str("scope") || "personal",
1870
1877
  version: ctx.str("version") || void 0
1871
1878
  });
1872
- const id = created?.item?.id;
1879
+ const id2 = created?.item?.id;
1873
1880
  const meta = buildMetaBody2(ctx);
1874
- if (id && meta) {
1881
+ if (id2 && meta) {
1875
1882
  try {
1876
- await patchAgentApi(ctx, `${MARKET_BASE_PATH2}/${encodeURIComponent(id)}/meta`, meta);
1883
+ await patchAgentApi(ctx, `${MARKET_BASE_PATH2}/${encodeURIComponent(id2)}/meta`, meta);
1877
1884
  } catch (err) {
1878
1885
  process.stderr.write(`Warning: Skill created but meta update failed: ${err?.message ?? err}
1879
1886
  `);
@@ -1982,8 +1989,8 @@ var listSkillMarket = {
1982
1989
  ],
1983
1990
  risk: "read",
1984
1991
  validate: (ctx) => {
1985
- const scope = ctx.str("scope");
1986
- if (scope && !MARKET_SCOPES.includes(scope)) {
1992
+ const scope2 = ctx.str("scope");
1993
+ if (scope2 && !MARKET_SCOPES.includes(scope2)) {
1987
1994
  throw new Error(`--scope must be one of: ${MARKET_SCOPES.join(", ")}`);
1988
1995
  }
1989
1996
  const category = ctx.str("category");
@@ -2594,8 +2601,8 @@ var uploadSkill = {
2594
2601
  if (!existsSync(resolved)) throw new Error(`File not found: ${resolved}`);
2595
2602
  const ext = extname(resolved).toLowerCase();
2596
2603
  if (ext !== ".zip") throw new Error("--file must be a .zip file");
2597
- const scope = ctx.str("scope");
2598
- if (scope && !["personal", "company"].includes(scope)) {
2604
+ const scope2 = ctx.str("scope");
2605
+ if (scope2 && !["personal", "company"].includes(scope2)) {
2599
2606
  throw new Error("--scope must be personal or company");
2600
2607
  }
2601
2608
  const category = ctx.str("category");
@@ -2640,8 +2647,8 @@ var uploadSkill = {
2640
2647
  type: "application/zip"
2641
2648
  });
2642
2649
  fd.append("file", blob, fileName);
2643
- const scope = ctx.str("scope") || "personal";
2644
- fd.append("scope", scope);
2650
+ const scope2 = ctx.str("scope") || "personal";
2651
+ fd.append("scope", scope2);
2645
2652
  if (ctx.bool("autoRename")) fd.append("autoRename", "true");
2646
2653
  if (ctx.str("replaceSkillId")) fd.append("replaceSkillId", ctx.str("replaceSkillId"));
2647
2654
  if (ctx.str("category")) fd.append("category", ctx.str("category"));
@@ -3121,12 +3128,12 @@ function parseShim(filePath) {
3121
3128
  target: ""
3122
3129
  };
3123
3130
  try {
3124
- const stat = lstatSync(filePath);
3125
- if (!stat.isFile() || stat.isSymbolicLink()) return fallback;
3126
- const lines = readShimHeader(filePath, stat.size).split("\n").slice(0, 10);
3131
+ const stat2 = lstatSync(filePath);
3132
+ if (!stat2.isFile() || stat2.isSymbolicLink()) return fallback;
3133
+ const lines = readShimHeader(filePath, stat2.size).split("\n").slice(0, 10);
3127
3134
  const managed = lines.includes(`# ${SHIM_MARKER}`);
3128
3135
  if (!managed) return fallback;
3129
- if (stat.size > MAX_SHIM_BYTES) {
3136
+ if (stat2.size > MAX_SHIM_BYTES) {
3130
3137
  return { ...fallback, managed: true, reason: "shim exceeds size limit" };
3131
3138
  }
3132
3139
  const values = /* @__PURE__ */ new Map();
@@ -3578,17 +3585,17 @@ function validateLimit(ctx) {
3578
3585
  function isRecord(value) {
3579
3586
  return value !== null && typeof value === "object" && !Array.isArray(value);
3580
3587
  }
3581
- function validateSnakeCaseValue(value, path = "payload") {
3588
+ function validateSnakeCaseValue(value, path2 = "payload") {
3582
3589
  if (Array.isArray(value)) {
3583
- value.forEach((item, index) => validateSnakeCaseValue(item, `${path}[${index}]`));
3590
+ value.forEach((item, index) => validateSnakeCaseValue(item, `${path2}[${index}]`));
3584
3591
  return;
3585
3592
  }
3586
3593
  if (!isRecord(value)) return;
3587
3594
  for (const [key, child] of Object.entries(value)) {
3588
3595
  if (!/^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/.test(key)) {
3589
- validation(`--payload keys must use snake_case (invalid key at ${path})`);
3596
+ validation(`--payload keys must use snake_case (invalid key at ${path2})`);
3590
3597
  }
3591
- validateSnakeCaseValue(child, `${path}.${key}`);
3598
+ validateSnakeCaseValue(child, `${path2}.${key}`);
3592
3599
  }
3593
3600
  }
3594
3601
  function approvalPayload(ctx) {
@@ -4013,6 +4020,649 @@ var retryApprovalEffect = {
4013
4020
  )
4014
4021
  };
4015
4022
 
4023
+ // src/commands/te-agent/resource-packages.ts
4024
+ import { randomUUID as randomUUID2 } from "crypto";
4025
+ import { readFileSync as readFileSync3 } from "fs";
4026
+
4027
+ // src/commands/te-agent/resource-package-transfer.ts
4028
+ import { createHash, randomUUID } from "crypto";
4029
+ import { createReadStream, createWriteStream } from "fs";
4030
+ import { chmod, link, lstat, mkdir, open, readFile, rename, stat, unlink, writeFile } from "fs/promises";
4031
+ import path from "path";
4032
+ import { Readable } from "stream";
4033
+ import { pipeline } from "stream/promises";
4034
+ function stateDirectory() {
4035
+ return path.join(getConfigDir(), "transfers", "resource-packages");
4036
+ }
4037
+ async function ensureDirectory(directory) {
4038
+ await mkdir(directory, { recursive: true, mode: 448 });
4039
+ await chmod(directory, 448);
4040
+ }
4041
+ async function saveJson(filePath, data) {
4042
+ const temporary = `${filePath}.${process.pid}.tmp`;
4043
+ await writeFile(temporary, `${JSON.stringify(data)}
4044
+ `, { mode: 384 });
4045
+ await chmod(temporary, 384);
4046
+ await rename(temporary, filePath);
4047
+ }
4048
+ async function loadJson(filePath) {
4049
+ try {
4050
+ const info = await lstat(filePath);
4051
+ if (!info.isFile() || info.isSymbolicLink()) throw new Error(`Unsafe transfer metadata: ${filePath}`);
4052
+ return JSON.parse(await readFile(filePath, "utf8"));
4053
+ } catch (error) {
4054
+ if (error.code === "ENOENT") return void 0;
4055
+ throw new Error(`Invalid transfer metadata: ${filePath}`);
4056
+ }
4057
+ }
4058
+ async function removeFile(filePath) {
4059
+ try {
4060
+ await unlink(filePath);
4061
+ } catch (error) {
4062
+ if (error.code !== "ENOENT") throw error;
4063
+ }
4064
+ }
4065
+ function sameIdentity(left, right) {
4066
+ return left.size === right.size && left.mtimeMs === right.mtimeMs && left.dev === right.dev && left.ino === right.ino;
4067
+ }
4068
+ function statePath(directory, host, filePath, scope2) {
4069
+ const key = createHash("sha256").update(`${host}\0${filePath}\0${scope2}`).digest("hex");
4070
+ return path.join(directory, `upload-${key}.json`);
4071
+ }
4072
+ async function slice(filePath, offset, length) {
4073
+ const file = await open(filePath, "r");
4074
+ try {
4075
+ const bytes = Buffer.allocUnsafe(length);
4076
+ const result = await file.read(bytes, 0, length, offset);
4077
+ if (result.bytesRead !== length) throw new Error("The resource package file changed during upload");
4078
+ return bytes;
4079
+ } finally {
4080
+ await file.close();
4081
+ }
4082
+ }
4083
+ async function transientRetry(operation, maxAttempts) {
4084
+ for (let attempt = 0; ; attempt += 1) {
4085
+ try {
4086
+ return await operation();
4087
+ } catch (error) {
4088
+ const transient = isTransientResourcePackageError(error);
4089
+ if (!transient || attempt + 1 >= maxAttempts) throw error;
4090
+ await new Promise((resolve4) => setTimeout(resolve4, 250 * 2 ** attempt));
4091
+ }
4092
+ }
4093
+ }
4094
+ async function uploadPackage(ctx, input) {
4095
+ const absolute = path.resolve(input.filePath);
4096
+ const before = await lstat(absolute).catch(() => void 0);
4097
+ if (!before?.isFile() || before.isSymbolicLink() || before.size < 1 || path.extname(absolute).toLowerCase() !== ".zip") {
4098
+ throw new Error("--file must point to a non-empty regular .zip file");
4099
+ }
4100
+ const directory = input.stateRoot ?? stateDirectory();
4101
+ await ensureDirectory(directory);
4102
+ const savedPath = statePath(directory, ctx.host(), absolute, input.scope);
4103
+ let saved = await loadJson(savedPath);
4104
+ if (saved && (!sameIdentity(saved, before) || saved.host !== ctx.host() || saved.scope !== input.scope)) {
4105
+ await removeFile(savedPath);
4106
+ saved = void 0;
4107
+ }
4108
+ let upload;
4109
+ const candidate = input.uploadId || saved?.uploadId;
4110
+ if (candidate) {
4111
+ try {
4112
+ upload = await requestResourcePackageApi(
4113
+ ctx,
4114
+ "GET",
4115
+ `/api/resource-packages/uploads/${encodeURIComponent(candidate)}`
4116
+ );
4117
+ } catch (error) {
4118
+ if (input.uploadId || !(error instanceof TeAgentApiError) || error.status !== 404 && error.status !== 410 && error.code !== "UPLOAD_EXPIRED") throw error;
4119
+ await removeFile(savedPath);
4120
+ saved = void 0;
4121
+ }
4122
+ }
4123
+ if (upload && (upload.fileName !== path.basename(absolute) || upload.totalBytes !== before.size || upload.scope !== input.scope || !["uploading", "completed"].includes(upload.status))) {
4124
+ if (input.uploadId) throw new Error("--upload-id does not match the selected ZIP and scope");
4125
+ upload = void 0;
4126
+ await removeFile(savedPath);
4127
+ }
4128
+ if (!upload) {
4129
+ upload = await requestResourcePackageApi(ctx, "POST", "/api/resource-packages/uploads", {
4130
+ fileName: path.basename(absolute),
4131
+ totalBytes: before.size,
4132
+ scope: input.scope
4133
+ });
4134
+ }
4135
+ if (!upload) throw new Error("The service did not create an upload");
4136
+ const active = upload;
4137
+ if (saved?.requestKey && input.requestKey && saved.requestKey !== input.requestKey) {
4138
+ throw new Error("--request-key differs from the existing upload state; reuse its original key");
4139
+ }
4140
+ const requestKey = input.requestKey || saved?.requestKey || randomUUID();
4141
+ const trustedLocalState = Boolean(saved && saved.uploadId === active.id && sameIdentity(saved, before));
4142
+ const state = {
4143
+ version: 1,
4144
+ host: ctx.host(),
4145
+ filePath: absolute,
4146
+ scope: input.scope,
4147
+ uploadId: active.id,
4148
+ size: before.size,
4149
+ mtimeMs: before.mtimeMs,
4150
+ dev: before.dev,
4151
+ ino: before.ino,
4152
+ requestKey
4153
+ };
4154
+ await saveJson(savedPath, state);
4155
+ if (active.status === "uploading") {
4156
+ const limits = await requestResourcePackageApi(
4157
+ ctx,
4158
+ "GET",
4159
+ "/api/resource-packages/limits"
4160
+ );
4161
+ const concurrency = Math.max(1, Math.min(8, limits.desktopUploadConcurrency || 3));
4162
+ const maxAttempts = Math.max(1, Math.min(10, limits.uploadChunkRetries || 3));
4163
+ const done = new Set(active.parts ?? []);
4164
+ const pending = Array.from({ length: active.totalChunks }, (_, index) => index).filter((index) => !trustedLocalState || !done.has(index));
4165
+ let next = 0;
4166
+ await Promise.all(Array.from({ length: Math.min(concurrency, pending.length) }, async () => {
4167
+ while (next < pending.length) {
4168
+ const part = pending[next++];
4169
+ const offset = part * active.chunkBytes;
4170
+ const bytes = await slice(absolute, offset, Math.min(active.chunkBytes, before.size - offset));
4171
+ const digest = createHash("sha256").update(bytes).digest("hex");
4172
+ await transientRetry(async () => {
4173
+ const response = await requestResourcePackageRaw(
4174
+ ctx,
4175
+ "PUT",
4176
+ `/api/resource-packages/uploads/${encodeURIComponent(active.id)}/chunks/${part}`,
4177
+ {
4178
+ body: new Uint8Array(bytes),
4179
+ timeoutMs: 12e4,
4180
+ headers: {
4181
+ "Content-Type": "application/octet-stream",
4182
+ "Content-Length": String(bytes.length),
4183
+ "X-Chunk-Sha256": digest
4184
+ }
4185
+ }
4186
+ );
4187
+ await response.body?.cancel();
4188
+ }, maxAttempts);
4189
+ }
4190
+ }));
4191
+ }
4192
+ const after = await stat(absolute);
4193
+ if (!sameIdentity(before, after)) {
4194
+ throw new Error("The resource package file changed during upload; retry with the unchanged ZIP");
4195
+ }
4196
+ const completed = await requestResourcePackageApi(
4197
+ ctx,
4198
+ "POST",
4199
+ `/api/resource-packages/uploads/${encodeURIComponent(active.id)}/complete`,
4200
+ {}
4201
+ );
4202
+ return { completed, statePath: savedPath, requestKey };
4203
+ }
4204
+ async function clearUploadState(filePath) {
4205
+ await removeFile(filePath);
4206
+ }
4207
+ function artifactFileName(response) {
4208
+ const disposition = response.headers.get("content-disposition") || "";
4209
+ const encoded = disposition.match(/filename\*=UTF-8''([^;]+)/i)?.[1];
4210
+ if (encoded) {
4211
+ try {
4212
+ return path.basename(decodeURIComponent(encoded.trim()));
4213
+ } catch {
4214
+ return path.basename(encoded.trim());
4215
+ }
4216
+ }
4217
+ const ordinary = disposition.match(/filename="([^"]+)"/i)?.[1] ?? disposition.match(/filename=([^;]+)/i)?.[1];
4218
+ return ordinary ? path.basename(ordinary.trim()) : void 0;
4219
+ }
4220
+ async function fileHash(filePath) {
4221
+ const hash = createHash("sha256");
4222
+ for await (const chunk of createReadStream(filePath)) hash.update(chunk);
4223
+ return hash.digest("hex");
4224
+ }
4225
+ async function downloadArtifact(ctx, task, outputPath, timezone) {
4226
+ const query2 = timezone ? `?timezone=${encodeURIComponent(timezone)}` : "";
4227
+ const url2 = `/api/resource-packages/tasks/${encodeURIComponent(task.id)}/artifact${query2}`;
4228
+ const head = await requestResourcePackageRaw(ctx, "HEAD", url2);
4229
+ const totalBytes = Number(head.headers.get("content-length"));
4230
+ if (!Number.isSafeInteger(totalBytes) || totalBytes < 1) throw new Error("Artifact Content-Length is invalid");
4231
+ const etag = head.headers.get("etag") || "";
4232
+ const output = path.resolve(outputPath ?? artifactFileName(head) ?? `resource-package-${task.id}.zip`);
4233
+ try {
4234
+ await lstat(output);
4235
+ throw new Error(`Output file already exists: ${output}`);
4236
+ } catch (error) {
4237
+ if (error.code !== "ENOENT") throw error;
4238
+ }
4239
+ const partial = `${output}.part`;
4240
+ const metadataPath = `${partial}.json`;
4241
+ let offset = 0;
4242
+ try {
4243
+ const info2 = await lstat(partial);
4244
+ if (!info2.isFile() || info2.isSymbolicLink()) throw new Error(`Unsafe partial file: ${partial}`);
4245
+ const metadata = await loadJson(metadataPath);
4246
+ if (!etag || !metadata || metadata.host !== ctx.host() || metadata.taskId !== task.id || metadata.etag !== etag || metadata.totalBytes !== totalBytes || info2.size > totalBytes) {
4247
+ throw new Error(`Partial artifact cannot be resumed safely: ${partial}`);
4248
+ }
4249
+ offset = info2.size;
4250
+ } catch (error) {
4251
+ if (error.code !== "ENOENT") throw error;
4252
+ }
4253
+ if (offset === 0) {
4254
+ await saveJson(metadataPath, { version: 1, host: ctx.host(), taskId: task.id, etag, totalBytes });
4255
+ }
4256
+ if (offset < totalBytes) {
4257
+ const response = await requestResourcePackageRaw(ctx, "GET", url2, {
4258
+ headers: offset ? { Range: `bytes=${offset}-`, "If-Range": etag } : void 0,
4259
+ timeoutMs: 12e4
4260
+ });
4261
+ if (offset && response.status !== 206 || !offset && response.status !== 200) {
4262
+ throw new Error("Artifact server returned an unexpected range status");
4263
+ }
4264
+ if (etag && response.headers.get("etag") !== etag) throw new Error("Artifact changed while downloading");
4265
+ if (offset && response.headers.get("content-range") !== `bytes ${offset}-${totalBytes - 1}/${totalBytes}`) {
4266
+ throw new Error("Artifact server returned a mismatched Content-Range");
4267
+ }
4268
+ if (!response.body) throw new Error("Artifact response body is empty");
4269
+ await pipeline(
4270
+ Readable.fromWeb(response.body),
4271
+ createWriteStream(partial, { flags: offset ? "a" : "wx", mode: 384 })
4272
+ );
4273
+ }
4274
+ const info = await stat(partial);
4275
+ if (info.size !== totalBytes) throw new Error(`Artifact size mismatch: expected ${totalBytes}, got ${info.size}`);
4276
+ const sha256 = await fileHash(partial);
4277
+ if (!task.packageSha256 || !/^[a-f0-9]{64}$/.test(task.packageSha256)) {
4278
+ throw new Error("Export task does not provide a valid package SHA-256 for verification");
4279
+ }
4280
+ if (sha256 !== task.packageSha256) {
4281
+ throw new Error(`Artifact SHA-256 mismatch: expected ${task.packageSha256}, got ${sha256}`);
4282
+ }
4283
+ await link(partial, output);
4284
+ await removeFile(partial);
4285
+ await removeFile(metadataPath);
4286
+ return { path: output, bytes: totalBytes, sha256 };
4287
+ }
4288
+
4289
+ // src/commands/te-agent/resource-packages.ts
4290
+ var statuses = /* @__PURE__ */ new Set([
4291
+ "uploading",
4292
+ "preflighting",
4293
+ "ready",
4294
+ "queued",
4295
+ "running",
4296
+ "cancelling",
4297
+ "succeeded",
4298
+ "partially_succeeded",
4299
+ "failed",
4300
+ "cancelled",
4301
+ "cancel_failed"
4302
+ ]);
4303
+ var terminal = /* @__PURE__ */ new Set(["succeeded", "partially_succeeded", "failed", "cancelled", "cancel_failed"]);
4304
+ var resourceTypes = /* @__PURE__ */ new Set(["knowledge_base", "mcp", "skill", "agent", "team"]);
4305
+ var previewNote = "Dry-run previews the local request only; it does not check permissions or current resources.";
4306
+ function id(ctx, key, flag2) {
4307
+ const value = ctx.str(key);
4308
+ if (!value || value.trim() !== value || value.length > 191) {
4309
+ throw new CliValidationError(`--${flag2} must be a non-empty identifier of at most 191 characters`);
4310
+ }
4311
+ return value;
4312
+ }
4313
+ function scope(ctx) {
4314
+ const value = ctx.str("scope");
4315
+ if (value !== "personal" && value !== "company") {
4316
+ throw new CliValidationError("--scope must be personal or company");
4317
+ }
4318
+ return value;
4319
+ }
4320
+ function jsonSource(raw, flag2) {
4321
+ if (!raw) throw new CliValidationError(`--${flag2} is required`);
4322
+ try {
4323
+ const text = raw === "-" ? readFileSync3(0, "utf8") : raw.startsWith("@") ? readFileSync3(raw.slice(1), "utf8") : raw;
4324
+ return JSON.parse(text);
4325
+ } catch (error) {
4326
+ throw new CliValidationError(`--${flag2} must contain valid JSON, @file JSON, or - for stdin: ${error.message}`);
4327
+ }
4328
+ }
4329
+ function references(ctx, key) {
4330
+ const raw = ctx.str(key);
4331
+ if (!raw && key === "excluded") return [];
4332
+ const value = jsonSource(raw, key);
4333
+ const maximum = key === "roots" ? 500 : 2e3;
4334
+ if (!Array.isArray(value) || key === "roots" && !value.length || value.length > maximum || value.some((entry) => !entry || typeof entry !== "object" || Array.isArray(entry) || Object.keys(entry).sort().join(",") !== "sourceId,type" || !resourceTypes.has(entry.type) || typeof entry.sourceId !== "string" || !entry.sourceId || entry.sourceId.length > 191)) {
4335
+ throw new CliValidationError(`--${key} must be a JSON array of valid resource references (max ${maximum})`);
4336
+ }
4337
+ return value;
4338
+ }
4339
+ function stringArray(ctx, key, flag2) {
4340
+ const raw = ctx.str(key);
4341
+ if (!raw) return [];
4342
+ const value = jsonSource(raw, flag2);
4343
+ if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) {
4344
+ throw new CliValidationError(`--${flag2} must be a JSON string array`);
4345
+ }
4346
+ return value;
4347
+ }
4348
+ function replacementMap(ctx) {
4349
+ const raw = ctx.str("systemReplacements");
4350
+ if (!raw) return {};
4351
+ const value = jsonSource(raw, "system-replacements");
4352
+ if (!value || typeof value !== "object" || Array.isArray(value) || Object.entries(value).length > 500 || Object.entries(value).some(([key, target]) => !key || key.length > 64 || typeof target !== "string" || !target || target.length > 191)) {
4353
+ throw new CliValidationError("--system-replacements must be a JSON object of reference keys to target IDs");
4354
+ }
4355
+ return value;
4356
+ }
4357
+ function taskPath(ctx) {
4358
+ return `/api/resource-packages/tasks/${encodeURIComponent(id(ctx, "taskId", "task-id"))}`;
4359
+ }
4360
+ function waitSettings(ctx) {
4361
+ const seconds = ctx.optionalNum("waitTimeoutSeconds") ?? 1800;
4362
+ const pollMs = ctx.optionalNum("pollIntervalMs") ?? 1500;
4363
+ if (!Number.isInteger(seconds) || seconds < 1 || seconds > 86400) {
4364
+ throw new CliValidationError("--wait-timeout-seconds must be an integer from 1 to 86400");
4365
+ }
4366
+ if (!Number.isInteger(pollMs) || pollMs < 250 || pollMs > 6e4) {
4367
+ throw new CliValidationError("--poll-interval-ms must be an integer from 250 to 60000");
4368
+ }
4369
+ return { timeoutMs: seconds * 1e3, pollMs };
4370
+ }
4371
+ async function waitForTask(ctx, task) {
4372
+ const { timeoutMs, pollMs } = waitSettings(ctx);
4373
+ const deadline = Date.now() + timeoutMs;
4374
+ let current = task;
4375
+ while (!terminal.has(current.status)) {
4376
+ if (Date.now() >= deadline) return { task: current, timedOut: true };
4377
+ await new Promise((resolve4) => setTimeout(resolve4, pollMs));
4378
+ current = await requestResourcePackageApi(ctx, "GET", `/api/resource-packages/tasks/${encodeURIComponent(task.id)}`);
4379
+ }
4380
+ return { task: current, timedOut: false };
4381
+ }
4382
+ var taskIdFlag2 = { name: "task-id", type: "string", required: true, desc: "Resource package task ID" };
4383
+ var waitFlags = [
4384
+ { name: "no-wait", type: "boolean", desc: "Return after submission without polling" },
4385
+ { name: "wait-timeout-seconds", type: "number", desc: "Maximum poll duration in seconds (default: 1800)" },
4386
+ { name: "poll-interval-ms", type: "number", desc: "Poll interval from 250 to 60000 milliseconds (default: 1500)" }
4387
+ ];
4388
+ function listPath2(ctx) {
4389
+ const kind = ctx.str("kind");
4390
+ const selectedScope = ctx.str("scope");
4391
+ const status = ctx.str("status");
4392
+ if (kind && !["export", "import"].includes(kind)) throw new CliValidationError("--kind must be export or import");
4393
+ if (selectedScope && !["personal", "company"].includes(selectedScope)) throw new CliValidationError("--scope must be personal or company");
4394
+ if (status && !statuses.has(status)) throw new CliValidationError("--status is invalid");
4395
+ const page = ctx.optionalNum("page") ?? 1;
4396
+ const pageSize = ctx.optionalNum("pageSize") ?? 20;
4397
+ if (!Number.isSafeInteger(page) || page < 1) throw new CliValidationError("--page must be a positive integer");
4398
+ if (![20, 50, 100].includes(pageSize)) throw new CliValidationError("--page-size must be 20, 50, or 100");
4399
+ const query2 = new URLSearchParams();
4400
+ if (kind) query2.set("kind", kind);
4401
+ if (selectedScope) query2.set("scope", selectedScope);
4402
+ if (status) query2.set("status", status);
4403
+ query2.set("page", String(page));
4404
+ query2.set("pageSize", String(pageSize));
4405
+ return `/api/resource-packages/tasks?${query2}`;
4406
+ }
4407
+ var listResourcePackages = {
4408
+ service: "agent",
4409
+ resource: "resource-package",
4410
+ command: "list",
4411
+ description: "List personal and company resource package tasks",
4412
+ helpText: previewNote,
4413
+ flags: [
4414
+ { name: "kind", type: "string", desc: "Filter by export or import" },
4415
+ { name: "scope", type: "string", desc: "Filter by personal or company" },
4416
+ { name: "status", type: "string", desc: "Filter by task status" },
4417
+ { name: "page", type: "number", desc: "Page number (default: 1)" },
4418
+ { name: "page-size", type: "number", desc: "Page size: 20, 50, or 100 (default: 20)" }
4419
+ ],
4420
+ risk: "read",
4421
+ validate: (ctx) => {
4422
+ listPath2(ctx);
4423
+ },
4424
+ dryRun: (ctx) => ({ method: "GET", url: listPath2(ctx) }),
4425
+ execute: (ctx) => requestResourcePackageApi(ctx, "GET", listPath2(ctx))
4426
+ };
4427
+ var showResourcePackage = {
4428
+ service: "agent",
4429
+ resource: "resource-package",
4430
+ command: "show",
4431
+ description: "Show a resource package task and its item results",
4432
+ flags: [taskIdFlag2],
4433
+ risk: "read",
4434
+ validate: (ctx) => {
4435
+ taskPath(ctx);
4436
+ },
4437
+ dryRun: (ctx) => ({ method: "GET", url: taskPath(ctx) }),
4438
+ execute: (ctx) => requestResourcePackageApi(ctx, "GET", taskPath(ctx))
4439
+ };
4440
+ var previewResourcePackageExport = {
4441
+ service: "agent",
4442
+ resource: "resource-package",
4443
+ command: "export-preview",
4444
+ description: "Preview export resources and dependencies",
4445
+ helpText: previewNote,
4446
+ flags: [{ name: "roots", type: "string", required: true, desc: "JSON, @file, or stdin (-) array of resource references" }],
4447
+ risk: "read",
4448
+ validate: (ctx) => {
4449
+ references(ctx, "roots");
4450
+ },
4451
+ dryRun: (ctx) => ({ method: "POST", url: "/api/resource-packages/exports/preview", body: { roots: references(ctx, "roots") } }),
4452
+ execute: (ctx) => requestResourcePackageApi(ctx, "POST", "/api/resource-packages/exports/preview", { roots: references(ctx, "roots") })
4453
+ };
4454
+ function exportBody(ctx) {
4455
+ return {
4456
+ requestKey: ctx.str("requestKey") || randomUUID2(),
4457
+ kind: "export",
4458
+ scope: scope(ctx),
4459
+ payload: {
4460
+ roots: references(ctx, "roots"),
4461
+ excluded: references(ctx, "excluded"),
4462
+ ...ctx.str("fileNameBase") ? { fileNameBase: ctx.str("fileNameBase") } : {}
4463
+ }
4464
+ };
4465
+ }
4466
+ function validateExport(ctx) {
4467
+ exportBody(ctx);
4468
+ if (ctx.str("requestKey")) id(ctx, "requestKey", "request-key");
4469
+ const base = ctx.str("fileNameBase");
4470
+ if (base && (base.length > 160 || !/^[^\\/\x00-\x1f]+$/.test(base))) {
4471
+ throw new CliValidationError("--file-name-base must be a safe filename base of at most 160 characters");
4472
+ }
4473
+ if (ctx.bool("noWait") && ctx.str("output")) throw new CliValidationError("--no-wait cannot be combined with --output");
4474
+ if (!ctx.bool("noWait")) waitSettings(ctx);
4475
+ }
4476
+ var exportResourcePackage = {
4477
+ service: "agent",
4478
+ resource: "resource-package",
4479
+ command: "export",
4480
+ description: "Export a personal or company resource package and download the artifact",
4481
+ helpText: previewNote,
4482
+ flags: [
4483
+ { name: "scope", type: "string", required: true, desc: "Export scope: personal or company" },
4484
+ { name: "roots", type: "string", required: true, desc: "JSON, @file, or stdin (-) array of root resources" },
4485
+ { name: "excluded", type: "string", desc: "JSON or @file array of dependencies to exclude" },
4486
+ { name: "file-name-base", type: "string", desc: "Optional output ZIP base name" },
4487
+ { name: "request-key", type: "string", desc: "Optional idempotency key; reuse only for the same export" },
4488
+ { name: "output", type: "string", desc: "Local ZIP path; defaults to the artifact filename" },
4489
+ { name: "timezone", type: "string", desc: "IANA timezone for generated artifact filename (default: UTC)" },
4490
+ ...waitFlags
4491
+ ],
4492
+ risk: "write",
4493
+ validate: validateExport,
4494
+ preflight: validateExport,
4495
+ dryRun: (ctx) => ({ method: "POST", url: "/api/resource-packages/tasks", body: exportBody(ctx) }),
4496
+ execute: async (ctx) => {
4497
+ let task = await requestResourcePackageApi(ctx, "POST", "/api/resource-packages/tasks", exportBody(ctx));
4498
+ if (ctx.bool("noWait")) return { status: "submitted", task };
4499
+ const waited = await waitForTask(ctx, task);
4500
+ task = waited.task;
4501
+ if (waited.timedOut) return { status: "still_running", task };
4502
+ if (task.status !== "succeeded" || !task.artifactAvailable) return { status: "completed", task };
4503
+ const artifact = await downloadArtifact(ctx, task, ctx.str("output") || void 0, ctx.str("timezone") || void 0);
4504
+ return { status: "downloaded", task, artifact };
4505
+ }
4506
+ };
4507
+ function validateImport(ctx) {
4508
+ if (!ctx.str("file")) throw new CliValidationError("--file is required");
4509
+ scope(ctx);
4510
+ stringArray(ctx, "confirmations", "confirmations");
4511
+ replacementMap(ctx);
4512
+ if (ctx.str("uploadId")) id(ctx, "uploadId", "upload-id");
4513
+ if (ctx.str("requestKey")) id(ctx, "requestKey", "request-key");
4514
+ if (!ctx.bool("noWait")) waitSettings(ctx);
4515
+ }
4516
+ function reviewPreflight(preflight, replacements, confirmations) {
4517
+ const unresolvedBlockers = preflight.blockers.filter((item) => {
4518
+ if (item.code !== "CORE_SYSTEM_AGENT_UNRESOLVED" || !item.referenceKey) return true;
4519
+ const replacement = replacements[item.referenceKey];
4520
+ return !replacement || replacement !== "__skip_resource__" && !item.replacementCandidates?.some((candidate) => candidate.id === replacement);
4521
+ });
4522
+ const missingConfirmations = preflight.confirmations.filter((item) => !confirmations.includes(item.code));
4523
+ return { unresolvedBlockers, missingConfirmations };
4524
+ }
4525
+ var importResourcePackage = {
4526
+ service: "agent",
4527
+ resource: "resource-package",
4528
+ command: "import",
4529
+ description: "Upload, preflight, confirm, and import a resource package with resume support",
4530
+ flags: [
4531
+ { name: "file", type: "string", required: true, desc: "Path to a non-empty resource package ZIP" },
4532
+ { name: "scope", type: "string", required: true, desc: "Import scope: personal or company" },
4533
+ { name: "upload-id", type: "string", desc: "Explicit upload ID to resume" },
4534
+ { name: "request-key", type: "string", desc: "Optional idempotency key; reuse only for the same import" },
4535
+ { name: "confirmations", type: "string", desc: "JSON or @file array of required confirmation codes" },
4536
+ { name: "system-replacements", type: "string", desc: "JSON or @file mapping of reference keys to target IDs or __skip_resource__" },
4537
+ { name: "accept-warnings", type: "boolean", desc: "Accept all warnings from the current preflight snapshot" },
4538
+ { name: "allow-duplicate", type: "boolean", desc: "Allow a package previously imported successfully" },
4539
+ ...waitFlags
4540
+ ],
4541
+ risk: "write",
4542
+ validate: validateImport,
4543
+ preflight: validateImport,
4544
+ dryRun: (ctx) => ({ method: "WORKFLOW", url: "/api/resource-packages/uploads", body: {
4545
+ file: ctx.str("file"),
4546
+ scope: scope(ctx),
4547
+ resume: true,
4548
+ wait: !ctx.bool("noWait")
4549
+ } }),
4550
+ execute: async (ctx) => {
4551
+ const { completed, statePath: statePath2, requestKey } = await uploadPackage(ctx, {
4552
+ filePath: ctx.str("file"),
4553
+ scope: scope(ctx),
4554
+ uploadId: ctx.str("uploadId") || void 0,
4555
+ requestKey: ctx.str("requestKey") || void 0
4556
+ });
4557
+ const confirmations = stringArray(ctx, "confirmations", "confirmations");
4558
+ const replacements = replacementMap(ctx);
4559
+ const review = reviewPreflight(completed.preflight, replacements, confirmations);
4560
+ if (completed.duplicateImport && !ctx.bool("allowDuplicate") || completed.preflight.warnings.length && !ctx.bool("acceptWarnings") || review.unresolvedBlockers.length || review.missingConfirmations.length) {
4561
+ return {
4562
+ status: "review_required",
4563
+ uploadId: completed.uploadId,
4564
+ requestKey,
4565
+ duplicateImport: completed.duplicateImport,
4566
+ preflight: completed.preflight,
4567
+ ...review
4568
+ };
4569
+ }
4570
+ let task;
4571
+ try {
4572
+ task = await requestResourcePackageApi(
4573
+ ctx,
4574
+ "POST",
4575
+ `/api/resource-packages/uploads/${encodeURIComponent(completed.uploadId)}/confirm`,
4576
+ {
4577
+ requestKey,
4578
+ preflightSnapshotId: completed.preflight.snapshotId,
4579
+ confirmations,
4580
+ systemReplacements: replacements
4581
+ }
4582
+ );
4583
+ } catch (error) {
4584
+ const changed = resourcePackagePreflightChange(error);
4585
+ if (changed) return {
4586
+ status: "review_required",
4587
+ reason: "preflight_changed",
4588
+ uploadId: completed.uploadId,
4589
+ requestKey,
4590
+ preflight: changed
4591
+ };
4592
+ throw error;
4593
+ }
4594
+ await clearUploadState(statePath2);
4595
+ if (ctx.bool("noWait")) return { status: "submitted", task };
4596
+ const waited = await waitForTask(ctx, task);
4597
+ return { status: waited.timedOut ? "still_running" : "completed", task: waited.task };
4598
+ }
4599
+ };
4600
+ var downloadResourcePackageCommand = {
4601
+ service: "agent",
4602
+ resource: "resource-package",
4603
+ command: "download",
4604
+ description: "Download or resume a completed export artifact and verify its SHA-256",
4605
+ flags: [
4606
+ taskIdFlag2,
4607
+ { name: "output", type: "string", desc: "Local ZIP path; defaults to the artifact filename" },
4608
+ { name: "timezone", type: "string", desc: "IANA timezone for generated artifact filename (default: UTC)" }
4609
+ ],
4610
+ risk: "read",
4611
+ validate: (ctx) => {
4612
+ taskPath(ctx);
4613
+ },
4614
+ dryRun: (ctx) => ({ method: "GET", url: `${taskPath(ctx)}/artifact` }),
4615
+ execute: async (ctx) => {
4616
+ const task = await requestResourcePackageApi(ctx, "GET", taskPath(ctx));
4617
+ if (task.kind !== "export" || task.status !== "succeeded" || !task.artifactAvailable) {
4618
+ throw new Error("This task does not have an available export artifact");
4619
+ }
4620
+ return downloadArtifact(ctx, task, ctx.str("output") || void 0, ctx.str("timezone") || void 0);
4621
+ }
4622
+ };
4623
+ var cancelResourcePackage = {
4624
+ service: "agent",
4625
+ resource: "resource-package",
4626
+ command: "cancel",
4627
+ description: "Request cancellation of a running resource package task",
4628
+ flags: [taskIdFlag2],
4629
+ risk: "high-risk-write",
4630
+ validate: (ctx) => {
4631
+ taskPath(ctx);
4632
+ },
4633
+ dryRun: (ctx) => ({ method: "POST", url: `${taskPath(ctx)}/cancel` }),
4634
+ execute: (ctx) => requestResourcePackageApi(ctx, "POST", `${taskPath(ctx)}/cancel`, {})
4635
+ };
4636
+ var retryResourcePackage = {
4637
+ service: "agent",
4638
+ resource: "resource-package",
4639
+ command: "retry",
4640
+ description: "Retry a retryable failed resource package task",
4641
+ flags: [taskIdFlag2, ...waitFlags],
4642
+ risk: "write",
4643
+ validate: (ctx) => {
4644
+ taskPath(ctx);
4645
+ if (!ctx.bool("noWait")) waitSettings(ctx);
4646
+ },
4647
+ dryRun: (ctx) => ({ method: "POST", url: `${taskPath(ctx)}/retry` }),
4648
+ execute: async (ctx) => {
4649
+ const task = await requestResourcePackageApi(ctx, "POST", `${taskPath(ctx)}/retry`, {});
4650
+ if (ctx.bool("noWait")) return { status: "submitted", task };
4651
+ const waited = await waitForTask(ctx, task);
4652
+ return { status: waited.timedOut ? "still_running" : "completed", task: waited.task };
4653
+ }
4654
+ };
4655
+ var resourcePackageCommands = [
4656
+ listResourcePackages,
4657
+ showResourcePackage,
4658
+ previewResourcePackageExport,
4659
+ exportResourcePackage,
4660
+ importResourcePackage,
4661
+ downloadResourcePackageCommand,
4662
+ cancelResourcePackage,
4663
+ retryResourcePackage
4664
+ ];
4665
+
4016
4666
  // src/commands/te-agent/index.ts
4017
4667
  var commands = [
4018
4668
  ...notificationCommands,
@@ -4113,15 +4763,24 @@ var commands = [
4113
4763
  findArchivedConversations,
4114
4764
  restoreConversation,
4115
4765
  // Sandbox tools (local scan of /home/ta/.local/bin managed shims)
4116
- listSandboxTools
4766
+ listSandboxTools,
4767
+ ...resourcePackageCommands
4117
4768
  ];
4118
4769
  var te_agent_default = commands;
4119
4770
  export {
4771
+ cancelResourcePackage,
4120
4772
  te_agent_default as default,
4773
+ downloadResourcePackageCommand,
4774
+ exportResourcePackage,
4775
+ importResourcePackage,
4776
+ listResourcePackages,
4121
4777
  notificationGet,
4122
4778
  notificationList,
4123
4779
  notificationMarkRead,
4124
4780
  notificationRecipients,
4125
4781
  notificationSend,
4126
- notificationUnreadCount
4782
+ notificationUnreadCount,
4783
+ previewResourcePackageExport,
4784
+ retryResourcePackage,
4785
+ showResourcePackage
4127
4786
  };