@thinkingai/ae-cli 6.1.19 → 6.1.21

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 (370) hide show
  1. package/README.md +96 -38
  2. package/README.zh.md +96 -38
  3. package/dist/{auth-QPEVVBKT.js → auth-XZNXFRJS.js} +236 -127
  4. package/dist/{capability-ASI62I4A.js → capability-FYTU3X6L.js} +80 -37
  5. package/dist/{chunk-QL6R6TSK.js → chunk-4NRCTUZJ.js} +27045 -477
  6. package/dist/{chunk-JYMGHGCE.js → chunk-57RRFUEZ.js} +42 -15
  7. package/dist/chunk-6ZIQV5GW.js +26 -0
  8. package/dist/{chunk-KZ6ZHF5J.js → chunk-7FTTULED.js} +14 -14
  9. package/dist/chunk-7XGFSUOM.js +623 -0
  10. package/dist/chunk-CCS66K4K.js +155 -0
  11. package/dist/{chunk-B5HMQAOM.js → chunk-DVMLWQD4.js} +8 -186
  12. package/dist/{chunk-KEWVSO64.js → chunk-DX5CDO34.js} +28 -18
  13. package/dist/chunk-EQ255HKO.js +38248 -0
  14. package/dist/{chunk-6QK7SYYY.js → chunk-HBGADCKA.js} +29 -37
  15. package/dist/{chunk-GJXRF7Y6.js → chunk-HFGZGYCG.js} +54 -81
  16. package/dist/chunk-JOCDD4ON.js +15 -0
  17. package/dist/{chunk-TKHSULJT.js → chunk-KPQY44JQ.js} +6 -0
  18. package/dist/{chunk-FR2EDAQM.js → chunk-MAPZ7VB6.js} +90 -2
  19. package/dist/chunk-V2NUHPXF.js +196 -0
  20. package/dist/{chunk-S5PONFBM.js → chunk-VYXXOKYS.js} +9 -9
  21. package/dist/{community-report-client-6OL6GBQW.js → community-report-client-CU22W53K.js} +2 -4
  22. package/dist/{config-XNMACCKX.js → config-XO3LI3SA.js} +8 -9
  23. package/dist/context-IFJI3LIT.js +46 -0
  24. package/dist/{data-integration-4NZGZ45E.js → data-integration-HNGUKFIC.js} +55 -44
  25. package/dist/index.js +122 -112
  26. package/dist/{local-data-upload-client-EFHDLXFG.js → local-data-upload-client-GTRIT64F.js} +4 -5
  27. package/dist/{memory-HBJQ2GC5.js → memory-QGPSNCQS.js} +4 -6
  28. package/dist/{metadata-62EWBEIG.js → metadata-DI5BMYFU.js} +8 -10
  29. package/dist/{model-BHLJ2QMT.js → model-RNPQXIBI.js} +4 -6
  30. package/dist/{personal-semantic-preference-JBVMAI7L.js → personal-semantic-preference-5C3WUXFI.js} +11 -10
  31. package/dist/{project-semantic-BQ4MPUS5.js → project-semantic-3LF6Q6JZ.js} +29 -25
  32. package/dist/{sync-MUWPRM5I.js → sync-O45NXEQY.js} +7 -8
  33. package/dist/{te-agent-WQZTMEK4.js → te-agent-K5MSPNHJ.js} +393 -90
  34. package/dist/{te-analysis-MNCG65LU.js → te-analysis-AISWCOOZ.js} +1175 -377
  35. package/dist/{te-community-BNE6KREL.js → te-community-4OYU3BDA.js} +10 -33
  36. package/dist/{te-dataops-TXLKM2W6.js → te-dataops-NFIPB6FX.js} +19 -20
  37. package/dist/{te-engage-TPKLRVTL.js → te-engage-BAM3GBFX.js} +13 -15
  38. package/dist/{te-experiment-6BYKTCY7.js → te-experiment-GUTZXZ5Z.js} +132 -16
  39. package/dist/te-kb-3TS73NO6.js +1992 -0
  40. package/dist/{te-system-44LZJDTQ.js → te-system-STMHLS5J.js} +12 -9
  41. package/dist/{te-team-XMP47YXE.js → te-team-3I5AOX3N.js} +6 -8
  42. package/dist/{update-UODFOZ4P.js → update-RZXLPCRH.js} +7 -8
  43. package/package.json +29 -19
  44. package/skills/ae-agent/SKILL.md +30 -13
  45. package/skills/ae-agent/references/agent-distribution.md +94 -0
  46. package/skills/ae-agent/references/approval-request.md +4 -0
  47. package/skills/ae-agent/references/command_index.md +9 -2
  48. package/skills/ae-agent/references/create-automation.md +20 -2
  49. package/skills/ae-agent/references/get-agent-context.md +70 -0
  50. package/skills/ae-agent/references/list-automations.md +18 -3
  51. package/skills/ae-agent/references/list-mcp-credentials.md +1 -1
  52. package/skills/ae-agent/references/mcp-token.md +3 -3
  53. package/skills/ae-agent/references/set-mcp-credential.md +0 -1
  54. package/skills/ae-agent/references/update-automation.md +18 -0
  55. package/skills/ae-analysis/SKILL.md +101 -79
  56. package/skills/ae-analysis/references/adhoc_export.md +11 -18
  57. package/skills/ae-analysis/references/adhoc_run.md +17 -7
  58. package/skills/ae-analysis/references/agent_review_detail.md +11 -0
  59. package/skills/ae-analysis/references/agent_review_evidence.md +46 -0
  60. package/skills/ae-analysis/references/agent_review_list.md +9 -0
  61. package/skills/ae-analysis/references/agent_review_preflight.md +96 -0
  62. package/skills/ae-analysis/references/agent_review_priorities_comparisons.md +76 -0
  63. package/skills/ae-analysis/references/agent_review_records.md +9 -0
  64. package/skills/ae-analysis/references/agent_review_retry.md +12 -0
  65. package/skills/ae-analysis/references/agent_review_review.md +16 -0
  66. package/skills/ae-analysis/references/agent_review_submit_to_page.md +184 -0
  67. package/skills/ae-analysis/references/ai_models/attribution.md +29 -0
  68. package/skills/ae-analysis/references/ai_models/distribution.md +40 -0
  69. package/skills/ae-analysis/references/ai_models/event.md +108 -0
  70. package/skills/ae-analysis/references/ai_models/funnel.md +46 -0
  71. package/skills/ae-analysis/references/ai_models/heat_map.md +26 -0
  72. package/skills/ae-analysis/references/ai_models/interval.md +20 -0
  73. package/skills/ae-analysis/references/ai_models/path.md +38 -0
  74. package/skills/ae-analysis/references/ai_models/prop_analysis.md +39 -0
  75. package/skills/ae-analysis/references/ai_models/rank_list.md +25 -0
  76. package/skills/ae-analysis/references/ai_models/retention.md +70 -0
  77. package/skills/ae-analysis/references/ai_models/revenue.md +28 -0
  78. package/skills/ae-analysis/references/ai_models/sql.md +74 -0
  79. package/skills/ae-analysis/references/ai_models/tag.md +19 -0
  80. package/skills/ae-analysis/references/ai_models.md +32 -453
  81. package/skills/ae-analysis/references/alert_create.md +7 -7
  82. package/skills/ae-analysis/references/alert_delete.md +4 -6
  83. package/skills/ae-analysis/references/alert_detail_list.md +7 -9
  84. package/skills/ae-analysis/references/alert_get.md +5 -7
  85. package/skills/ae-analysis/references/alert_job_list.md +4 -6
  86. package/skills/ae-analysis/references/alert_list.md +6 -8
  87. package/skills/ae-analysis/references/alert_notice_config_list.md +4 -6
  88. package/skills/ae-analysis/references/alert_start.md +5 -7
  89. package/skills/ae-analysis/references/alert_stop.md +5 -7
  90. package/skills/ae-analysis/references/alert_update.md +8 -8
  91. package/skills/ae-analysis/references/analysis_data_export.md +72 -0
  92. package/skills/ae-analysis/references/analysis_data_retrieval.md +32 -196
  93. package/skills/ae-analysis/references/analysis_gateway_assets.md +23 -180
  94. package/skills/ae-analysis/references/analysis_interpretation.md +37 -17
  95. package/skills/ae-analysis/references/asset_abnormal_get.md +0 -1
  96. package/skills/ae-analysis/references/asset_abnormal_list.md +0 -1
  97. package/skills/ae-analysis/references/asset_authentication_export.md +4 -0
  98. package/skills/ae-analysis/references/asset_authentication_list.md +7 -1
  99. package/skills/ae-analysis/references/asset_authentication_update.md +5 -1
  100. package/skills/ae-analysis/references/asset_batch_dashboard_schedule_freeze.md +8 -6
  101. package/skills/ae-analysis/references/asset_batch_delete.md +6 -6
  102. package/skills/ae-analysis/references/asset_batch_disable_auto_backup.md +4 -5
  103. package/skills/ae-analysis/references/asset_batch_disable_auto_update.md +5 -6
  104. package/skills/ae-analysis/references/asset_batch_handover.md +4 -5
  105. package/skills/ae-analysis/references/asset_batch_info_export.md +4 -5
  106. package/skills/ae-analysis/references/asset_batch_sql_export.md +5 -6
  107. package/skills/ae-analysis/references/asset_dependency_list.md +4 -5
  108. package/skills/ae-analysis/references/asset_export.md +4 -5
  109. package/skills/ae-analysis/references/asset_impact_list.md +5 -9
  110. package/skills/ae-analysis/references/asset_lineage_get.md +5 -6
  111. package/skills/ae-analysis/references/asset_list.md +4 -5
  112. package/skills/ae-analysis/references/asset_query_history_list.md +4 -8
  113. package/skills/ae-analysis/references/asset_recent_list.md +0 -1
  114. package/skills/ae-analysis/references/asset_search.md +12 -9
  115. package/skills/ae-analysis/references/asset_url_get.md +3 -4
  116. package/skills/ae-analysis/references/bi_panel_copy.md +2 -2
  117. package/skills/ae-analysis/references/bi_panel_page_data_export.md +4 -12
  118. package/skills/ae-analysis/references/bi_panel_page_data_run.md +2 -0
  119. package/skills/ae-analysis/references/catalog_export.md +4 -17
  120. package/skills/ae-analysis/references/catalog_list.md +4 -4
  121. package/skills/ae-analysis/references/check_delete.md +5 -7
  122. package/skills/ae-analysis/references/check_export.md +11 -11
  123. package/skills/ae-analysis/references/check_get.md +8 -10
  124. package/skills/ae-analysis/references/check_list.md +4 -6
  125. package/skills/ae-analysis/references/check_retry.md +8 -10
  126. package/skills/ae-analysis/references/check_run.md +2 -4
  127. package/skills/ae-analysis/references/command_index.md +46 -28
  128. package/skills/ae-analysis/references/cross_source_config.md +84 -0
  129. package/skills/ae-analysis/references/dashboard_report_data_export.md +5 -13
  130. package/skills/ae-analysis/references/dashboard_report_data_run.md +1 -1
  131. package/skills/ae-analysis/references/dashboard_update.md +15 -4
  132. package/skills/ae-analysis/references/datatable_columns_get.md +0 -1
  133. package/skills/ae-analysis/references/datatable_influence_list.md +0 -1
  134. package/skills/ae-analysis/references/datatable_version_get.md +0 -1
  135. package/skills/ae-analysis/references/datatable_version_list.md +0 -1
  136. package/skills/ae-analysis/references/debug_device_add.md +1 -2
  137. package/skills/ae-analysis/references/drilldown_entities_export.md +3 -3
  138. package/skills/ae-analysis/references/drilldown_events_export.md +3 -2
  139. package/skills/ae-analysis/references/drilldown_user_events_export.md +2 -2
  140. package/skills/ae-analysis/references/entity_detail_export.md +3 -2
  141. package/skills/ae-analysis/references/entity_detail_run.md +1 -0
  142. package/skills/ae-analysis/references/event_blacklist_add.md +5 -7
  143. package/skills/ae-analysis/references/event_blacklist_list.md +4 -6
  144. package/skills/ae-analysis/references/event_blacklist_update.md +6 -8
  145. package/skills/ae-analysis/references/event_changelog_list.md +0 -1
  146. package/skills/ae-analysis/references/event_create.md +0 -1
  147. package/skills/ae-analysis/references/event_detail_export.md +3 -2
  148. package/skills/ae-analysis/references/event_detail_run.md +1 -0
  149. package/skills/ae-analysis/references/event_export.md +0 -1
  150. package/skills/ae-analysis/references/event_get.md +0 -1
  151. package/skills/ae-analysis/references/event_hide_update.md +0 -1
  152. package/skills/ae-analysis/references/event_influence_list.md +0 -1
  153. package/skills/ae-analysis/references/event_list.md +0 -1
  154. package/skills/ae-analysis/references/event_property_bundle_export.md +5 -14
  155. package/skills/ae-analysis/references/event_property_bundle_import.md +2 -6
  156. package/skills/ae-analysis/references/event_relation_update.md +0 -1
  157. package/skills/ae-analysis/references/event_update.md +0 -1
  158. package/skills/ae-analysis/references/exchange_config_update.md +0 -1
  159. package/skills/ae-analysis/references/exchange_rate_refresh.md +0 -1
  160. package/skills/ae-analysis/references/exchange_rule_list.md +0 -1
  161. package/skills/ae-analysis/references/exchange_rule_update.md +0 -1
  162. package/skills/ae-analysis/references/exchange_rule_validate.md +0 -1
  163. package/skills/ae-analysis/references/governance_recommendation_decisions.md +23 -0
  164. package/skills/ae-analysis/references/governance_recommendation_export.md +108 -0
  165. package/skills/ae-analysis/references/governance_recommendation_submit.md +41 -0
  166. package/skills/ae-analysis/references/history_tag_data_drilldown_export.md +4 -4
  167. package/skills/ae-analysis/references/history_tag_data_export.md +3 -3
  168. package/skills/ae-analysis/references/ingest_error_list.md +7 -9
  169. package/skills/ae-analysis/references/ingest_summary.md +6 -8
  170. package/skills/ae-analysis/references/live_data_export.md +10 -10
  171. package/skills/ae-analysis/references/live_data_list.md +7 -9
  172. package/skills/ae-analysis/references/metadata_resolution.md +78 -0
  173. package/skills/ae-analysis/references/metric_export.md +0 -1
  174. package/skills/ae-analysis/references/metric_get.md +0 -1
  175. package/skills/ae-analysis/references/metric_list.md +4 -5
  176. package/skills/ae-analysis/references/metric_update.md +0 -1
  177. package/skills/ae-analysis/references/operation_record_export.md +4 -5
  178. package/skills/ae-analysis/references/operation_record_list.md +4 -5
  179. package/skills/ae-analysis/references/personal_semantic_preference_list.md +18 -1
  180. package/skills/ae-analysis/references/plan_change_log_export.md +10 -10
  181. package/skills/ae-analysis/references/plan_change_log_list.md +4 -6
  182. package/skills/ae-analysis/references/plan_delete_items.md +2 -4
  183. package/skills/ae-analysis/references/plan_export.md +9 -9
  184. package/skills/ae-analysis/references/plan_generate.md +2 -4
  185. package/skills/ae-analysis/references/plan_get.md +4 -6
  186. package/skills/ae-analysis/references/plan_import_excel.md +6 -8
  187. package/skills/ae-analysis/references/plan_save_items.md +2 -4
  188. package/skills/ae-analysis/references/plan_sync_from_meta.md +4 -6
  189. package/skills/ae-analysis/references/project_access_detail_get.md +0 -1
  190. package/skills/ae-analysis/references/project_data_power_get.md +0 -1
  191. package/skills/ae-analysis/references/project_data_power_list.md +0 -1
  192. package/skills/ae-analysis/references/project_data_power_upsert.md +0 -1
  193. package/skills/ae-analysis/references/project_entity_create.md +0 -1
  194. package/skills/ae-analysis/references/project_entity_event_list.md +0 -1
  195. package/skills/ae-analysis/references/project_entity_get.md +0 -1
  196. package/skills/ae-analysis/references/project_entity_list.md +0 -1
  197. package/skills/ae-analysis/references/project_entity_update.md +0 -1
  198. package/skills/ae-analysis/references/project_function_list.md +0 -1
  199. package/skills/ae-analysis/references/project_info_get.md +0 -1
  200. package/skills/ae-analysis/references/project_info_list.md +0 -1
  201. package/skills/ae-analysis/references/project_info_update.md +0 -1
  202. package/skills/ae-analysis/references/project_mark_time_create.md +0 -1
  203. package/skills/ae-analysis/references/project_mark_time_list.md +0 -1
  204. package/skills/ae-analysis/references/project_mark_time_update.md +0 -1
  205. package/skills/ae-analysis/references/project_member_add.md +6 -5
  206. package/skills/ae-analysis/references/project_member_batch_update.md +0 -1
  207. package/skills/ae-analysis/references/project_member_candidate_list.md +4 -3
  208. package/skills/ae-analysis/references/project_member_handover_run.md +2 -3
  209. package/skills/ae-analysis/references/project_member_list.md +0 -1
  210. package/skills/ae-analysis/references/project_member_receiver_list.md +0 -1
  211. package/skills/ae-analysis/references/project_member_update.md +0 -1
  212. package/skills/ae-analysis/references/project_owner_update.md +0 -1
  213. package/skills/ae-analysis/references/project_permission_binding_list.md +0 -1
  214. package/skills/ae-analysis/references/project_role_function_list.md +0 -1
  215. package/skills/ae-analysis/references/project_role_get.md +0 -1
  216. package/skills/ae-analysis/references/project_role_list.md +0 -1
  217. package/skills/ae-analysis/references/project_role_upsert.md +32 -2
  218. package/skills/ae-analysis/references/project_role_user_list.md +0 -1
  219. package/skills/ae-analysis/references/project_semantic_knowledge_wiki.md +214 -0
  220. package/skills/ae-analysis/references/project_semantic_knowledge_wiki_plan_schema.md +93 -0
  221. package/skills/ae-analysis/references/project_timezone_get.md +0 -1
  222. package/skills/ae-analysis/references/project_timezone_overview.md +0 -1
  223. package/skills/ae-analysis/references/project_timezone_update.md +0 -1
  224. package/skills/ae-analysis/references/project_user_id_items_update.md +0 -1
  225. package/skills/ae-analysis/references/property_changelog_list.md +0 -1
  226. package/skills/ae-analysis/references/property_create.md +0 -1
  227. package/skills/ae-analysis/references/property_export.md +0 -1
  228. package/skills/ae-analysis/references/property_get.md +0 -1
  229. package/skills/ae-analysis/references/property_hide_update.md +0 -1
  230. package/skills/ae-analysis/references/property_influence_list.md +0 -1
  231. package/skills/ae-analysis/references/property_list.md +3 -4
  232. package/skills/ae-analysis/references/property_related_events.md +0 -1
  233. package/skills/ae-analysis/references/property_relation_update.md +0 -1
  234. package/skills/ae-analysis/references/property_update.md +0 -1
  235. package/skills/ae-analysis/references/report_create.md +4 -2
  236. package/skills/ae-analysis/references/report_data_export.md +11 -9
  237. package/skills/ae-analysis/references/report_data_run.md +14 -7
  238. package/skills/ae-analysis/references/report_get.md +5 -3
  239. package/skills/ae-analysis/references/report_list.md +2 -0
  240. package/skills/ae-analysis/references/report_update.md +5 -3
  241. package/skills/ae-analysis/references/rule_create.md +5 -6
  242. package/skills/ae-analysis/references/rule_delete.md +5 -5
  243. package/skills/ae-analysis/references/rule_list.md +3 -4
  244. package/skills/ae-analysis/references/rule_schema.md +3 -4
  245. package/skills/ae-analysis/references/rule_update.md +5 -6
  246. package/skills/ae-analysis/references/sdk_sample_generate.md +2 -4
  247. package/skills/ae-analysis/references/sql_table_columns.md +1 -1
  248. package/skills/ae-analysis/references/super_metadata_batch_create.md +1 -1
  249. package/skills/ae-analysis/references/super_metadata_batch_edit.md +1 -1
  250. package/skills/ae-analysis/references/system_member_add.md +1 -2
  251. package/skills/ae-analysis/references/system_member_status_update.md +1 -1
  252. package/skills/ae-analysis/references/system_ops_alert_contact_list.md +1 -1
  253. package/skills/ae-analysis/references/system_ops_alert_contact_test.md +0 -1
  254. package/skills/ae-analysis/references/system_query_monitor_overview.md +3 -3
  255. package/skills/ae-analysis/references/system_query_task_export.md +4 -14
  256. package/skills/ae-analysis/references/system_query_task_get.md +1 -1
  257. package/skills/ae-analysis/references/system_query_task_list.md +5 -6
  258. package/skills/ae-analysis/references/system_receiver_address_upsert.md +3 -3
  259. package/skills/ae-analysis/references/system_receiver_detection_get.md +1 -1
  260. package/skills/ae-analysis/references/system_third_party_login_disable.md +1 -1
  261. package/skills/ae-analysis/references/system_usage_trend_export.md +3 -12
  262. package/skills/ae-analysis/references/user_cluster_list.md +1 -1
  263. package/skills/ae-analysis/references/user_cluster_member_export.md +4 -4
  264. package/skills/ae-analysis/references/user_tag_create.md +23 -1
  265. package/skills/ae-analysis/references/user_tag_list.md +1 -1
  266. package/skills/ae-analysis/references/user_tag_member_export.md +4 -4
  267. package/skills/ae-analysis/references/user_tag_models.md +9 -1
  268. package/skills/ae-analysis/references/user_tag_update.md +14 -2
  269. package/skills/ae-analysis/references/virtual_event_create.md +10 -5
  270. package/skills/ae-analysis/references/virtual_event_get.md +0 -1
  271. package/skills/ae-analysis/references/virtual_property_create.md +0 -1
  272. package/skills/ae-analysis/references/virtual_property_sql_rule_update.md +0 -1
  273. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/build-project-semantic-wiki.mjs +1054 -0
  274. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/company-kb.mjs +112 -0
  275. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/default-compile-rules.md +30 -0
  276. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/generate-build-ir.mjs +2735 -0
  277. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/package-wiki-source-zip.mjs +376 -0
  278. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/plan-kb-source-sync.mjs +264 -0
  279. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/precompiled-source.mjs +49 -0
  280. package/skills/ae-analysis/scripts/project-semantic-knowledge-wiki/upload-kb-sources-concurrently.mjs +200 -0
  281. package/skills/ae-analysis/scripts/read_results.py +197 -0
  282. package/skills/ae-analysis-global/SKILL.md +1 -1
  283. package/skills/ae-capability/SKILL.md +1 -1
  284. package/skills/ae-community/SKILL.md +1 -1
  285. package/skills/ae-current-context/SKILL.md +53 -0
  286. package/skills/ae-data-integration/SKILL.md +6 -4
  287. package/skills/ae-data-integration/references/dimension-routing.md +36 -0
  288. package/skills/ae-data-integration/references/lark-bitable-source.md +288 -0
  289. package/skills/ae-data-integration/references/lark-sheet-source.md +130 -0
  290. package/skills/ae-data-integration/references/local-analysis.md +2 -0
  291. package/skills/ae-data-integration/references/manual-export-source.md +83 -0
  292. package/skills/ae-data-integration/references/reuse.md +2 -0
  293. package/skills/ae-data-integration/references/sink-upload.md +32 -0
  294. package/skills/ae-data-integration/references/source-inspect.md +1 -1
  295. package/skills/ae-data-integration/references/tracking-plan.md +5 -2
  296. package/skills/ae-data-integration/references/transform.md +1 -1
  297. package/skills/ae-data-integration/references/ue-mapping.md +7 -4
  298. package/skills/ae-data-integration/references/ue-routing.md +17 -1
  299. package/skills/ae-data-integration-helper/SKILL.md +5 -5
  300. package/skills/ae-data-integration-helper/references/android_sdk_faq.md +3 -3
  301. package/skills/ae-data-integration-helper/references/c_sdk_faq.md +3 -3
  302. package/skills/ae-data-integration-helper/references/cocoscreator_sdk_faq.md +1 -1
  303. package/skills/ae-data-integration-helper/references/cpp_server_sdk_faq.md +3 -3
  304. package/skills/ae-data-integration-helper/references/ios_sdk_faq.md +1 -1
  305. package/skills/ae-data-integration-helper/references/java_sdk_faq.md +3 -3
  306. package/skills/ae-data-integration-helper/references/javascript_sdk_faq.md +1 -1
  307. package/skills/ae-data-integration-helper/references/logbus2_guide.md +1 -1
  308. package/skills/ae-data-integration-helper/references/logbus2_parser_plugin.md +2 -2
  309. package/skills/ae-data-integration-helper/references/minigame_sdk_faq.md +2 -2
  310. package/skills/ae-data-integration-helper/references/miniprogram_sdk_faq.md +1 -1
  311. package/skills/ae-data-integration-helper/references/python_sdk_faq.md +2 -2
  312. package/skills/ae-data-integration-helper/references/restful_api_notes.md +2 -2
  313. package/skills/ae-data-integration-helper/references/sdk_log_guide.md +3 -3
  314. package/skills/ae-data-integration-helper/references/sdk_usage_notes.md +11 -11
  315. package/skills/ae-data-integration-helper/references/unity_sdk_faq.md +1 -1
  316. package/skills/ae-dataops/SKILL.md +1 -1
  317. package/skills/ae-engage/SKILL.md +4 -3
  318. package/skills/ae-engage/references/build-task-save-guide.md +3 -0
  319. package/skills/ae-engage/references/flow-metric-update.md +115 -1
  320. package/skills/ae-engage/references/save-flow.md +3 -0
  321. package/skills/ae-engage/references/save-task.md +21 -0
  322. package/skills/ae-engage/references/task-metric-update.md +151 -0
  323. package/skills/ae-experiment/SKILL.md +14 -7
  324. package/skills/ae-experiment/references/save_submit_external_experiment.md +52 -0
  325. package/skills/ae-experiment-design/SKILL.md +3 -3
  326. package/skills/ae-experiment-design/references/platform-operations.md +1 -1
  327. package/skills/ae-experiment-insight/SKILL.md +2 -2
  328. package/skills/ae-experiment-insight/references/platform-operations.md +1 -1
  329. package/skills/ae-generate-tracking-code/SKILL.md +2 -1
  330. package/skills/ae-generate-tracking-code/references/client-sdk-insert.md +1 -1
  331. package/skills/ae-generate-tracking-code/references/datax-config.md +1 -1
  332. package/skills/ae-generate-tracking-code/references/logbus-config.md +1 -1
  333. package/skills/ae-generate-tracking-code/references/modes.md +1 -1
  334. package/skills/ae-generate-tracking-code/references/server-sdk-insert.md +5 -5
  335. package/skills/ae-generate-tracking-code/references/snippet-delivery.md +3 -3
  336. package/skills/ae-generate-tracking-plan/SKILL.md +27 -15
  337. package/skills/ae-generate-tracking-plan/references/business-dimension-mapping.md +1 -1
  338. package/skills/ae-generate-tracking-plan/references/te-api.md +1 -0
  339. package/skills/ae-generate-tracking-plan/references/xlsx-schema.md +3 -2
  340. package/skills/ae-kb/SKILL.md +147 -37
  341. package/skills/ae-kb/references/analysis-workflow.md +292 -0
  342. package/skills/ae-kb/references/query-workflow.md +59 -29
  343. package/skills/ae-kb/references/source-mutations.md +95 -0
  344. package/skills/ae-kb/references/versions.md +46 -0
  345. package/skills/ae-kb-discovery/SKILL.md +5 -1
  346. package/skills/ae-metadata/SKILL.md +1 -1
  347. package/skills/ae-migrate-tracking-code/SKILL.md +195 -0
  348. package/skills/ae-migrate-tracking-code/references/ae-preset-properties.md +76 -0
  349. package/skills/ae-migrate-tracking-code/references/ir.md +167 -0
  350. package/skills/ae-migrate-tracking-code/references/mapping-framework.md +112 -0
  351. package/skills/ae-migrate-tracking-code/references/providers/README.md +58 -0
  352. package/skills/ae-migrate-tracking-code/references/providers/amplitude.md +208 -0
  353. package/skills/ae-migrate-tracking-code/references/providers/firebase.md +160 -0
  354. package/skills/ae-migrate-tracking-code/references/providers/ga4.md +92 -0
  355. package/skills/ae-migrate-tracking-code/references/providers/mixpanel.md +150 -0
  356. package/skills/ae-migrate-tracking-code/references/providers/sensors-data.md +146 -0
  357. package/skills/ae-project-semantic/SKILL.md +1 -1
  358. package/skills/ae-system/SKILL.md +5 -5
  359. package/skills/ae-team/SKILL.md +2 -2
  360. package/skills/ae-use-agent/SKILL.md +42 -0
  361. package/skills/ae-use-agent/references/local-agent.md +114 -0
  362. package/dist/auth-UMJAA72O.js +0 -15
  363. package/dist/chunk-533JK3YX.js +0 -72
  364. package/dist/chunk-DKEXH6Q5.js +0 -72
  365. package/dist/chunk-O6K2ODUE.js +0 -318
  366. package/dist/chunk-RWXIXOZG.js +0 -326
  367. package/dist/client-N7NGZUNI.js +0 -204
  368. package/dist/te-kb-BUD6N3NI.js +0 -1222
  369. package/skills/ae-agent/references/auto-provision-mcp-credentials.md +0 -57
  370. package/skills/ae-analysis/metadata_resolution.md +0 -184
@@ -0,0 +1,1992 @@
1
+ import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
+ import {
3
+ kbApi,
4
+ kbUpload
5
+ } from "./chunk-57RRFUEZ.js";
6
+ import {
7
+ TeAgentApiError
8
+ } from "./chunk-HBGADCKA.js";
9
+ import {
10
+ CapabilityGatewayError
11
+ } from "./chunk-HFGZGYCG.js";
12
+ import {
13
+ printError
14
+ } from "./chunk-DX5CDO34.js";
15
+ import "./chunk-Y74WTIKJ.js";
16
+ import "./chunk-7XGFSUOM.js";
17
+ import "./chunk-7FTTULED.js";
18
+ import {
19
+ CliValidationError,
20
+ PermissionError
21
+ } from "./chunk-MAPZ7VB6.js";
22
+
23
+ // src/commands/te-kb/target-scope.ts
24
+ function getExternalKnowledgeBaseTargetScope(ctx) {
25
+ const scope = ctx.str("scope").trim();
26
+ if (!scope) return void 0;
27
+ if (scope === "personal" || scope === "company") return scope;
28
+ throw new CliValidationError(
29
+ `Invalid --scope: ${scope}. Must be one of: personal | company`
30
+ );
31
+ }
32
+
33
+ // src/commands/te-kb/source-check-updates.ts
34
+ var API_PATH = "/agent/api/external/knowledge-bases/sources/check-updates";
35
+ function body(ctx) {
36
+ const scope = getExternalKnowledgeBaseTargetScope(ctx);
37
+ return { name: ctx.str("name").trim(), sourceId: ctx.str("id").trim(), ...scope ? { scope } : {} };
38
+ }
39
+ var sourceCheckUpdates = {
40
+ service: "kb",
41
+ resource: "source",
42
+ command: "check-updates",
43
+ risk: "write",
44
+ description: "Check one compiled Feishu URL source for updates using the scheduled detector. Marks changes without compiling. Existing pending changes are preserved; updated=0 does not prove identical content.",
45
+ flags: [
46
+ { name: "name", type: "string", required: true, minLength: 1, maxLength: 200, desc: "Knowledge base name" },
47
+ { name: "id", type: "string", required: true, minLength: 1, maxLength: 191, desc: "Stable Feishu source ID from kb +list-sources" },
48
+ { name: "scope", type: "string", desc: "Exact scope: personal | company (omit for personal then company lookup)" }
49
+ ],
50
+ validate: (ctx) => {
51
+ for (const [flag, max] of [["name", 200], ["id", 191]]) {
52
+ const value = ctx.str(flag).trim();
53
+ if (!value || value.length > max) throw new CliValidationError(`Invalid --${flag}: expected 1-${max} characters.`);
54
+ }
55
+ getExternalKnowledgeBaseTargetScope(ctx);
56
+ },
57
+ dryRun: (ctx) => ({ method: "POST", url: `${ctx.host().replace(/\/$/, "")}${API_PATH}`, body: body(ctx) }),
58
+ execute: async (ctx) => {
59
+ try {
60
+ return await kbApi(ctx, "POST", API_PATH, {}, body(ctx), { preserveErrorMetadata: true });
61
+ } catch (error) {
62
+ const hint = "Read kb +list-sources to confirm the current source state before retrying.";
63
+ if (error instanceof PermissionError) {
64
+ throw new PermissionError("Source write permission is required for this knowledge base.", error.code, "Request source write access; signing in again does not grant permission.");
65
+ }
66
+ if (error instanceof CapabilityGatewayError) {
67
+ const messages = {
68
+ INVALID_REQUEST: "Invalid source update-check parameters.",
69
+ KB_NOT_FOUND: "The knowledge base was not found or is not accessible.",
70
+ SOURCE_NOT_FOUND: "The source was not found in the selected knowledge base.",
71
+ SOURCE_NOT_FEISHU: "Only Feishu URL sources support update checks.",
72
+ SOURCE_NOT_COMPILED: "The source must finish compilation before checking for updates.",
73
+ SOURCE_CHECK_FAILED: "The Feishu source update check failed. Check server detection logs.",
74
+ SOURCE_CHECK_UNAVAILABLE: "The source changed or could not be selected for detection.",
75
+ SOURCE_CHECK_INTERNAL_ERROR: "The Feishu source update check could not complete."
76
+ };
77
+ throw new CapabilityGatewayError(messages[error.code ?? ""] ?? "The source update-check request failed.", error.code, error.httpStatus, hint, error.meta);
78
+ }
79
+ if (error instanceof Error && /[^\x00-\x7f]/.test(error.message)) {
80
+ error.message = "The source update-check request failed. Check credentials, rate limits and server logs.";
81
+ }
82
+ throw error;
83
+ }
84
+ }
85
+ };
86
+
87
+ // src/commands/te-kb/source-mutation.ts
88
+ import { promises as fs } from "fs";
89
+ import path from "path";
90
+ var API = "/agent/api/external/knowledge-bases";
91
+ var apiOptions = { preserveErrorMetadata: true };
92
+ var maxBytes = 50 * 1024 * 1024;
93
+ var fileExtensions = /* @__PURE__ */ new Set([".md", ".markdown", ".txt", ".csv", ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".svg"]);
94
+ var identityFlags = [
95
+ { name: "name", type: "string", required: true, desc: "Exact knowledge base name from kb +list" },
96
+ { name: "scope", type: "string", required: true, desc: "Exact knowledge base scope: personal or company" },
97
+ { name: "id", type: "string", required: true, desc: "Current stable source ID from kb +list-sources" }
98
+ ];
99
+ var typeFlag = { name: "source-type", type: "string", required: true, desc: "Current source type from kb +list-sources: file or zip" };
100
+ var revisionFlag = { name: "expected-revision", type: "number", required: true, min: 1, max: 2147483647, desc: "Current contentRevision from kb +list-sources; never automatically retry a conflict" };
101
+ var previewFlag = { name: "preview-id", type: "string", required: true, desc: "Exact previewId returned by ZIP replace or restore" };
102
+ function validateIdentity(ctx) {
103
+ for (const [flag, max] of [["name", 200], ["id", 191], ["preview-id", 191]]) {
104
+ const value = ctx.str(flag);
105
+ if ((flag !== "preview-id" || value) && (!value.trim() || value.length > max || /[\x00-\x1f\x7f]/.test(value))) {
106
+ throw new CliValidationError(`--${flag} must contain 1 to ${max} characters without control characters.`);
107
+ }
108
+ }
109
+ if (!["personal", "company"].includes(ctx.str("scope"))) throw new CliValidationError("--scope must be personal or company.");
110
+ }
111
+ function positiveInteger(ctx, flag) {
112
+ const value = ctx.num(flag);
113
+ if (!Number.isSafeInteger(value) || value < 1 || value > 2147483647) throw new CliValidationError(`--${flag} must be an integer from 1 to 2147483647.`);
114
+ }
115
+ function validateMutation(ctx) {
116
+ validateIdentity(ctx);
117
+ positiveInteger(ctx, "expected-revision");
118
+ if (!["file", "zip"].includes(ctx.str("source-type"))) throw new CliValidationError("--source-type must be file or zip; URL sources cannot be replaced or restored.");
119
+ }
120
+ function query(ctx) {
121
+ return { name: ctx.str("name").trim(), scope: ctx.str("scope") };
122
+ }
123
+ function sourceEndpoint(ctx, suffix) {
124
+ return `${API}/sources/${encodeURIComponent(ctx.str("id").trim())}/${suffix}`;
125
+ }
126
+ function previewEndpoint(ctx) {
127
+ return sourceEndpoint(ctx, `directory/previews/${encodeURIComponent(ctx.str("preview-id").trim())}`);
128
+ }
129
+ function dryRequest(ctx, method, endpoint2, body2) {
130
+ return { method, url: `${ctx.host().replace(/\/$/, "")}${endpoint2}`, params: query(ctx), ...body2 === void 0 ? {} : { body: body2 } };
131
+ }
132
+ async function replacementFile(ctx, read) {
133
+ const file = path.resolve(ctx.str("file"));
134
+ const extension = path.extname(file).toLowerCase();
135
+ if (ctx.str("source-type") === "zip" ? extension !== ".zip" : !fileExtensions.has(extension)) {
136
+ throw new CliValidationError("--file must be a ZIP for a ZIP source, or a supported non-ZIP file for a file source. File sources must keep their original format.");
137
+ }
138
+ const handle = await fs.open(file, "r");
139
+ try {
140
+ const stat = await handle.stat();
141
+ if (!stat.isFile() || stat.size > maxBytes) throw new CliValidationError("--file must be a regular file of at most 50 MB.");
142
+ const content = read ? await handle.readFile() : void 0;
143
+ if (content && content.length > maxBytes) throw new CliValidationError("--file exceeds 50 MB.");
144
+ return { file, filename: path.basename(file), sizeBytes: content?.length ?? stat.size, content };
145
+ } finally {
146
+ await handle.close();
147
+ }
148
+ }
149
+ function replaceEndpoint(ctx) {
150
+ return sourceEndpoint(ctx, ctx.str("source-type") === "zip" ? "directory/previews" : "raw");
151
+ }
152
+ function replaceFields(ctx) {
153
+ return { expectedRevision: ctx.num("expected-revision"), ...ctx.str("source-type") === "zip" ? { mode: "archive" } : {} };
154
+ }
155
+ var sourceReplace = {
156
+ service: "kb",
157
+ resource: "source",
158
+ command: "replace",
159
+ risk: "write",
160
+ description: "Replace a file source draft, or prepare a ZIP archive replacement preview. ZIP changes require source commit. Does not compile or publish.",
161
+ flags: [...identityFlags, typeFlag, revisionFlag, { name: "file", type: "string", required: true, desc: "Local replacement file, at most 50 MB; same format, different filename allowed" }],
162
+ validate: (ctx) => {
163
+ validateMutation(ctx);
164
+ if (!ctx.str("file").trim()) throw new CliValidationError("--file is required.");
165
+ },
166
+ dryRun: async (ctx) => {
167
+ const { file, filename, sizeBytes } = await replacementFile(ctx, false);
168
+ return { ...dryRequest(ctx, ctx.str("source-type") === "zip" ? "POST" : "PUT", replaceEndpoint(ctx), replaceFields(ctx)), multipart: { file, filename, sizeBytes, content: "<redacted>" } };
169
+ },
170
+ execute: async (ctx) => {
171
+ const file = await replacementFile(ctx, true);
172
+ const form = new FormData();
173
+ form.append("file", new Blob([new Uint8Array(file.content)]), file.filename);
174
+ for (const [key, value] of Object.entries(replaceFields(ctx))) form.append(key, String(value));
175
+ return kbUpload(ctx, replaceEndpoint(ctx), form, query(ctx), { ...apiOptions, method: ctx.str("source-type") === "zip" ? "POST" : "PUT" });
176
+ }
177
+ };
178
+ function restoreEndpoint(ctx) {
179
+ return `${API}/versions/${ctx.num("version")}/sources/${encodeURIComponent(ctx.str("id").trim())}/restore`;
180
+ }
181
+ function restoreBody(ctx) {
182
+ return { expectedRevision: ctx.num("expected-revision"), ...ctx.str("source-type") === "zip" ? ctx.str("path") ? { target: "file", path: ctx.str("path") } : { target: "source" } : {} };
183
+ }
184
+ var sourceRestore = {
185
+ service: "kb",
186
+ resource: "source",
187
+ command: "restore",
188
+ risk: "write",
189
+ description: "Restore one current source draft from a published version. File sources restore immediately; ZIP source or child restores return a preview. Does not roll back the whole knowledge base or publish.",
190
+ flags: [
191
+ ...identityFlags,
192
+ typeFlag,
193
+ revisionFlag,
194
+ { name: "version", type: "number", required: true, min: 1, max: 2147483647, desc: "Published version number from kb +versions; use the latest number to discard unpublished changes" },
195
+ { name: "path", type: "string", desc: "Optional exact historical ZIP child file path from kb +version-tree; omit to restore the entire ZIP source" }
196
+ ],
197
+ validate: (ctx) => {
198
+ validateMutation(ctx);
199
+ positiveInteger(ctx, "version");
200
+ const value = ctx.str("path");
201
+ if (value && (ctx.str("source-type") !== "zip" || value.length > 1024 || /[\\\x00-\x1f\x7f]/.test(value) || /^[A-Za-z]:/.test(value) || value.split("/").some((p) => !p || p === "." || p === ".."))) {
202
+ throw new CliValidationError("--path is only valid for a ZIP child and must be a normalized relative file path.");
203
+ }
204
+ },
205
+ dryRun: (ctx) => dryRequest(ctx, "POST", restoreEndpoint(ctx), restoreBody(ctx)),
206
+ execute: (ctx) => kbApi(ctx, "POST", restoreEndpoint(ctx), query(ctx), restoreBody(ctx), apiOptions)
207
+ };
208
+ var sourcePreview = {
209
+ service: "kb",
210
+ resource: "source",
211
+ command: "preview",
212
+ risk: "read",
213
+ description: "Read one page of a ZIP replacement or restore preview, including additions, modifications and deletions.",
214
+ flags: [
215
+ ...identityFlags,
216
+ previewFlag,
217
+ { name: "cursor", type: "string", desc: "Opaque nextCursor returned by the previous preview page" },
218
+ { name: "limit", type: "number", default: 100, min: 1, max: 200, desc: "Preview page size from 1 to 200" }
219
+ ],
220
+ validate: (ctx) => {
221
+ validateIdentity(ctx);
222
+ if (!Number.isInteger(ctx.num("limit")) || ctx.num("limit") < 1 || ctx.num("limit") > 200) throw new CliValidationError("--limit must be an integer from 1 to 200.");
223
+ if (ctx.str("cursor").length > 4096) throw new CliValidationError("--cursor must be at most 4096 characters.");
224
+ },
225
+ dryRun: (ctx) => ({ ...dryRequest(ctx, "GET", previewEndpoint(ctx)), params: { ...query(ctx), limit: ctx.num("limit"), ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {} } }),
226
+ execute: (ctx) => kbApi(ctx, "GET", previewEndpoint(ctx), { ...query(ctx), limit: ctx.num("limit"), ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {} }, void 0, apiOptions)
227
+ };
228
+ var sourceCommit = {
229
+ service: "kb",
230
+ resource: "source",
231
+ command: "commit",
232
+ risk: "high-risk-write",
233
+ description: "Confirm a reviewed ZIP replacement or restore preview. May delete missing files; changes only the draft. On uncertain outcome, inspect state before any retry.",
234
+ flags: [...identityFlags, previewFlag, revisionFlag],
235
+ validate: (ctx) => {
236
+ validateIdentity(ctx);
237
+ positiveInteger(ctx, "expected-revision");
238
+ },
239
+ dryRun: (ctx) => dryRequest(ctx, "POST", `${previewEndpoint(ctx)}/commit`, { expectedRevision: ctx.num("expected-revision"), confirmed: true }),
240
+ execute: (ctx) => kbApi(ctx, "POST", `${previewEndpoint(ctx)}/commit`, query(ctx), { expectedRevision: ctx.num("expected-revision"), confirmed: true }, apiOptions)
241
+ };
242
+ var sourceCancel = {
243
+ service: "kb",
244
+ resource: "source",
245
+ command: "cancel",
246
+ risk: "high-risk-write",
247
+ description: "Discard an uncommitted ZIP replacement or restore preview; leaves the source draft unchanged.",
248
+ flags: [...identityFlags, previewFlag],
249
+ validate: validateIdentity,
250
+ dryRun: (ctx) => dryRequest(ctx, "DELETE", previewEndpoint(ctx)),
251
+ execute: async (ctx) => {
252
+ await kbApi(ctx, "DELETE", previewEndpoint(ctx), query(ctx), void 0, { ...apiOptions, responseType: "empty" });
253
+ return { previewId: ctx.str("preview-id"), cancelled: true };
254
+ }
255
+ };
256
+
257
+ // src/commands/te-kb/add.ts
258
+ import { promises as fs2 } from "fs";
259
+ import * as path2 from "path";
260
+ import TurndownService from "turndown";
261
+ var API_PATH2 = "/agent/api/external/knowledge-bases/sources/upload";
262
+ var SUPPORTED_EXTENSIONS = /* @__PURE__ */ new Set([
263
+ ".zip",
264
+ ".md",
265
+ ".markdown",
266
+ ".txt",
267
+ ".csv",
268
+ ".pdf",
269
+ ".doc",
270
+ ".docx",
271
+ ".xls",
272
+ ".xlsx",
273
+ ".ppt",
274
+ ".pptx",
275
+ ".jpg",
276
+ ".jpeg",
277
+ ".png",
278
+ ".gif",
279
+ ".webp",
280
+ ".bmp",
281
+ ".svg"
282
+ ]);
283
+ function normalizeFilesInput(raw) {
284
+ if (!Array.isArray(raw)) {
285
+ throw new Error(`--files must be a JSON array of strings, e.g. '["./a.md","./docs","https://example.com/page"]'`);
286
+ }
287
+ const items = [];
288
+ for (const v of raw) {
289
+ if (typeof v !== "string") {
290
+ throw new Error(`--files entries must be strings (got: ${JSON.stringify(v)})`);
291
+ }
292
+ const trimmed = v.trim();
293
+ if (trimmed) items.push(trimmed);
294
+ }
295
+ return items;
296
+ }
297
+ function isUrl(s) {
298
+ return /^https?:\/\//i.test(s);
299
+ }
300
+ function classifyInput(item) {
301
+ return isUrl(item) ? "url" : "path";
302
+ }
303
+ function sanitizeFilename(name) {
304
+ const cleaned = name.replace(/[\\/:*?"<>|\s]+/g, "-").replace(/^-+|-+$/g, "");
305
+ return cleaned || "document";
306
+ }
307
+ function getMimeType(filename) {
308
+ const ext = path2.extname(filename).toLowerCase();
309
+ switch (ext) {
310
+ case ".zip":
311
+ return "application/zip";
312
+ case ".md":
313
+ case ".markdown":
314
+ return "text/markdown";
315
+ case ".txt":
316
+ return "text/plain";
317
+ case ".csv":
318
+ return "text/csv";
319
+ case ".pdf":
320
+ return "application/pdf";
321
+ case ".doc":
322
+ return "application/msword";
323
+ case ".docx":
324
+ return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
325
+ case ".xls":
326
+ return "application/vnd.ms-excel";
327
+ case ".xlsx":
328
+ return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
329
+ case ".ppt":
330
+ return "application/vnd.ms-powerpoint";
331
+ case ".pptx":
332
+ return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
333
+ case ".jpg":
334
+ case ".jpeg":
335
+ return "image/jpeg";
336
+ case ".png":
337
+ return "image/png";
338
+ case ".gif":
339
+ return "image/gif";
340
+ case ".webp":
341
+ return "image/webp";
342
+ case ".bmp":
343
+ return "image/bmp";
344
+ case ".svg":
345
+ return "image/svg+xml";
346
+ default:
347
+ return "application/octet-stream";
348
+ }
349
+ }
350
+ async function readLocalFile(filePath) {
351
+ const ext = path2.extname(filePath).toLowerCase();
352
+ if (!SUPPORTED_EXTENSIONS.has(ext)) {
353
+ throw new Error(`Unsupported file extension (${ext || "none"}): ${filePath}`);
354
+ }
355
+ const content = await fs2.readFile(filePath);
356
+ const filename = path2.basename(filePath);
357
+ return { filename, content, mimeType: getMimeType(filename), origin: "file", source: filePath };
358
+ }
359
+ async function readDirectory(dir) {
360
+ const entries = await fs2.readdir(dir, { withFileTypes: true });
361
+ const files = [];
362
+ for (const entry of entries) {
363
+ if (!entry.isFile()) continue;
364
+ const ext = path2.extname(entry.name).toLowerCase();
365
+ if (!SUPPORTED_EXTENSIONS.has(ext)) continue;
366
+ const full = path2.join(dir, entry.name);
367
+ const content = await fs2.readFile(full);
368
+ files.push({ filename: entry.name, content, mimeType: getMimeType(entry.name), origin: "dir", source: full });
369
+ }
370
+ if (files.length === 0) {
371
+ throw new Error(`No supported files found in directory: ${dir}`);
372
+ }
373
+ return files;
374
+ }
375
+ function deriveFilenameFromUrl(rawUrl) {
376
+ try {
377
+ const u = new URL(rawUrl);
378
+ const lastSeg = u.pathname.split("/").filter(Boolean).pop();
379
+ const base = lastSeg ? lastSeg.replace(/\.[^.]+$/, "") : u.hostname;
380
+ return `${sanitizeFilename(base)}.md`;
381
+ } catch {
382
+ return `${sanitizeFilename(rawUrl)}.md`;
383
+ }
384
+ }
385
+ async function fetchAsMarkdown(rawUrl) {
386
+ const resp = await fetch(rawUrl);
387
+ if (!resp.ok) {
388
+ throw new Error(`Failed to fetch ${rawUrl}: HTTP ${resp.status}`);
389
+ }
390
+ const html = await resp.text();
391
+ const turndown = new TurndownService({ headingStyle: "atx", codeBlockStyle: "fenced" });
392
+ const markdown = turndown.turndown(html);
393
+ return {
394
+ filename: deriveFilenameFromUrl(rawUrl),
395
+ content: markdown,
396
+ mimeType: "text/markdown",
397
+ origin: "url",
398
+ source: rawUrl
399
+ };
400
+ }
401
+ async function resolveLocalPath(p) {
402
+ const abs = path2.resolve(p);
403
+ let stat;
404
+ try {
405
+ stat = await fs2.stat(abs);
406
+ } catch {
407
+ throw new Error(`Path not found: ${p}`);
408
+ }
409
+ if (stat.isDirectory()) {
410
+ return readDirectory(abs);
411
+ }
412
+ if (stat.isFile()) {
413
+ return [await readLocalFile(abs)];
414
+ }
415
+ throw new Error(`Unsupported path (not file or directory): ${p}`);
416
+ }
417
+ async function collectFiles(ctx) {
418
+ const items = normalizeFilesInput(ctx.json("files"));
419
+ if (items.length === 0) {
420
+ throw new Error("--files must contain at least one entry");
421
+ }
422
+ const collected = [];
423
+ for (const item of items) {
424
+ if (classifyInput(item) === "url") {
425
+ collected.push(await fetchAsMarkdown(item));
426
+ } else {
427
+ collected.push(...await resolveLocalPath(item));
428
+ }
429
+ }
430
+ if (collected.length === 0) {
431
+ throw new Error("No supported files collected from the given inputs");
432
+ }
433
+ return dedupeByFilename(collected);
434
+ }
435
+ function dedupeByFilename(files) {
436
+ const used = /* @__PURE__ */ new Map();
437
+ return files.map((f) => {
438
+ const count = used.get(f.filename) ?? 0;
439
+ used.set(f.filename, count + 1);
440
+ if (count === 0) return f;
441
+ const ext = path2.extname(f.filename);
442
+ const stem = f.filename.slice(0, f.filename.length - ext.length);
443
+ return { ...f, filename: `${stem}-${count}${ext}` };
444
+ });
445
+ }
446
+ function buildForm(name, scope, files) {
447
+ const form = new FormData();
448
+ form.append("name", name);
449
+ if (scope) form.append("scope", scope);
450
+ for (const f of files) {
451
+ form.append("files", new Blob([f.content], { type: f.mimeType }), f.filename);
452
+ }
453
+ return form;
454
+ }
455
+ var add = {
456
+ service: "kb",
457
+ command: "+add",
458
+ description: "Upload sources to a knowledge. --files accepts a JSON array; each entry can be a supported file path, a directory path (supported files inside, non-recursive), or an http(s) URL (HTML auto-converted to markdown).",
459
+ flags: [
460
+ { name: "name", type: "string", required: true, desc: "Knowledge base name" },
461
+ { name: "scope", type: "string", required: false, desc: "Exact knowledge base scope: personal | company (omit for personal \u2192 company fallback)" },
462
+ {
463
+ name: "files",
464
+ type: "json",
465
+ required: true,
466
+ desc: `JSON array of strings. Each entry can be a supported file path, a directory path, or an http(s) URL. Example: '["./a.md","./docs","https://example.com/page"]'`
467
+ }
468
+ ],
469
+ risk: "write",
470
+ validate: (ctx) => {
471
+ getExternalKnowledgeBaseTargetScope(ctx);
472
+ normalizeFilesInput(ctx.json("files"));
473
+ },
474
+ dryRun: (ctx) => {
475
+ const items = normalizeFilesInput(ctx.json("files"));
476
+ const body2 = {
477
+ name: ctx.str("name")
478
+ };
479
+ const scope = getExternalKnowledgeBaseTargetScope(ctx);
480
+ if (scope) body2.scope = scope;
481
+ body2.files = items.map((item) => ({ value: item, type: classifyInput(item) }));
482
+ body2.contentType = "multipart/form-data";
483
+ return {
484
+ method: "POST",
485
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH2}`,
486
+ body: body2
487
+ };
488
+ },
489
+ execute: async (ctx) => {
490
+ const name = ctx.str("name");
491
+ const scope = getExternalKnowledgeBaseTargetScope(ctx);
492
+ const files = await collectFiles(ctx);
493
+ const form = buildForm(name, scope, files);
494
+ const result = await kbUpload(ctx, API_PATH2, form);
495
+ return {
496
+ uploaded: files.map((f) => ({ filename: f.filename, origin: f.origin, source: f.source })),
497
+ result
498
+ };
499
+ }
500
+ };
501
+
502
+ // src/commands/te-kb/compile.ts
503
+ var API_PATH3 = "/agent/api/external/knowledge-bases/compile";
504
+ var VALID_MODES = /* @__PURE__ */ new Set(["incremental", "full"]);
505
+ function getMode(ctx) {
506
+ const mode = ctx.str("mode") || "incremental";
507
+ if (!VALID_MODES.has(mode)) {
508
+ throw new Error(`Invalid --mode: ${mode}. Must be one of: incremental | full`);
509
+ }
510
+ return mode;
511
+ }
512
+ function buildBody(ctx) {
513
+ const body2 = {
514
+ name: ctx.str("name"),
515
+ mode: getMode(ctx)
516
+ };
517
+ const scope = getExternalKnowledgeBaseTargetScope(ctx);
518
+ if (scope) body2.scope = scope;
519
+ const model = ctx.str("model");
520
+ if (model) body2.model = model;
521
+ return body2;
522
+ }
523
+ var compile = {
524
+ service: "kb",
525
+ command: "+compile",
526
+ description: "Compile a knowledge.",
527
+ flags: [
528
+ { name: "name", type: "string", required: true, desc: "Knowledge base name" },
529
+ { name: "mode", type: "string", required: false, default: "incremental", desc: "Compile mode: incremental | full (default: incremental)" },
530
+ { name: "scope", type: "string", required: false, desc: "Exact knowledge base scope: personal | company (omit for personal \u2192 company fallback)" },
531
+ { name: "model", type: "string", required: false, desc: "Optional model reference: Model.id, legacy modelId, or modelId::scope" }
532
+ ],
533
+ risk: "write",
534
+ validate: (ctx) => {
535
+ getMode(ctx);
536
+ getExternalKnowledgeBaseTargetScope(ctx);
537
+ },
538
+ dryRun: (ctx) => ({
539
+ method: "POST",
540
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH3}`,
541
+ body: buildBody(ctx)
542
+ }),
543
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH3, {}, buildBody(ctx))
544
+ };
545
+
546
+ // src/commands/te-kb/remove.ts
547
+ var API_PATH4 = "/agent/api/external/knowledge-bases";
548
+ function buildBody2(ctx) {
549
+ const body2 = { name: ctx.str("name") };
550
+ const scope = getExternalKnowledgeBaseTargetScope(ctx);
551
+ if (scope) body2.scope = scope;
552
+ return body2;
553
+ }
554
+ var remove = {
555
+ service: "kb",
556
+ command: "+remove",
557
+ description: "Delete an entire knowledge.",
558
+ flags: [
559
+ { name: "name", type: "string", required: true, desc: "Knowledge base name to delete" },
560
+ { name: "scope", type: "string", required: false, desc: "Exact knowledge base scope: personal | company (omit for personal \u2192 company fallback)" }
561
+ ],
562
+ risk: "high-risk-write",
563
+ validate: (ctx) => {
564
+ getExternalKnowledgeBaseTargetScope(ctx);
565
+ },
566
+ dryRun: (ctx) => ({
567
+ method: "DELETE",
568
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH4}`,
569
+ body: buildBody2(ctx)
570
+ }),
571
+ execute: async (ctx) => kbApi(ctx, "DELETE", API_PATH4, {}, buildBody2(ctx))
572
+ };
573
+
574
+ // src/commands/te-kb/create.ts
575
+ var API_PATH5 = "/agent/api/external/knowledge-bases/create";
576
+ var VALID_SCOPES = /* @__PURE__ */ new Set(["personal", "company"]);
577
+ function getScope(ctx) {
578
+ const scope = ctx.str("scope") || "company";
579
+ validateScope(scope);
580
+ return scope;
581
+ }
582
+ function validateScope(scope) {
583
+ if (!VALID_SCOPES.has(scope)) {
584
+ throw new Error(`Invalid --scope: ${scope}. Must be one of: personal | company`);
585
+ }
586
+ }
587
+ function normalizeTags(raw) {
588
+ if (raw === void 0 || raw === null) return void 0;
589
+ if (!Array.isArray(raw)) {
590
+ throw new Error(`--tags must be a JSON array of strings, e.g. '["t1","t2"]'`);
591
+ }
592
+ const tags = [];
593
+ for (const v of raw) {
594
+ if (typeof v !== "string") {
595
+ throw new Error(`--tags entries must be strings (got: ${JSON.stringify(v)})`);
596
+ }
597
+ const t = v.trim();
598
+ if (t) tags.push(t);
599
+ }
600
+ return tags;
601
+ }
602
+ function buildBody3(ctx) {
603
+ const body2 = {
604
+ scope: getScope(ctx),
605
+ name: ctx.str("name")
606
+ };
607
+ const description = ctx.str("description");
608
+ if (description) body2.description = description;
609
+ const tags = normalizeTags(ctx.json("tags"));
610
+ if (tags && tags.length > 0) body2.tags = tags;
611
+ const projectId = ctx.str("project-id");
612
+ if (projectId) body2.projectId = projectId;
613
+ const projectName = ctx.str("project-name");
614
+ if (projectName) body2.projectName = projectName;
615
+ return body2;
616
+ }
617
+ var create = {
618
+ service: "kb",
619
+ command: "+new",
620
+ description: "Create a new knowledge.",
621
+ flags: [
622
+ { name: "scope", type: "string", required: false, default: "company", desc: "Knowledge base scope: personal | company (default: company)" },
623
+ { name: "name", type: "string", required: true, desc: "Knowledge base name (\u226430 chars, unique per scope)" },
624
+ { name: "description", type: "string", required: false, desc: "Optional description (\u2264200 chars)" },
625
+ { name: "tags", type: "json", required: false, desc: `Optional JSON array of tags (max 2, each \u226415 chars). Example: '["t1","t2"]'` },
626
+ { name: "project-id", type: "string", required: false, desc: "Optional project ID to bind" },
627
+ { name: "project-name", type: "string", required: false, desc: "Optional project display name" }
628
+ ],
629
+ risk: "write",
630
+ validate: (ctx) => {
631
+ getScope(ctx);
632
+ normalizeTags(ctx.json("tags"));
633
+ },
634
+ dryRun: (ctx) => ({
635
+ method: "POST",
636
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH5}`,
637
+ body: buildBody3(ctx)
638
+ }),
639
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH5, {}, buildBody3(ctx))
640
+ };
641
+
642
+ // src/commands/te-kb/rm-source.ts
643
+ var API_PATH6 = "/agent/api/external/knowledge-bases/sources";
644
+ function sourceSelector(ctx) {
645
+ const id = ctx.str("id").trim();
646
+ if (id) return { id };
647
+ const displayName = ctx.str("display-name").trim();
648
+ if (displayName) return { displayName };
649
+ throw new CliValidationError("One of --id or --display-name is required.");
650
+ }
651
+ function buildBody4(ctx) {
652
+ const body2 = {
653
+ name: ctx.str("name")
654
+ };
655
+ const scope = getExternalKnowledgeBaseTargetScope(ctx);
656
+ if (scope) body2.scope = scope;
657
+ return { ...body2, ...sourceSelector(ctx) };
658
+ }
659
+ var rmSource = {
660
+ service: "kb",
661
+ command: "+rm-source",
662
+ description: "Delete one source from a knowledge base by ID or exact display name.",
663
+ flags: [
664
+ { name: "name", type: "string", required: true, desc: "Knowledge base name (looked up personal \u2192 company)" },
665
+ { name: "scope", type: "string", required: false, desc: "Exact knowledge base scope: personal | company (omit for personal \u2192 company fallback)" },
666
+ { name: "id", type: "string", required: false, desc: "Source ID copied from +list-sources (preferred)" },
667
+ { name: "display-name", type: "string", required: false, desc: "Exact source display name for legacy compatibility" }
668
+ ],
669
+ risk: "high-risk-write",
670
+ validate: (ctx) => {
671
+ getExternalKnowledgeBaseTargetScope(ctx);
672
+ sourceSelector(ctx);
673
+ },
674
+ dryRun: (ctx) => ({
675
+ method: "DELETE",
676
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH6}`,
677
+ body: buildBody4(ctx)
678
+ }),
679
+ execute: async (ctx) => kbApi(ctx, "DELETE", API_PATH6, {}, buildBody4(ctx), {
680
+ preserveErrorMetadata: true
681
+ })
682
+ };
683
+
684
+ // src/commands/te-kb/schema.ts
685
+ import fs3 from "fs";
686
+ import path3 from "path";
687
+ var API_PATH7 = "/agent/api/external/knowledge-bases/schema";
688
+ var MAX_CUSTOM_INSTRUCTIONS_CHARS = 1e4;
689
+ function getCustomInstructions(ctx) {
690
+ const inline = ctx.str("custom-instructions");
691
+ const file = ctx.str("custom-instructions-file");
692
+ if (inline && file) {
693
+ throw new Error("Use either --custom-instructions or --custom-instructions-file, not both.");
694
+ }
695
+ const content = file ? fs3.readFileSync(path3.resolve(file), "utf8") : inline;
696
+ if (file && !content.trim()) {
697
+ throw new Error("--custom-instructions-file is empty.");
698
+ }
699
+ if ([...content].length > MAX_CUSTOM_INSTRUCTIONS_CHARS) {
700
+ throw new Error("Custom instructions exceed 10000 characters.");
701
+ }
702
+ return content;
703
+ }
704
+ function buildBody5(ctx) {
705
+ const body2 = {
706
+ name: ctx.str("name")
707
+ };
708
+ const scope = getExternalKnowledgeBaseTargetScope(ctx);
709
+ if (scope) body2.scope = scope;
710
+ if (ctx.bool("force")) body2.force = true;
711
+ const model = ctx.str("model");
712
+ if (model) body2.model = model;
713
+ const customInstructions = getCustomInstructions(ctx);
714
+ if (customInstructions) body2.customInstructions = customInstructions;
715
+ return body2;
716
+ }
717
+ async function executeSchema(ctx, api = kbApi) {
718
+ return api(ctx, "POST", API_PATH7, {}, buildBody5(ctx), {
719
+ preserveBusinessErrorCode: true
720
+ });
721
+ }
722
+ var schema = {
723
+ service: "kb",
724
+ command: "+schema",
725
+ description: "Generate the compile schema for a knowledge base via POST /agent/api/external/knowledge-bases/schema.",
726
+ flags: [
727
+ { name: "name", type: "string", required: true, desc: "Knowledge base name (looked up personal \u2192 company)" },
728
+ { name: "scope", type: "string", required: false, desc: "Exact knowledge base scope: personal | company (omit for personal \u2192 company fallback)" },
729
+ { name: "force", type: "boolean", required: false, desc: "Preempt generation even when status is `generating` (use only for stuck recovery)" },
730
+ { name: "model", type: "string", required: false, desc: "Optional model reference: Model.id, legacy modelId, or modelId::scope" },
731
+ {
732
+ name: "custom-instructions",
733
+ type: "string",
734
+ required: false,
735
+ sensitive: true,
736
+ desc: "Optional per-run instructions for generating this knowledge base schema"
737
+ },
738
+ {
739
+ name: "custom-instructions-file",
740
+ type: "string",
741
+ required: false,
742
+ sensitive: true,
743
+ desc: "Read optional per-run schema generation instructions from a UTF-8 text file"
744
+ }
745
+ ],
746
+ risk: "write",
747
+ validate: (ctx) => {
748
+ getExternalKnowledgeBaseTargetScope(ctx);
749
+ getCustomInstructions(ctx);
750
+ },
751
+ dryRun: (ctx) => ({
752
+ method: "POST",
753
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH7}`,
754
+ body: buildBody5(ctx)
755
+ }),
756
+ execute: executeSchema
757
+ };
758
+
759
+ // src/commands/te-kb/status.ts
760
+ var API_PATH8 = "/agent/api/external/knowledge-bases/status";
761
+ function buildBody6(ctx) {
762
+ const body2 = {
763
+ name: ctx.str("name")
764
+ };
765
+ const scope = getExternalKnowledgeBaseTargetScope(ctx);
766
+ if (scope) body2.scope = scope;
767
+ return body2;
768
+ }
769
+ var status = {
770
+ service: "kb",
771
+ command: "+status",
772
+ description: "Query knowledge base status.",
773
+ flags: [
774
+ { name: "name", type: "string", required: true, desc: "Knowledge base name" },
775
+ { name: "scope", type: "string", required: false, desc: "Exact knowledge base scope: personal | company (omit for personal \u2192 company fallback)" }
776
+ ],
777
+ risk: "read",
778
+ validate: (ctx) => {
779
+ getExternalKnowledgeBaseTargetScope(ctx);
780
+ },
781
+ dryRun: (ctx) => ({
782
+ method: "POST",
783
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH8}`,
784
+ body: buildBody6(ctx)
785
+ }),
786
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH8, {}, buildBody6(ctx))
787
+ };
788
+
789
+ // src/commands/te-kb/kb-index.ts
790
+ var API_PATH9 = "/agent/api/external/knowledge-bases/index";
791
+ function buildBody7(ctx) {
792
+ const body2 = {};
793
+ const sources = ctx.json("sources");
794
+ if (sources) body2.sources = sources;
795
+ const locale = ctx.str("locale");
796
+ if (locale) body2.locale = locale;
797
+ return body2;
798
+ }
799
+ var kbIndex = {
800
+ service: "kb",
801
+ command: "+index",
802
+ description: "List accessible knowledge bases and their index.md navigation maps via POST /agent/api/external/knowledge-bases/index. Call this first to see the layout, then use +grep to locate and +read to open pages.",
803
+ flags: [
804
+ {
805
+ name: "sources",
806
+ type: "json",
807
+ required: false,
808
+ desc: 'Optional JSON array of knowledge base refs to scope the index, e.g. [{"scope":"company","name":"engineering-handbook"}]. Omit to list all accessible knowledge bases.'
809
+ },
810
+ { name: "locale", type: "string", required: false, desc: "Optional locale: zh | en | ja | ko" }
811
+ ],
812
+ risk: "read",
813
+ dryRun: (ctx) => ({
814
+ method: "POST",
815
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH9}`,
816
+ body: buildBody7(ctx)
817
+ }),
818
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH9, {}, buildBody7(ctx))
819
+ };
820
+
821
+ // src/commands/te-kb/kb-list.ts
822
+ var API_PATH10 = "/agent/api/external/knowledge-bases/list";
823
+ var DEFAULT_BUILD_STATUS = "compiled";
824
+ var VALID_BUILD_STATUSES = ["idle", "pending", "compiling", "compiled", "failed"];
825
+ function getBuildStatus(ctx) {
826
+ return ctx.str("build-status") || DEFAULT_BUILD_STATUS;
827
+ }
828
+ function validateBuildStatus(ctx) {
829
+ const value = ctx.str("build-status");
830
+ if (value && !VALID_BUILD_STATUSES.includes(value)) {
831
+ printError(
832
+ "validation",
833
+ `Invalid --build-status: ${value}. Valid values: ${VALID_BUILD_STATUSES.join(" | ")} (omit to default to ${DEFAULT_BUILD_STATUS}).`
834
+ );
835
+ process.exit(1);
836
+ }
837
+ }
838
+ function buildBody8(ctx) {
839
+ const body2 = {
840
+ buildStatus: getBuildStatus(ctx)
841
+ };
842
+ const locale = ctx.str("locale");
843
+ if (locale) body2.locale = locale;
844
+ return body2;
845
+ }
846
+ var kbList = {
847
+ service: "kb",
848
+ command: "+list",
849
+ description: "List accessible knowledge bases via POST /agent/api/external/knowledge-bases/list. Filters by buildStatus (default: compiled). Returns KB metadata including buildStatus, without index.md navigation maps.",
850
+ flags: [
851
+ {
852
+ name: "build-status",
853
+ type: "string",
854
+ required: false,
855
+ default: DEFAULT_BUILD_STATUS,
856
+ desc: `Filter by knowledge base build status: ${VALID_BUILD_STATUSES.join(" | ")} (default: ${DEFAULT_BUILD_STATUS} when omitted)`
857
+ },
858
+ { name: "locale", type: "string", required: false, desc: "Optional locale: zh | en | ja | ko" }
859
+ ],
860
+ risk: "read",
861
+ validate: (ctx) => {
862
+ validateBuildStatus(ctx);
863
+ },
864
+ dryRun: (ctx) => ({
865
+ method: "POST",
866
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH10}`,
867
+ body: buildBody8(ctx)
868
+ }),
869
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH10, {}, buildBody8(ctx))
870
+ };
871
+
872
+ // src/commands/te-kb/list-sources.ts
873
+ var API_PATH11 = "/agent/api/external/knowledge-bases/sources";
874
+ var MAX_KNOWLEDGE_BASE_NAME_LENGTH = 200;
875
+ function knowledgeBaseName(ctx) {
876
+ return ctx.str("name").trim();
877
+ }
878
+ function buildUrl(ctx) {
879
+ const url2 = new URL(`${ctx.host().replace(/\/$/, "")}${API_PATH11}`);
880
+ url2.searchParams.set("name", knowledgeBaseName(ctx));
881
+ const scope = getExternalKnowledgeBaseTargetScope(ctx);
882
+ if (scope) url2.searchParams.set("scope", scope);
883
+ return url2.toString();
884
+ }
885
+ var listSources = {
886
+ service: "kb",
887
+ command: "+list-sources",
888
+ description: "List source metadata for a knowledge base via GET /agent/api/external/knowledge-bases/sources?name=<name>. Copy the stable source ID from this output before using +rm-source. Preserves deletionProjection, pendingDeletions (null means undetermined), and separate cleanup state.",
889
+ flags: [
890
+ {
891
+ name: "name",
892
+ type: "string",
893
+ required: true,
894
+ minLength: 1,
895
+ maxLength: MAX_KNOWLEDGE_BASE_NAME_LENGTH,
896
+ desc: "Knowledge base name"
897
+ },
898
+ {
899
+ name: "scope",
900
+ type: "string",
901
+ required: false,
902
+ desc: "Exact knowledge base scope: personal | company (omit for personal \u2192 company fallback)"
903
+ }
904
+ ],
905
+ risk: "read",
906
+ validate: (ctx) => {
907
+ const name = knowledgeBaseName(ctx);
908
+ if (!name) {
909
+ throw new CliValidationError("Invalid --name: must be non-empty.");
910
+ }
911
+ if (name.length > MAX_KNOWLEDGE_BASE_NAME_LENGTH) {
912
+ throw new CliValidationError(
913
+ `Invalid --name length: ${name.length}. Must be at most ${MAX_KNOWLEDGE_BASE_NAME_LENGTH} characters.`
914
+ );
915
+ }
916
+ getExternalKnowledgeBaseTargetScope(ctx);
917
+ },
918
+ dryRun: (ctx) => ({
919
+ method: "GET",
920
+ url: buildUrl(ctx)
921
+ }),
922
+ execute: async (ctx) => {
923
+ const params = { name: knowledgeBaseName(ctx) };
924
+ const scope = getExternalKnowledgeBaseTargetScope(ctx);
925
+ if (scope) params.scope = scope;
926
+ return kbApi(ctx, "GET", API_PATH11, params, void 0, {
927
+ preserveErrorMetadata: true,
928
+ retryUnauthorized: false
929
+ });
930
+ }
931
+ };
932
+
933
+ // src/commands/te-kb/kb-grep.ts
934
+ var API_PATH12 = "/agent/api/external/knowledge-bases/grep";
935
+ function buildBody9(ctx) {
936
+ const body2 = {
937
+ query: ctx.str("query"),
938
+ sources: ctx.json("sources"),
939
+ paths: ctx.json("paths")
940
+ };
941
+ const topK = ctx.optionalNum("top-k");
942
+ if (topK !== void 0) body2.topK = topK;
943
+ const locale = ctx.str("locale");
944
+ if (locale) body2.locale = locale;
945
+ return body2;
946
+ }
947
+ var kbGrep = {
948
+ service: "kb",
949
+ command: "+grep",
950
+ description: "Keyword-search knowledge base pages via POST /agent/api/external/knowledge-bases/grep. Returns a page-level results array: one entry per page with hitCount (full match count), pageKind (content/catalog), up to 4 sections previews (breadcrumb, sectionStartLine/sectionEndLine, text excerpt) and moreSections. Copy --paths from +index (wiki pages, module catalog pages, or subdirectories); read the matched section range with +read.",
951
+ flags: [
952
+ {
953
+ name: "query",
954
+ type: "string",
955
+ required: true,
956
+ alias: "q",
957
+ desc: "Keywords to search across the knowledge bases"
958
+ },
959
+ {
960
+ name: "sources",
961
+ type: "json",
962
+ required: true,
963
+ desc: 'JSON array of knowledge base refs, e.g. [{"scope":"company","name":"engineering-handbook"}]'
964
+ },
965
+ {
966
+ name: "paths",
967
+ type: "json",
968
+ required: true,
969
+ desc: 'JSON array of wiki pages or subdirectories copied from +index, e.g. ["wiki/sandbox.md"] or ["wiki/guides"]'
970
+ },
971
+ { name: "top-k", type: "number", required: false, min: 1, max: 50, desc: "Max number of pages to return (1-50, default 10)" },
972
+ { name: "locale", type: "string", required: false, desc: "Optional locale: zh | en | ja | ko" }
973
+ ],
974
+ risk: "read",
975
+ dryRun: (ctx) => ({
976
+ method: "POST",
977
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH12}`,
978
+ body: buildBody9(ctx)
979
+ }),
980
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH12, {}, buildBody9(ctx))
981
+ };
982
+
983
+ // src/commands/te-kb/kb-read.ts
984
+ var API_PATH13 = "/agent/api/external/knowledge-bases/read";
985
+ var VALID_EXPAND_MODES = /* @__PURE__ */ new Set(["block", "none"]);
986
+ var MAX_READ_LIMIT = 2e3;
987
+ function readExpand(ctx) {
988
+ const expand = ctx.str("expand").trim();
989
+ if (!expand) return void 0;
990
+ if (!VALID_EXPAND_MODES.has(expand)) {
991
+ throw new CliValidationError(
992
+ `Invalid --expand: ${expand}. Must be one of: block | none`
993
+ );
994
+ }
995
+ return expand;
996
+ }
997
+ function readLimit(ctx) {
998
+ const limit = ctx.optionalNum("limit");
999
+ if (limit === void 0) return void 0;
1000
+ if (!Number.isInteger(limit) || limit < 1 || limit > MAX_READ_LIMIT) {
1001
+ throw new CliValidationError(
1002
+ `Invalid --limit: ${limit}. Must be an integer from 1 to ${MAX_READ_LIMIT}`
1003
+ );
1004
+ }
1005
+ return limit;
1006
+ }
1007
+ function buildBody10(ctx) {
1008
+ const body2 = {
1009
+ source: ctx.json("source"),
1010
+ path: ctx.str("path")
1011
+ };
1012
+ const offset = ctx.optionalNum("offset");
1013
+ if (offset !== void 0) body2.offset = offset;
1014
+ const limit = ctx.optionalNum("limit");
1015
+ if (limit !== void 0) body2.limit = limit;
1016
+ const expand = readExpand(ctx);
1017
+ if (expand) body2.expand = expand;
1018
+ if (ctx.bool("outline")) body2.outline = true;
1019
+ const locale = ctx.str("locale");
1020
+ if (locale) body2.locale = locale;
1021
+ return body2;
1022
+ }
1023
+ var kbRead = {
1024
+ service: "kb",
1025
+ command: "+read",
1026
+ description: "Read a full knowledge base page (or a line window) via POST /agent/api/external/knowledge-bases/read. Use after +index / +grep locate a candidate page. Pass --outline to get only the page heading tree (no content) and pick a section to read.",
1027
+ flags: [
1028
+ {
1029
+ name: "source",
1030
+ type: "json",
1031
+ required: true,
1032
+ desc: 'Knowledge base ref pointing to exactly one base, e.g. {"scope":"company","name":"engineering-handbook"}'
1033
+ },
1034
+ {
1035
+ name: "path",
1036
+ type: "string",
1037
+ required: true,
1038
+ desc: "Page path relative to the knowledge base root, e.g. wiki/concepts/data-model.md or index.md"
1039
+ },
1040
+ { name: "offset", type: "number", required: false, min: 1, desc: "Start line (1-based integer). Omit to read from the beginning." },
1041
+ { name: "limit", type: "number", required: false, min: 1, max: MAX_READ_LIMIT, desc: "Max number of lines to return (1-2000)." },
1042
+ { name: "expand", type: "string", required: false, desc: "Read-window expansion mode: block | none (omit for the server default: block)" },
1043
+ {
1044
+ name: "outline",
1045
+ type: "boolean",
1046
+ required: false,
1047
+ desc: "Return only the page outline (headings with line numbers), no content. Use it to decide which section to read on long pages."
1048
+ },
1049
+ { name: "locale", type: "string", required: false, desc: "Optional locale: zh | en | ja | ko" }
1050
+ ],
1051
+ risk: "read",
1052
+ validate: (ctx) => {
1053
+ const offset = ctx.optionalNum("offset");
1054
+ if (offset !== void 0 && !Number.isInteger(offset)) {
1055
+ throw new CliValidationError("--offset must be an integer.");
1056
+ }
1057
+ readLimit(ctx);
1058
+ readExpand(ctx);
1059
+ },
1060
+ dryRun: (ctx) => ({
1061
+ method: "POST",
1062
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH13}`,
1063
+ body: buildBody10(ctx)
1064
+ }),
1065
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH13, {}, buildBody10(ctx))
1066
+ };
1067
+
1068
+ // src/commands/te-kb/ask-shared.ts
1069
+ var ASK_API_PATH = "/agent/api/external/knowledge-bases/ask";
1070
+ var ASK_POLL_INTERVAL_MS = 5e3;
1071
+ var ASK_POLL_TIMEOUT_MS = 10 * 60 * 1e3;
1072
+ var ASK_MAX_TRANSIENT_POLL_FAILURES = 3;
1073
+ function isTransientAskPollError(error) {
1074
+ if (error instanceof PermissionError) return false;
1075
+ if (error instanceof TypeError) return true;
1076
+ if (!(error instanceof Error)) return false;
1077
+ if (/KB MCP token auth failed|unauthorized|Invalid access token/i.test(error.message)) {
1078
+ return false;
1079
+ }
1080
+ return /fetch|network|socket|ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|timeout/i.test(
1081
+ error.message
1082
+ );
1083
+ }
1084
+ async function pollUntilSettled(getStatus, executionId, options = {}) {
1085
+ const intervalMs = options.intervalMs ?? ASK_POLL_INTERVAL_MS;
1086
+ const timeoutMs = options.timeoutMs ?? ASK_POLL_TIMEOUT_MS;
1087
+ const maxTransientFailures = options.maxTransientFailures ?? ASK_MAX_TRANSIENT_POLL_FAILURES;
1088
+ const now = options.now ?? Date.now;
1089
+ const sleep = options.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)));
1090
+ const startTime = now();
1091
+ let transientFailures = 0;
1092
+ while (true) {
1093
+ const elapsed = now() - startTime;
1094
+ if (elapsed > timeoutMs) {
1095
+ throw new Error(
1096
+ `Ask execution timeout after ${Math.floor(elapsed / 1e3)} seconds (executionId: ${executionId})`
1097
+ );
1098
+ }
1099
+ let response;
1100
+ try {
1101
+ response = await getStatus(executionId);
1102
+ transientFailures = 0;
1103
+ } catch (err) {
1104
+ if (!isTransientAskPollError(err) || ++transientFailures >= maxTransientFailures) {
1105
+ throw err;
1106
+ }
1107
+ await sleep(intervalMs);
1108
+ continue;
1109
+ }
1110
+ if (response.status !== "running") {
1111
+ return response;
1112
+ }
1113
+ await sleep(intervalMs);
1114
+ }
1115
+ }
1116
+ function transformCompletedResponse(response) {
1117
+ const result = {
1118
+ executionId: response.executionId,
1119
+ answer: response.answer ?? "",
1120
+ sources: response.sources ?? []
1121
+ };
1122
+ if (response.modelId !== void 0) result.modelId = response.modelId;
1123
+ if (response.modelUsage !== void 0) result.modelUsage = response.modelUsage;
1124
+ if (response.toolCallCount !== void 0) result.toolCallCount = response.toolCallCount;
1125
+ return result;
1126
+ }
1127
+
1128
+ // src/commands/te-kb/ask.ts
1129
+ var VALID_LOCALES = /* @__PURE__ */ new Set(["zh", "en", "ja", "ko"]);
1130
+ var MIN_QUESTION_LEN = 1;
1131
+ var MAX_QUESTION_LEN = 2e3;
1132
+ function validateQuestion(question) {
1133
+ const len = question.length;
1134
+ if (len < MIN_QUESTION_LEN || len > MAX_QUESTION_LEN) {
1135
+ throw new Error(
1136
+ `Invalid --question length: ${len}. Must be between ${MIN_QUESTION_LEN} and ${MAX_QUESTION_LEN} characters.`
1137
+ );
1138
+ }
1139
+ }
1140
+ function validateLocale(locale) {
1141
+ if (locale && !VALID_LOCALES.has(locale)) {
1142
+ throw new Error(`Invalid --locale: ${locale}. Must be one of: zh | en | ja | ko`);
1143
+ }
1144
+ }
1145
+ function buildBody11(ctx) {
1146
+ const body2 = {
1147
+ question: ctx.str("question")
1148
+ };
1149
+ const sources = ctx.json("sources");
1150
+ if (sources) body2.sources = sources;
1151
+ const modelId = ctx.str("model-id");
1152
+ if (modelId) body2.modelId = modelId;
1153
+ const locale = ctx.str("locale");
1154
+ if (locale) body2.locale = locale;
1155
+ return body2;
1156
+ }
1157
+ var ask = {
1158
+ service: "kb",
1159
+ command: "+ask",
1160
+ description: "Ask knowledge bases via LLM-powered retrieval (POST /agent/api/external/knowledge-bases/ask). Consumes platform tokens. Prefer +index -> +grep -> +read for deterministic, token-free lookup. By default, polls for completion; use --no-wait to return immediately with executionId.",
1161
+ flags: [
1162
+ {
1163
+ name: "question",
1164
+ type: "string",
1165
+ required: true,
1166
+ alias: "q",
1167
+ desc: "Natural-language question (1-2000 characters). Required."
1168
+ },
1169
+ {
1170
+ name: "sources",
1171
+ type: "json",
1172
+ required: false,
1173
+ desc: 'Optional JSON array of knowledge base refs to scope the search, e.g. [{"scope":"company","name":"engineering-handbook"}]. Omit to search all accessible knowledge bases.'
1174
+ },
1175
+ {
1176
+ name: "model-id",
1177
+ type: "string",
1178
+ required: false,
1179
+ desc: "Optional LLM model ID (e.g. claude-sonnet-4-6). Omit to use the platform default model."
1180
+ },
1181
+ { name: "locale", type: "string", required: false, desc: "Optional locale: zh | en | ja | ko" },
1182
+ {
1183
+ name: "no-wait",
1184
+ type: "boolean",
1185
+ required: false,
1186
+ desc: "Return immediately after submission with executionId, without polling for completion."
1187
+ }
1188
+ ],
1189
+ risk: "read",
1190
+ validate: (ctx) => {
1191
+ validateQuestion(ctx.str("question"));
1192
+ validateLocale(ctx.str("locale"));
1193
+ },
1194
+ dryRun: (ctx) => ({
1195
+ method: "POST",
1196
+ url: `${ctx.host().replace(/\/$/, "")}${ASK_API_PATH}`,
1197
+ body: buildBody11(ctx)
1198
+ }),
1199
+ execute: async (ctx) => {
1200
+ const noWait = ctx.bool("no-wait");
1201
+ const submitResponse = await kbApi(ctx, "POST", ASK_API_PATH, {}, buildBody11(ctx));
1202
+ if (!submitResponse.executionId) {
1203
+ throw new Error("Invalid submit response: missing executionId");
1204
+ }
1205
+ const executionId = submitResponse.executionId;
1206
+ if (noWait) {
1207
+ return {
1208
+ executionId,
1209
+ status: submitResponse.status
1210
+ };
1211
+ }
1212
+ const finalResponse = await pollUntilSettled(
1213
+ (id) => kbApi(ctx, "GET", ASK_API_PATH, { executionId: id }),
1214
+ executionId
1215
+ );
1216
+ if (finalResponse.status === "completed") {
1217
+ return transformCompletedResponse(finalResponse);
1218
+ }
1219
+ if (finalResponse.status === "failed") {
1220
+ const code = finalResponse.error?.code || "provider_failed";
1221
+ const message = finalResponse.error?.message || "Ask execution failed";
1222
+ throw new TeAgentApiError(
1223
+ `${message} (executionId: ${finalResponse.executionId})`,
1224
+ 200,
1225
+ code,
1226
+ finalResponse
1227
+ );
1228
+ }
1229
+ throw new Error(`Unexpected execution status: ${finalResponse.status}`);
1230
+ }
1231
+ };
1232
+
1233
+ // src/commands/te-kb/ask-status.ts
1234
+ var MAX_EXECUTION_ID_LEN = 64;
1235
+ function executionIdFrom(ctx) {
1236
+ return ctx.str("execution-id").trim();
1237
+ }
1238
+ var askStatus = {
1239
+ service: "kb",
1240
+ command: "+ask-status",
1241
+ description: "Query the status of an in-progress or completed knowledge base ask execution (GET /agent/api/external/knowledge-bases/ask?executionId=<id>). Does not poll; returns the current state.",
1242
+ flags: [
1243
+ {
1244
+ name: "execution-id",
1245
+ type: "string",
1246
+ required: true,
1247
+ minLength: 1,
1248
+ maxLength: MAX_EXECUTION_ID_LEN,
1249
+ desc: "The execution ID returned by kb +ask submission."
1250
+ }
1251
+ ],
1252
+ risk: "read",
1253
+ validate: (ctx) => {
1254
+ const executionId = executionIdFrom(ctx);
1255
+ if (!executionId) {
1256
+ throw new Error("Invalid --execution-id: must be non-empty.");
1257
+ }
1258
+ if (executionId.length > MAX_EXECUTION_ID_LEN) {
1259
+ throw new Error(
1260
+ `Invalid --execution-id length: ${executionId.length}. Must be at most ${MAX_EXECUTION_ID_LEN} characters.`
1261
+ );
1262
+ }
1263
+ },
1264
+ dryRun: (ctx) => ({
1265
+ method: "GET",
1266
+ url: `${ctx.host().replace(/\/$/, "")}${ASK_API_PATH}?executionId=${encodeURIComponent(executionIdFrom(ctx))}`
1267
+ }),
1268
+ execute: async (ctx) => {
1269
+ const executionId = executionIdFrom(ctx);
1270
+ return await kbApi(ctx, "GET", ASK_API_PATH, { executionId });
1271
+ }
1272
+ };
1273
+
1274
+ // src/commands/te-kb/url.ts
1275
+ var API_PATH14 = "/agent/api/external/knowledge-bases/sources/url";
1276
+ function validateUrl(url2) {
1277
+ if (!/^https?:\/\//i.test(url2)) {
1278
+ throw new Error(`Invalid --url: ${url2}. Must be an http(s) URL`);
1279
+ }
1280
+ }
1281
+ function buildBody12(ctx) {
1282
+ const body2 = {
1283
+ name: ctx.str("name"),
1284
+ url: ctx.str("url")
1285
+ };
1286
+ const scope = getExternalKnowledgeBaseTargetScope(ctx);
1287
+ if (scope) body2.scope = scope;
1288
+ const displayName = ctx.str("display-name");
1289
+ if (displayName) body2.displayName = displayName;
1290
+ const parseInstruction = ctx.str("parse-instruction");
1291
+ if (parseInstruction) body2.parseInstruction = parseInstruction;
1292
+ return body2;
1293
+ }
1294
+ var url = {
1295
+ service: "kb",
1296
+ command: "+url",
1297
+ description: "Upload a URL source to a knowledge base.",
1298
+ flags: [
1299
+ { name: "name", type: "string", required: true, desc: "Knowledge base name" },
1300
+ { name: "scope", type: "string", required: false, desc: "Exact knowledge base scope: personal | company (omit for personal \u2192 company fallback)" },
1301
+ { name: "url", type: "string", required: true, desc: "Source URL to upload" },
1302
+ { name: "display-name", type: "string", required: false, desc: "Optional display name for the URL source" },
1303
+ { name: "parse-instruction", type: "string", required: false, desc: "Optional parsing instruction for the URL source; ignored for Lark/Feishu doc URLs (the server applies its own Feishu parsing)" }
1304
+ ],
1305
+ risk: "write",
1306
+ validate: (ctx) => {
1307
+ getExternalKnowledgeBaseTargetScope(ctx);
1308
+ validateUrl(ctx.str("url"));
1309
+ },
1310
+ dryRun: (ctx) => ({
1311
+ method: "POST",
1312
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH14}`,
1313
+ body: buildBody12(ctx)
1314
+ }),
1315
+ execute: async (ctx) => kbApi(ctx, "POST", API_PATH14, {}, buildBody12(ctx))
1316
+ };
1317
+
1318
+ // src/commands/te-kb/import.ts
1319
+ import { promises as fs4 } from "fs";
1320
+ import path4 from "path";
1321
+ var API_PATH15 = "/agent/api/external/knowledge-bases/import";
1322
+ var MAX_SNAPSHOT_ARCHIVE_BYTES = 50 * 1024 * 1024;
1323
+ var VALID_SCOPES2 = /* @__PURE__ */ new Set(["personal", "company"]);
1324
+ function getScope2(ctx) {
1325
+ const scope = ctx.str("scope") || "personal";
1326
+ if (!VALID_SCOPES2.has(scope)) {
1327
+ throw new CliValidationError("Invalid --scope. Must be one of: personal | company", {
1328
+ location: { field: "scope" }
1329
+ });
1330
+ }
1331
+ return scope;
1332
+ }
1333
+ function normalizeTags2(raw) {
1334
+ if (raw === void 0 || raw === null) return [];
1335
+ if (!Array.isArray(raw)) {
1336
+ throw new Error(
1337
+ `--tags must be a JSON array of strings, e.g. '["docs","product"]'`
1338
+ );
1339
+ }
1340
+ const tags = [];
1341
+ for (const value of raw) {
1342
+ if (typeof value !== "string") {
1343
+ throw new Error(
1344
+ `--tags entries must be strings (got: ${JSON.stringify(value)})`
1345
+ );
1346
+ }
1347
+ const tag = value.trim();
1348
+ if (tag && !tags.includes(tag)) tags.push(tag);
1349
+ }
1350
+ if (tags.length > 2) throw new Error("--tags accepts at most 2 unique tags");
1351
+ if (tags.some((tag) => tag.length > 15)) {
1352
+ throw new Error("--tags entries must be at most 15 characters");
1353
+ }
1354
+ return tags;
1355
+ }
1356
+ function validateArchivePath(filePath) {
1357
+ if (path4.extname(filePath).toLocaleLowerCase("en-US") !== ".zip") {
1358
+ throw new Error("--file must point to a .zip archive");
1359
+ }
1360
+ }
1361
+ async function readArchive(filePath) {
1362
+ validateArchivePath(filePath);
1363
+ const absolutePath = path4.resolve(filePath);
1364
+ let stat;
1365
+ try {
1366
+ stat = await fs4.stat(absolutePath);
1367
+ } catch {
1368
+ throw new Error(`File not found: ${filePath}`);
1369
+ }
1370
+ if (!stat.isFile())
1371
+ throw new Error(`--file must point to a file: ${filePath}`);
1372
+ if (stat.size === 0) throw new Error(`ZIP archive is empty: ${filePath}`);
1373
+ if (stat.size > MAX_SNAPSHOT_ARCHIVE_BYTES) {
1374
+ throw new Error("--file must not exceed 50 MB");
1375
+ }
1376
+ return { absolutePath, bytes: await fs4.readFile(absolutePath) };
1377
+ }
1378
+ function appendOptionalFields(ctx, form) {
1379
+ const description = ctx.str("description").trim();
1380
+ if (description) form.append("description", description);
1381
+ for (const tag of normalizeTags2(ctx.json("tags"))) form.append("tags", tag);
1382
+ const projectId = ctx.str("project-id").trim();
1383
+ if (projectId) form.append("projectId", projectId);
1384
+ }
1385
+ var importSnapshot = {
1386
+ service: "kb",
1387
+ command: "+import",
1388
+ description: "Import a compiled Markdown ZIP snapshot as a personal or company read-only knowledge base.",
1389
+ flags: [
1390
+ {
1391
+ name: "scope",
1392
+ type: "string",
1393
+ required: false,
1394
+ default: "personal",
1395
+ desc: "Target scope: personal | company (default: personal)"
1396
+ },
1397
+ {
1398
+ name: "file",
1399
+ type: "string",
1400
+ required: true,
1401
+ desc: "Local .zip snapshot containing root index.md and wiki/**/*.md"
1402
+ },
1403
+ {
1404
+ name: "name",
1405
+ type: "string",
1406
+ required: true,
1407
+ maxLength: 30,
1408
+ desc: "Knowledge base name (max 30 characters)"
1409
+ },
1410
+ {
1411
+ name: "description",
1412
+ type: "string",
1413
+ required: false,
1414
+ maxLength: 200,
1415
+ desc: "Optional description (max 200 characters)"
1416
+ },
1417
+ {
1418
+ name: "tags",
1419
+ type: "json",
1420
+ required: false,
1421
+ desc: "Optional JSON array of tags (max 2, each max 15 characters)"
1422
+ },
1423
+ {
1424
+ name: "project-id",
1425
+ type: "string",
1426
+ required: false,
1427
+ maxLength: 128,
1428
+ desc: "Optional project ID to bind"
1429
+ }
1430
+ ],
1431
+ risk: "write",
1432
+ validate: (ctx) => {
1433
+ getScope2(ctx);
1434
+ validateArchivePath(ctx.str("file"));
1435
+ normalizeTags2(ctx.json("tags"));
1436
+ },
1437
+ execute: async (ctx) => {
1438
+ const archive = await readArchive(ctx.str("file"));
1439
+ const form = new FormData();
1440
+ form.append(
1441
+ "file",
1442
+ new Blob([Uint8Array.from(archive.bytes)], { type: "application/zip" }),
1443
+ path4.basename(archive.absolutePath)
1444
+ );
1445
+ form.append("name", ctx.str("name").trim());
1446
+ form.append("scope", getScope2(ctx));
1447
+ appendOptionalFields(ctx, form);
1448
+ try {
1449
+ return await kbUpload(
1450
+ ctx,
1451
+ API_PATH15,
1452
+ form,
1453
+ { scope: getScope2(ctx) },
1454
+ { preserveErrorMetadata: true, retryUnauthorized: true }
1455
+ );
1456
+ } catch (error) {
1457
+ const hint = "If a requestId was returned, run ae-cli kb +import-status --request-id <requestId>; otherwise run ae-cli kb +list before retrying the same name.";
1458
+ if (error instanceof CapabilityGatewayError) {
1459
+ throw new CapabilityGatewayError(
1460
+ `${error.message} ${hint}`,
1461
+ error.code,
1462
+ error.httpStatus,
1463
+ error.hint ?? hint,
1464
+ error.meta
1465
+ );
1466
+ }
1467
+ if (error instanceof Error) {
1468
+ if (error.constructor === Error) {
1469
+ throw new CapabilityGatewayError(`${error.message} ${hint}`, void 0, void 0, hint);
1470
+ }
1471
+ error.message = `${error.message} ${hint}`;
1472
+ throw error;
1473
+ }
1474
+ throw new Error(`${String(error)} ${hint}`);
1475
+ }
1476
+ }
1477
+ };
1478
+
1479
+ // src/commands/te-kb/import-status.ts
1480
+ var API_PATH16 = "/agent/api/external/knowledge-bases/import";
1481
+ var MAX_REQUEST_ID_LENGTH = 191;
1482
+ function requestIdFrom(ctx) {
1483
+ return ctx.str("request-id").trim();
1484
+ }
1485
+ var importStatus = {
1486
+ service: "kb",
1487
+ command: "+import-status",
1488
+ description: "Query one asynchronous knowledge-base snapshot import by its request ID without polling.",
1489
+ flags: [
1490
+ {
1491
+ name: "request-id",
1492
+ type: "string",
1493
+ required: true,
1494
+ minLength: 1,
1495
+ maxLength: MAX_REQUEST_ID_LENGTH,
1496
+ desc: "The requestId returned by kb +import."
1497
+ }
1498
+ ],
1499
+ risk: "read",
1500
+ validate: (ctx) => {
1501
+ const requestId = requestIdFrom(ctx);
1502
+ if (!requestId) throw new Error("Invalid --request-id: must be non-empty.");
1503
+ if (requestId.length > MAX_REQUEST_ID_LENGTH) {
1504
+ throw new Error(
1505
+ `Invalid --request-id length: ${requestId.length}. Must be at most ${MAX_REQUEST_ID_LENGTH} characters.`
1506
+ );
1507
+ }
1508
+ },
1509
+ dryRun: (ctx) => ({
1510
+ method: "GET",
1511
+ url: `${ctx.host().replace(/\/$/, "")}${API_PATH16}?requestId=${encodeURIComponent(requestIdFrom(ctx))}`
1512
+ }),
1513
+ execute: async (ctx) => {
1514
+ const hint = "Verify the request ID and that the server supports kb +import-status. Do not retry the import until its status is known.";
1515
+ try {
1516
+ return await kbApi(
1517
+ ctx,
1518
+ "GET",
1519
+ API_PATH16,
1520
+ { requestId: requestIdFrom(ctx) },
1521
+ void 0,
1522
+ { preserveErrorMetadata: true, retryUnauthorized: true }
1523
+ );
1524
+ } catch (error) {
1525
+ if (error instanceof PermissionError) {
1526
+ throw new PermissionError(error.message, error.code, error.hint ?? hint);
1527
+ }
1528
+ if (error instanceof CapabilityGatewayError) {
1529
+ if (error.hint) throw error;
1530
+ throw new CapabilityGatewayError(
1531
+ error.message,
1532
+ error.code,
1533
+ error.httpStatus,
1534
+ hint,
1535
+ error.meta
1536
+ );
1537
+ }
1538
+ if (error instanceof Error) {
1539
+ if (error.constructor === Error) {
1540
+ throw new CapabilityGatewayError(error.message, void 0, void 0, hint);
1541
+ }
1542
+ throw error;
1543
+ }
1544
+ throw error;
1545
+ }
1546
+ }
1547
+ };
1548
+
1549
+ // src/commands/te-kb/source-directory.ts
1550
+ import { promises as fs5 } from "fs";
1551
+ import path5 from "path";
1552
+ var sourceFlags = [
1553
+ { name: "name", type: "string", required: true, desc: "Knowledge base name (personal then company)" },
1554
+ { name: "id", type: "string", required: true, desc: "ZIP source ID copied from +list-sources" }
1555
+ ];
1556
+ var pathFlag = { name: "path", type: "string", required: true, desc: "Exact path relative to the ZIP source root" };
1557
+ var revisionFlag2 = {
1558
+ name: "expected-revision",
1559
+ type: "number",
1560
+ required: true,
1561
+ min: 1,
1562
+ desc: "Revision returned by +source-ls; a conflict requires a fresh read and explicit retry"
1563
+ };
1564
+ var apiOptions2 = { preserveErrorMetadata: true, retryUnauthorized: false };
1565
+ var maxFileBytes = 50 * 1024 * 1024;
1566
+ function validateIdentity2(ctx) {
1567
+ for (const [flag, max] of [["name", 200], ["id", 191]]) {
1568
+ const value = ctx.str(flag).trim();
1569
+ if (!value || value.length > max) throw new CliValidationError(`Invalid --${flag}.`);
1570
+ }
1571
+ }
1572
+ function relativePath(ctx, allowRoot = false) {
1573
+ const value = ctx.str("path");
1574
+ if (allowRoot && value === "") return value;
1575
+ if (!value || value.length > 1024 || /[\\\x00-\x1f\x7f]/.test(value) || /^[A-Za-z]:/.test(value) || value.split("/").some((part) => !part || part === "." || part === "..")) {
1576
+ throw new CliValidationError("--path must be a normalized relative path inside the ZIP source.");
1577
+ }
1578
+ return value;
1579
+ }
1580
+ function validateMutation2(ctx) {
1581
+ validateIdentity2(ctx);
1582
+ relativePath(ctx);
1583
+ if (!Number.isSafeInteger(ctx.num("expected-revision")) || ctx.num("expected-revision") < 1) {
1584
+ throw new CliValidationError("--expected-revision must be a positive safe integer.");
1585
+ }
1586
+ }
1587
+ function endpoint(ctx, suffix = "directory") {
1588
+ return `/agent/api/external/knowledge-bases/sources/${encodeURIComponent(ctx.str("id").trim())}/${suffix}`;
1589
+ }
1590
+ function query2(ctx) {
1591
+ return { name: ctx.str("name").trim(), path: ctx.str("path") };
1592
+ }
1593
+ function preview(ctx, method, suffix = "directory", body2) {
1594
+ return { method, url: `${ctx.host().replace(/\/$/, "")}${endpoint(ctx, suffix)}`, ...body2 ? { body: body2 } : { params: query2(ctx) } };
1595
+ }
1596
+ function mutationBody(ctx, operation) {
1597
+ return { name: ctx.str("name").trim(), expectedRevision: ctx.num("expected-revision"), operations: [operation] };
1598
+ }
1599
+ var sourceLs = {
1600
+ service: "kb",
1601
+ command: "+source-ls",
1602
+ risk: "read",
1603
+ description: "List one ZIP source directory, its revision, and changes since successful compilation.",
1604
+ flags: [
1605
+ ...sourceFlags,
1606
+ { ...pathFlag, required: false, default: "" },
1607
+ { name: "cursor", type: "string", desc: "Opaque nextCursor returned by the previous page" },
1608
+ { name: "limit", type: "number", default: 100, min: 1, max: 200, desc: "Page size (1-200)" }
1609
+ ],
1610
+ validate: (ctx) => {
1611
+ validateIdentity2(ctx);
1612
+ relativePath(ctx, true);
1613
+ if (!Number.isInteger(ctx.num("limit")) || ctx.num("limit") < 1 || ctx.num("limit") > 200) {
1614
+ throw new CliValidationError("--limit must be an integer from 1 to 200.");
1615
+ }
1616
+ },
1617
+ dryRun: (ctx) => ({ ...preview(ctx, "GET"), params: { ...query2(ctx), limit: ctx.num("limit"), ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {} } }),
1618
+ execute: (ctx) => kbApi(ctx, "GET", endpoint(ctx), {
1619
+ ...query2(ctx),
1620
+ limit: ctx.num("limit"),
1621
+ ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {}
1622
+ }, void 0, apiOptions2)
1623
+ };
1624
+ var sourceRead = {
1625
+ service: "kb",
1626
+ command: "+source-read",
1627
+ risk: "read",
1628
+ description: "Read a ZIP source file as UTF-8/base64 or save its original bytes to a new local file.",
1629
+ flags: [
1630
+ ...sourceFlags,
1631
+ pathFlag,
1632
+ { name: "encoding", type: "string", default: "utf8", desc: "JSON content encoding: utf8 or base64 (ignored with --output)" },
1633
+ { name: "output", type: "string", desc: "Save original bytes to this local path; existing files are never overwritten" }
1634
+ ],
1635
+ validate: (ctx) => {
1636
+ validateIdentity2(ctx);
1637
+ relativePath(ctx);
1638
+ if (!["utf8", "base64"].includes(ctx.str("encoding"))) throw new CliValidationError("--encoding must be utf8 or base64.");
1639
+ },
1640
+ dryRun: (ctx) => preview(ctx, "GET", "raw"),
1641
+ execute: async (ctx) => {
1642
+ const result = await kbApi(ctx, "GET", endpoint(ctx, "raw"), query2(ctx), void 0, { ...apiOptions2, responseType: "bytes" });
1643
+ const bytes = Buffer.from(result.bytes);
1644
+ const metadata = { path: ctx.str("path"), sizeBytes: bytes.length, contentType: result.contentType };
1645
+ if (ctx.str("output")) {
1646
+ const output = path5.resolve(ctx.str("output"));
1647
+ await fs5.writeFile(output, bytes, { flag: "wx" });
1648
+ return { ...metadata, output };
1649
+ }
1650
+ if (ctx.str("encoding") === "base64") return { ...metadata, encoding: "base64", content: bytes.toString("base64") };
1651
+ try {
1652
+ return { ...metadata, encoding: "utf8", content: new TextDecoder("utf-8", { fatal: true }).decode(bytes) };
1653
+ } catch {
1654
+ throw new CliValidationError("This file is not UTF-8. Use --encoding base64 or --output.");
1655
+ }
1656
+ }
1657
+ };
1658
+ async function fileOperation(ctx, dryRun) {
1659
+ const file = path5.resolve(ctx.str("file"));
1660
+ const handle = await fs5.open(file, "r");
1661
+ try {
1662
+ const stat = await handle.stat();
1663
+ if (!stat.isFile() || stat.size > maxFileBytes) throw new CliValidationError("--file must be a regular file of at most 50 MB.");
1664
+ const action = ctx.str("action");
1665
+ const content = dryRun ? void 0 : await handle.readFile();
1666
+ if (content && content.length > maxFileBytes) throw new CliValidationError("--file exceeds 50 MB.");
1667
+ return {
1668
+ action,
1669
+ path: ctx.str("path"),
1670
+ ...action === "replace" ? { confirmed: true } : {},
1671
+ ...dryRun ? { file, sizeBytes: stat.size, contentBase64: "<redacted>" } : { contentBase64: content.toString("base64") }
1672
+ };
1673
+ } finally {
1674
+ await handle.close();
1675
+ }
1676
+ }
1677
+ var sourcePut = {
1678
+ service: "kb",
1679
+ command: "+source-put",
1680
+ risk: "write",
1681
+ description: "Add or explicitly replace one file at an exact ZIP-relative path using a checked revision.",
1682
+ flags: [
1683
+ ...sourceFlags,
1684
+ pathFlag,
1685
+ revisionFlag2,
1686
+ { name: "file", type: "string", required: true, desc: "Local file to upload (at most 50 MB)" },
1687
+ { name: "action", type: "string", default: "add", desc: "add rejects an existing path; replace explicitly overwrites an existing file" }
1688
+ ],
1689
+ validate: (ctx) => {
1690
+ validateMutation2(ctx);
1691
+ if (!ctx.str("file").trim()) throw new CliValidationError("--file must be non-empty.");
1692
+ if (!["add", "replace"].includes(ctx.str("action"))) throw new CliValidationError("--action must be add or replace.");
1693
+ },
1694
+ dryRun: async (ctx) => preview(ctx, "POST", "directory", mutationBody(ctx, await fileOperation(ctx, true))),
1695
+ execute: async (ctx) => kbApi(ctx, "POST", endpoint(ctx), {}, mutationBody(ctx, await fileOperation(ctx, false)), apiOptions2)
1696
+ };
1697
+ function deleteOperation(ctx) {
1698
+ return { action: "delete", path: ctx.str("path"), confirmed: true, ...ctx.bool("recursive") ? { recursive: true } : {} };
1699
+ }
1700
+ var sourceRm = {
1701
+ service: "kb",
1702
+ command: "+source-rm",
1703
+ risk: "high-risk-write",
1704
+ description: "Delete one ZIP child file or recursively delete one directory; keeps the parent source.",
1705
+ flags: [
1706
+ ...sourceFlags,
1707
+ pathFlag,
1708
+ revisionFlag2,
1709
+ { name: "recursive", type: "boolean", desc: "Explicitly allow recursive directory deletion" }
1710
+ ],
1711
+ validate: validateMutation2,
1712
+ dryRun: (ctx) => preview(ctx, "POST", "directory", mutationBody(ctx, deleteOperation(ctx))),
1713
+ execute: (ctx) => kbApi(ctx, "POST", endpoint(ctx), {}, mutationBody(ctx, deleteOperation(ctx)), apiOptions2)
1714
+ };
1715
+
1716
+ // src/commands/te-kb/version-management.ts
1717
+ import { promises as fs6 } from "fs";
1718
+ import path6 from "path";
1719
+ var API2 = "/agent/api/external/knowledge-bases/versions";
1720
+ var apiOptions3 = { preserveErrorMetadata: true, retryUnauthorized: false };
1721
+ var targetFlags = [
1722
+ { name: "name", type: "string", required: true, minLength: 1, maxLength: 200, desc: "Exact knowledge base name copied from +list" },
1723
+ { name: "scope", type: "string", desc: "Exact personal or company scope; omit for personal then company lookup" }
1724
+ ];
1725
+ var versionFlag = { name: "version", type: "number", required: true, min: 1, max: 2147483647, desc: "Historical version number from +versions, without the v prefix" };
1726
+ var sourceFlag = { name: "id", type: "string", required: true, minLength: 1, maxLength: 191, desc: "Stable historical source ID copied from +version-sources" };
1727
+ var pagingFlags = [
1728
+ { name: "cursor", type: "string", desc: "nextCursor from the previous page; omit for the first page" },
1729
+ { name: "limit", type: "number", default: 100, min: 1, max: 200, desc: "Page size from 1 to 200" }
1730
+ ];
1731
+ var pathFlag2 = { name: "path", type: "string", desc: "Exact path relative to the historical source directory" };
1732
+ function positiveInteger2(ctx, flag) {
1733
+ const value = ctx.num(flag);
1734
+ if (!Number.isSafeInteger(value) || value < 1 || value > 2147483647) throw new CliValidationError(`--${flag} must be a positive integer no greater than 2147483647.`);
1735
+ return value;
1736
+ }
1737
+ function validateTarget(ctx) {
1738
+ const name = ctx.str("name").trim();
1739
+ if (!name || name.length > 200) throw new CliValidationError("--name must contain 1 to 200 characters.");
1740
+ getExternalKnowledgeBaseTargetScope(ctx);
1741
+ }
1742
+ function validateVersion(ctx) {
1743
+ validateTarget(ctx);
1744
+ positiveInteger2(ctx, "version");
1745
+ }
1746
+ function validateSource(ctx) {
1747
+ validateVersion(ctx);
1748
+ const id = ctx.str("id").trim();
1749
+ if (!id || id.length > 191) throw new CliValidationError("--id must contain 1 to 191 characters.");
1750
+ }
1751
+ function validatePage(ctx) {
1752
+ const limit = ctx.num("limit");
1753
+ if (!Number.isInteger(limit) || limit < 1 || limit > 200) throw new CliValidationError("--limit must be an integer from 1 to 200.");
1754
+ if (ctx.str("cursor").length > 500) throw new CliValidationError("--cursor must be at most 500 characters.");
1755
+ }
1756
+ function validatePath(ctx, required = false) {
1757
+ const value = ctx.str("path");
1758
+ if (!value && !required) return;
1759
+ if (!value || value.length > 500 || /[\\\x00-\x1f\x7f]/.test(value) || /^[A-Za-z]:/.test(value) || value.split("/").some((part) => !part || part === "." || part === "..")) {
1760
+ throw new CliValidationError("--path must be a normalized relative path inside the historical source.");
1761
+ }
1762
+ }
1763
+ function query3(ctx) {
1764
+ const scope = getExternalKnowledgeBaseTargetScope(ctx);
1765
+ return { name: ctx.str("name").trim(), ...scope ? { scope } : {} };
1766
+ }
1767
+ function pageQuery(ctx) {
1768
+ return { ...query3(ctx), limit: ctx.num("limit"), ...ctx.str("cursor") ? { cursor: ctx.str("cursor") } : {} };
1769
+ }
1770
+ function versionEndpoint(ctx, suffix = "") {
1771
+ return `${API2}/${positiveInteger2(ctx, "version")}${suffix}`;
1772
+ }
1773
+ function sourceEndpoint2(ctx, action) {
1774
+ return versionEndpoint(ctx, `/sources/${encodeURIComponent(ctx.str("id").trim())}/${action}`);
1775
+ }
1776
+ function preview2(ctx, endpoint2, params, body2) {
1777
+ return { method: body2 ? "POST" : "GET", url: `${ctx.host().replace(/\/$/, "")}${endpoint2}`, params, ...body2 ? { body: body2 } : {} };
1778
+ }
1779
+ var versions = {
1780
+ service: "kb",
1781
+ command: "+versions",
1782
+ risk: "read",
1783
+ description: "List immutable published versions and the latest version ID, one page at a time.",
1784
+ flags: [...targetFlags, ...pagingFlags],
1785
+ validate: (ctx) => {
1786
+ validateTarget(ctx);
1787
+ validatePage(ctx);
1788
+ if (ctx.str("cursor") && (!/^[1-9][0-9]*$/.test(ctx.str("cursor")) || Number(ctx.str("cursor")) > 2147483647)) throw new CliValidationError("--cursor must be a version number returned as nextCursor.");
1789
+ },
1790
+ dryRun: (ctx) => preview2(ctx, API2, pageQuery(ctx)),
1791
+ execute: (ctx) => kbApi(ctx, "GET", API2, pageQuery(ctx), void 0, apiOptions3)
1792
+ };
1793
+ var versionShow = {
1794
+ service: "kb",
1795
+ command: "+version-show",
1796
+ risk: "read",
1797
+ description: "Read one published version summary without reading current sources.",
1798
+ flags: [...targetFlags, versionFlag],
1799
+ validate: validateVersion,
1800
+ dryRun: (ctx) => preview2(ctx, versionEndpoint(ctx), query3(ctx)),
1801
+ execute: (ctx) => kbApi(ctx, "GET", versionEndpoint(ctx), query3(ctx), void 0, apiOptions3)
1802
+ };
1803
+ var versionSources = {
1804
+ service: "kb",
1805
+ command: "+version-sources",
1806
+ risk: "read",
1807
+ description: "List historical sources and stable IDs from one immutable version.",
1808
+ flags: [...targetFlags, versionFlag, ...pagingFlags, { name: "source-type", type: "string", desc: "Optional source type filter: file | url | zip" }],
1809
+ validate: (ctx) => {
1810
+ validateVersion(ctx);
1811
+ validatePage(ctx);
1812
+ if (ctx.str("source-type") && !["file", "url", "zip"].includes(ctx.str("source-type"))) throw new CliValidationError("--source-type must be file, url, or zip.");
1813
+ },
1814
+ dryRun: (ctx) => preview2(ctx, versionEndpoint(ctx, "/sources"), { ...pageQuery(ctx), ...ctx.str("source-type") ? { sourceType: ctx.str("source-type") } : {} }),
1815
+ execute: (ctx) => kbApi(ctx, "GET", versionEndpoint(ctx, "/sources"), { ...pageQuery(ctx), ...ctx.str("source-type") ? { sourceType: ctx.str("source-type") } : {} }, void 0, apiOptions3)
1816
+ };
1817
+ var versionDiff = {
1818
+ service: "kb",
1819
+ command: "+version-diff",
1820
+ risk: "read",
1821
+ description: "Compare historical source additions, deletions, content, and metadata between two versions.",
1822
+ flags: [...targetFlags, { ...versionFlag, name: "from", desc: "Before version number" }, { ...versionFlag, name: "to", desc: "After version number" }],
1823
+ validate: (ctx) => {
1824
+ validateTarget(ctx);
1825
+ positiveInteger2(ctx, "from");
1826
+ positiveInteger2(ctx, "to");
1827
+ },
1828
+ dryRun: (ctx) => preview2(ctx, `${API2}/compare`, { ...query3(ctx), from: ctx.num("from"), to: ctx.num("to") }),
1829
+ execute: (ctx) => kbApi(ctx, "GET", `${API2}/compare`, { ...query3(ctx), from: ctx.num("from"), to: ctx.num("to") }, void 0, apiOptions3)
1830
+ };
1831
+ var versionTree = {
1832
+ service: "kb",
1833
+ command: "+version-tree",
1834
+ risk: "read",
1835
+ description: "List a historical ZIP or URL source directory without changing current files.",
1836
+ flags: [...targetFlags, versionFlag, sourceFlag, pathFlag2, ...pagingFlags],
1837
+ validate: (ctx) => {
1838
+ validateSource(ctx);
1839
+ validatePath(ctx);
1840
+ validatePage(ctx);
1841
+ },
1842
+ dryRun: (ctx) => preview2(ctx, sourceEndpoint2(ctx, "tree"), { ...pageQuery(ctx), path: ctx.str("path") }),
1843
+ execute: (ctx) => kbApi(ctx, "GET", sourceEndpoint2(ctx, "tree"), { ...pageQuery(ctx), path: ctx.str("path") }, void 0, apiOptions3)
1844
+ };
1845
+ var versionRead = {
1846
+ service: "kb",
1847
+ command: "+version-read",
1848
+ risk: "read",
1849
+ description: "Preview one historical directory child file; unsupported or oversized files return metadata only.",
1850
+ flags: [...targetFlags, versionFlag, sourceFlag, { ...pathFlag2, required: true }],
1851
+ validate: (ctx) => {
1852
+ validateSource(ctx);
1853
+ validatePath(ctx, true);
1854
+ },
1855
+ dryRun: (ctx) => preview2(ctx, sourceEndpoint2(ctx, "file"), { ...query3(ctx), path: ctx.str("path") }),
1856
+ execute: (ctx) => kbApi(ctx, "GET", sourceEndpoint2(ctx, "file"), { ...query3(ctx), path: ctx.str("path") }, void 0, apiOptions3)
1857
+ };
1858
+ var versionDownload = {
1859
+ service: "kb",
1860
+ command: "+version-download",
1861
+ risk: "read",
1862
+ description: "Download one ordinary historical file source to a new local file. ZIP/URL directories cannot be downloaded.",
1863
+ flags: [...targetFlags, versionFlag, sourceFlag, { name: "output", type: "string", required: true, desc: "New local output path; existing files are never overwritten" }],
1864
+ validate: (ctx) => {
1865
+ validateSource(ctx);
1866
+ if (!ctx.str("output").trim()) throw new CliValidationError("--output is required.");
1867
+ },
1868
+ dryRun: (ctx) => ({ ...preview2(ctx, sourceEndpoint2(ctx, "raw"), query3(ctx)), output: path6.resolve(ctx.str("output")) }),
1869
+ execute: async (ctx) => {
1870
+ const result = await kbApi(ctx, "GET", sourceEndpoint2(ctx, "raw"), query3(ctx), void 0, { ...apiOptions3, responseType: "bytes" });
1871
+ const output = path6.resolve(ctx.str("output"));
1872
+ const bytes = Buffer.from(result.bytes);
1873
+ await fs6.writeFile(output, bytes, { flag: "wx" });
1874
+ return { versionNumber: ctx.num("version"), sourceId: ctx.str("id").trim(), sizeBytes: String(bytes.length), output };
1875
+ }
1876
+ };
1877
+ function rollbackBody(ctx) {
1878
+ return { requestId: ctx.str("request-id"), expectedLatestVersionId: ctx.str("expected-latest-version-id") };
1879
+ }
1880
+ var rollback = {
1881
+ service: "kb",
1882
+ command: "+rollback",
1883
+ risk: "high-risk-write",
1884
+ description: "Restore an earlier version as a new publication. Replace target-source drafts, delete other compiled sources, and preserve unpublished additions. Reuse request-id on network retries.",
1885
+ flags: [
1886
+ ...targetFlags,
1887
+ versionFlag,
1888
+ { name: "request-id", type: "string", required: true, maxLength: 191, desc: "Caller-generated stable ASCII request ID; reuse exactly for retries of this logical operation" },
1889
+ { name: "expected-latest-version-id", type: "string", required: true, maxLength: 191, desc: "latestVersionId returned by +versions; conflicts require fresh discovery and a new intentional request" }
1890
+ ],
1891
+ validate: (ctx) => {
1892
+ validateVersion(ctx);
1893
+ if (!/^[A-Za-z0-9_-]{1,191}$/.test(ctx.str("request-id"))) throw new CliValidationError("--request-id must contain 1-191 ASCII letters, digits, underscores, or hyphens.");
1894
+ const latest = ctx.str("expected-latest-version-id");
1895
+ if (!latest || latest.length > 191) throw new CliValidationError("--expected-latest-version-id must contain 1 to 191 characters.");
1896
+ },
1897
+ dryRun: (ctx) => preview2(ctx, versionEndpoint(ctx, "/rollback"), query3(ctx), rollbackBody(ctx)),
1898
+ execute: (ctx) => kbApi(ctx, "POST", versionEndpoint(ctx, "/rollback"), query3(ctx), rollbackBody(ctx), apiOptions3)
1899
+ };
1900
+ var rollbackStatus = {
1901
+ service: "kb",
1902
+ command: "+rollback-status",
1903
+ risk: "read",
1904
+ description: "Read one persisted rollback operation without polling. A running operation with errorCode requires administrator review; never retry it as a new write.",
1905
+ flags: [...targetFlags, { name: "operation-id", type: "string", required: true, minLength: 1, maxLength: 191, desc: "operationId returned by +rollback" }],
1906
+ validate: (ctx) => {
1907
+ validateTarget(ctx);
1908
+ if (!ctx.str("operation-id").trim() || ctx.str("operation-id").length > 191) throw new CliValidationError("--operation-id must contain 1 to 191 characters.");
1909
+ },
1910
+ dryRun: (ctx) => preview2(ctx, `${API2}/operations/${encodeURIComponent(ctx.str("operation-id").trim())}`, query3(ctx)),
1911
+ execute: (ctx) => kbApi(ctx, "GET", `${API2}/operations/${encodeURIComponent(ctx.str("operation-id").trim())}`, query3(ctx), void 0, apiOptions3)
1912
+ };
1913
+
1914
+ // src/commands/te-kb/index.ts
1915
+ var commands = [
1916
+ sourceCheckUpdates,
1917
+ sourceReplace,
1918
+ sourceRestore,
1919
+ sourcePreview,
1920
+ sourceCommit,
1921
+ sourceCancel,
1922
+ versions,
1923
+ versionShow,
1924
+ versionSources,
1925
+ versionDiff,
1926
+ versionTree,
1927
+ versionRead,
1928
+ versionDownload,
1929
+ rollback,
1930
+ rollbackStatus,
1931
+ sourceLs,
1932
+ sourceRead,
1933
+ sourcePut,
1934
+ sourceRm,
1935
+ ask,
1936
+ askStatus,
1937
+ add,
1938
+ url,
1939
+ compile,
1940
+ remove,
1941
+ create,
1942
+ listSources,
1943
+ rmSource,
1944
+ schema,
1945
+ status,
1946
+ kbList,
1947
+ kbIndex,
1948
+ kbGrep,
1949
+ kbRead,
1950
+ importSnapshot,
1951
+ importStatus
1952
+ ];
1953
+ var te_kb_default = commands;
1954
+ export {
1955
+ add,
1956
+ ask,
1957
+ askStatus,
1958
+ compile,
1959
+ create,
1960
+ te_kb_default as default,
1961
+ importSnapshot,
1962
+ importStatus,
1963
+ kbGrep,
1964
+ kbIndex,
1965
+ kbList,
1966
+ kbRead,
1967
+ listSources,
1968
+ remove,
1969
+ rmSource,
1970
+ rollback,
1971
+ rollbackStatus,
1972
+ schema,
1973
+ sourceCancel,
1974
+ sourceCheckUpdates,
1975
+ sourceCommit,
1976
+ sourceLs,
1977
+ sourcePreview,
1978
+ sourcePut,
1979
+ sourceRead,
1980
+ sourceReplace,
1981
+ sourceRestore,
1982
+ sourceRm,
1983
+ status,
1984
+ url,
1985
+ versionDiff,
1986
+ versionDownload,
1987
+ versionRead,
1988
+ versionShow,
1989
+ versionSources,
1990
+ versionTree,
1991
+ versions
1992
+ };