@huicai/cli 2026.814.0 → 2026.1021.0

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 (493) hide show
  1. package/LICENSE +391 -32
  2. package/README.md +139 -8
  3. package/bin/huicai.js +155 -74
  4. package/bin/update.js +97 -0
  5. package/package.json +27 -8
  6. package/skills/ab-testing/trigger-cases.json +30 -0
  7. package/skills/academic-writing/trigger-cases.json +30 -0
  8. package/skills/accounting-ops/trigger-cases.json +30 -0
  9. package/skills/ai-agent/trigger-cases.json +30 -0
  10. package/skills/ai-aiops/trigger-cases.json +30 -0
  11. package/skills/ai-coding/SKILL.md +2 -0
  12. package/skills/ai-coding/trigger-cases.json +30 -0
  13. package/skills/ai-compliance/trigger-cases.json +30 -0
  14. package/skills/ai-eval/trigger-cases.json +30 -0
  15. package/skills/ai-llm-app/trigger-cases.json +30 -0
  16. package/skills/ai-mlops/trigger-cases.json +30 -0
  17. package/skills/ai-multimodal/trigger-cases.json +30 -0
  18. package/skills/ai-prompt/trigger-cases.json +30 -0
  19. package/skills/ai-rag/trigger-cases.json +30 -0
  20. package/skills/anomaly-detection/trigger-cases.json +30 -0
  21. package/skills/api-design/trigger-cases.json +31 -0
  22. package/skills/api-integration/trigger-cases.json +31 -0
  23. package/skills/arch-design/trigger-cases.json +12 -0
  24. package/skills/arch-diagram/SKILL.md +118 -0
  25. package/skills/arch-diagram/trigger-cases.json +30 -0
  26. package/skills/arch-distributed/trigger-cases.json +30 -0
  27. package/skills/arch-multitenant/trigger-cases.json +30 -0
  28. package/skills/audio-brief/SKILL.md +65 -0
  29. package/skills/audio-brief/trigger-cases.json +30 -0
  30. package/skills/audit-assist/trigger-cases.json +30 -0
  31. package/skills/audit-chain/trigger-cases.json +31 -0
  32. package/skills/banking-credit/trigger-cases.json +30 -0
  33. package/skills/brand-design/trigger-cases.json +30 -0
  34. package/skills/business-plan/trigger-cases.json +30 -0
  35. package/skills/capital-ops/trigger-cases.json +30 -0
  36. package/skills/cicd-pipeline/trigger-cases.json +31 -0
  37. package/skills/code-archaeology/SKILL.md +55 -0
  38. package/skills/code-archaeology/trigger-cases.json +9 -0
  39. package/skills/code-quality/SKILL.md +138 -0
  40. package/skills/code-quality/references/languages.md +107 -0
  41. package/skills/code-quality/scripts/__pycache__/code_battery.cpython-312.pyc +0 -0
  42. package/skills/code-quality/scripts/__pycache__/code_check.cpython-312.pyc +0 -0
  43. package/skills/code-quality/scripts/__pycache__/code_check.cpython-313.pyc +0 -0
  44. package/skills/code-quality/scripts/__pycache__/code_csharp.cpython-312.pyc +0 -0
  45. package/skills/code-quality/scripts/__pycache__/code_csharp.cpython-313.pyc +0 -0
  46. package/skills/code-quality/scripts/__pycache__/code_fix.cpython-312.pyc +0 -0
  47. package/skills/code-quality/scripts/__pycache__/code_fix.cpython-313.pyc +0 -0
  48. package/skills/code-quality/scripts/__pycache__/code_java.cpython-312.pyc +0 -0
  49. package/skills/code-quality/scripts/__pycache__/code_java.cpython-313.pyc +0 -0
  50. package/skills/code-quality/scripts/__pycache__/code_jsts.cpython-312.pyc +0 -0
  51. package/skills/code-quality/scripts/__pycache__/code_jsts.cpython-313.pyc +0 -0
  52. package/skills/code-quality/scripts/__pycache__/code_lens.cpython-312.pyc +0 -0
  53. package/skills/code-quality/scripts/__pycache__/code_lens.cpython-313.pyc +0 -0
  54. package/skills/code-quality/scripts/__pycache__/code_python.cpython-312.pyc +0 -0
  55. package/skills/code-quality/scripts/__pycache__/code_python.cpython-313.pyc +0 -0
  56. package/skills/code-quality/scripts/__pycache__/code_testplan.cpython-312.pyc +0 -0
  57. package/skills/code-quality/scripts/code_battery.py +1072 -0
  58. package/skills/code-quality/scripts/code_check.py +1269 -0
  59. package/skills/code-quality/scripts/code_csharp.py +371 -0
  60. package/skills/code-quality/scripts/code_fix.py +201 -0
  61. package/skills/code-quality/scripts/code_java.py +695 -0
  62. package/skills/code-quality/scripts/code_jsts.py +313 -0
  63. package/skills/code-quality/scripts/code_lens.py +1079 -0
  64. package/skills/code-quality/scripts/code_python.py +536 -0
  65. package/skills/code-quality/scripts/code_testplan.py +239 -0
  66. package/skills/code-quality/trigger-cases.json +45 -0
  67. package/skills/code-review/SKILL.md +24 -0
  68. package/skills/code-review/trigger-cases.json +35 -0
  69. package/skills/commit-and-pr/trigger-cases.json +31 -0
  70. package/skills/content-creation/trigger-cases.json +30 -0
  71. package/skills/corporate-governance/trigger-cases.json +30 -0
  72. package/skills/crawl-chain/trigger-cases.json +31 -0
  73. package/skills/customer-service/trigger-cases.json +30 -0
  74. package/skills/data-analysis/trigger-cases.json +30 -0
  75. package/skills/data-chain/SKILL.md +1 -1
  76. package/skills/data-chain/trigger-cases.json +31 -0
  77. package/skills/data-governance/trigger-cases.json +30 -0
  78. package/skills/data-report-pro/trigger-cases.json +30 -0
  79. package/skills/data-streaming/trigger-cases.json +30 -0
  80. package/skills/data-wrangling/SKILL.md +1 -1
  81. package/skills/data-wrangling/trigger-cases.json +30 -0
  82. package/skills/db-es/trigger-cases.json +30 -0
  83. package/skills/db-migration/trigger-cases.json +30 -0
  84. package/skills/db-mysql/trigger-cases.json +30 -0
  85. package/skills/db-postgres/trigger-cases.json +30 -0
  86. package/skills/db-redis/trigger-cases.json +30 -0
  87. package/skills/debug-root-cause/trigger-cases.json +30 -0
  88. package/skills/dependency-audit/SKILL.md +56 -0
  89. package/skills/dependency-audit/trigger-cases.json +7 -0
  90. package/skills/dependency-upgrade/trigger-cases.json +31 -0
  91. package/skills/dev-cpp/trigger-cases.json +30 -0
  92. package/skills/dev-cross-platform/trigger-cases.json +30 -0
  93. package/skills/dev-csharp/SKILL.md +23 -0
  94. package/skills/dev-csharp/trigger-cases.json +30 -0
  95. package/skills/dev-frontend/SKILL.md +19 -0
  96. package/skills/dev-frontend/trigger-cases.json +30 -0
  97. package/skills/dev-go/trigger-cases.json +30 -0
  98. package/skills/dev-harmony/trigger-cases.json +30 -0
  99. package/skills/dev-java/SKILL.md +20 -0
  100. package/skills/dev-java/trigger-cases.json +30 -0
  101. package/skills/dev-mobile/trigger-cases.json +30 -0
  102. package/skills/dev-node/trigger-cases.json +30 -0
  103. package/skills/dev-php/trigger-cases.json +30 -0
  104. package/skills/dev-python/SKILL.md +21 -0
  105. package/skills/dev-python/trigger-cases.json +30 -0
  106. package/skills/dev-rust/trigger-cases.json +30 -0
  107. package/skills/dev-toolchain/trigger-cases.json +31 -0
  108. package/skills/doc-chain/trigger-cases.json +31 -0
  109. package/skills/doc-compare/trigger-cases.json +30 -0
  110. package/skills/docx-author/SKILL.md +127 -25
  111. package/skills/docx-author/scripts/__pycache__/docx_battery.cpython-312.pyc +0 -0
  112. package/skills/docx-author/scripts/__pycache__/docx_build.cpython-312.pyc +0 -0
  113. package/skills/docx-author/scripts/__pycache__/docx_check.cpython-312.pyc +0 -0
  114. package/skills/docx-author/scripts/__pycache__/docx_layout.cpython-312.pyc +0 -0
  115. package/skills/docx-author/scripts/__pycache__/zh_prose.cpython-312.pyc +0 -0
  116. package/skills/docx-author/scripts/docx_battery.py +586 -0
  117. package/skills/docx-author/scripts/docx_build.py +995 -0
  118. package/skills/docx-author/scripts/docx_check.py +1306 -0
  119. package/skills/docx-author/scripts/docx_doc.py +14 -154
  120. package/skills/docx-author/scripts/docx_layout.py +490 -0
  121. package/skills/docx-author/scripts/zh_prose.py +639 -0
  122. package/skills/docx-author/trigger-cases.json +58 -0
  123. package/skills/echo-brief/SKILL.md +84 -0
  124. package/skills/echo-brief/references/echo-format.md +68 -0
  125. package/skills/echo-brief/trigger-cases.json +40 -0
  126. package/skills/ecommerce-ops/trigger-cases.json +30 -0
  127. package/skills/education-training/trigger-cases.json +30 -0
  128. package/skills/ehs-safety/trigger-cases.json +30 -0
  129. package/skills/email-writing/trigger-cases.json +30 -0
  130. package/skills/eng-ai/trigger-cases.json +30 -0
  131. package/skills/eng-architecture/trigger-cases.json +31 -0
  132. package/skills/eng-automation/trigger-cases.json +31 -0
  133. package/skills/eng-collaboration/trigger-cases.json +30 -0
  134. package/skills/eng-complex-env/trigger-cases.json +30 -0
  135. package/skills/eng-data-platform/trigger-cases.json +31 -0
  136. package/skills/eng-database/trigger-cases.json +31 -0
  137. package/skills/eng-develop/SKILL.md +9 -1
  138. package/skills/eng-develop/references/dod-checklist.md +3 -0
  139. package/skills/eng-develop/references/engineering-workflow.md +37 -0
  140. package/skills/eng-develop/trigger-cases.json +30 -0
  141. package/skills/eng-docs/SKILL.md +24 -0
  142. package/skills/eng-docs/trigger-cases.json +30 -0
  143. package/skills/eng-efficiency/trigger-cases.json +30 -0
  144. package/skills/eng-infra/trigger-cases.json +30 -0
  145. package/skills/eng-integration/trigger-cases.json +31 -0
  146. package/skills/eng-legacy/trigger-cases.json +31 -0
  147. package/skills/eng-observability/trigger-cases.json +31 -0
  148. package/skills/eng-ops/trigger-cases.json +31 -0
  149. package/skills/eng-performance/trigger-cases.json +31 -0
  150. package/skills/eng-planning/trigger-cases.json +31 -0
  151. package/skills/eng-quality/SKILL.md +8 -0
  152. package/skills/eng-quality/trigger-cases.json +31 -0
  153. package/skills/eng-release/trigger-cases.json +31 -0
  154. package/skills/eng-reliability/trigger-cases.json +31 -0
  155. package/skills/eng-requirements/trigger-cases.json +12 -0
  156. package/skills/eng-research/trigger-cases.json +30 -0
  157. package/skills/eng-security/trigger-cases.json +31 -0
  158. package/skills/eng-ux/trigger-cases.json +30 -0
  159. package/skills/engineering-chain/trigger-cases.json +30 -0
  160. package/skills/env-offline/trigger-cases.json +31 -0
  161. package/skills/env-private-deploy/trigger-cases.json +31 -0
  162. package/skills/env-xinchuang/trigger-cases.json +31 -0
  163. package/skills/equipment-tpm/trigger-cases.json +30 -0
  164. package/skills/esg-report/trigger-cases.json +30 -0
  165. package/skills/event-management/trigger-cases.json +30 -0
  166. package/skills/excel-analysis-chain/SKILL.md +17 -4
  167. package/skills/excel-analysis-chain/trigger-cases.json +31 -0
  168. package/skills/explain-codebase/trigger-cases.json +11 -0
  169. package/skills/file-ingest/trigger-cases.json +30 -0
  170. package/skills/finance-analysis/trigger-cases.json +31 -0
  171. package/skills/finance-chain/trigger-cases.json +31 -0
  172. package/skills/financial-modeling/trigger-cases.json +31 -0
  173. package/skills/find-simplifications/SKILL.md +43 -0
  174. package/skills/find-simplifications/trigger-cases.json +23 -0
  175. package/skills/foreign-trade/trigger-cases.json +30 -0
  176. package/skills/funnel-cohort/trigger-cases.json +30 -0
  177. package/skills/gov-document/trigger-cases.json +30 -0
  178. package/skills/gui-change-evidence/SKILL.md +47 -0
  179. package/skills/gui-change-evidence/trigger-cases.json +23 -0
  180. package/skills/hr-chain/trigger-cases.json +31 -0
  181. package/skills/hr-operations/trigger-cases.json +30 -0
  182. package/skills/info-disclosure/trigger-cases.json +31 -0
  183. package/skills/infra-gateway/trigger-cases.json +31 -0
  184. package/skills/infra-k8s/trigger-cases.json +31 -0
  185. package/skills/infra-mq/trigger-cases.json +30 -0
  186. package/skills/insurance-advisory/trigger-cases.json +30 -0
  187. package/skills/internal-audit/trigger-cases.json +30 -0
  188. package/skills/ip-management/trigger-cases.json +31 -0
  189. package/skills/ipo-listing/trigger-cases.json +31 -0
  190. package/skills/it-audit/trigger-cases.json +31 -0
  191. package/skills/itsm-ops/trigger-cases.json +31 -0
  192. package/skills/knowledge-sop/trigger-cases.json +31 -0
  193. package/skills/legal-chain/trigger-cases.json +31 -0
  194. package/skills/legal-contract/trigger-cases.json +30 -0
  195. package/skills/litigation-support/trigger-cases.json +31 -0
  196. package/skills/logistics-warehouse/trigger-cases.json +30 -0
  197. package/skills/long-doc-analysis/trigger-cases.json +31 -0
  198. package/skills/management-accounting/trigger-cases.json +30 -0
  199. package/skills/manufacturing-chain/trigger-cases.json +31 -0
  200. package/skills/manufacturing-quality/trigger-cases.json +30 -0
  201. package/skills/marketing-analytics/trigger-cases.json +31 -0
  202. package/skills/marketing-chain/trigger-cases.json +31 -0
  203. package/skills/meeting-minutes/trigger-cases.json +30 -0
  204. package/skills/metrics-system/trigger-cases.json +31 -0
  205. package/skills/negotiation-prep/trigger-cases.json +30 -0
  206. package/skills/obs-prometheus/trigger-cases.json +31 -0
  207. package/skills/office-automation/trigger-cases.json +31 -0
  208. package/skills/okr-review/trigger-cases.json +30 -0
  209. package/skills/ops-fleet/trigger-cases.json +31 -0
  210. package/skills/ops-linux/trigger-cases.json +31 -0
  211. package/skills/optimization-solver/trigger-cases.json +30 -0
  212. package/skills/patent-disclosure/SKILL.md +105 -0
  213. package/skills/patent-disclosure/references/figures.md +110 -0
  214. package/skills/patent-disclosure/references/outline.md +162 -0
  215. package/skills/patent-disclosure/scripts/patent_docx.py +230 -0
  216. package/skills/patent-disclosure/trigger-cases.json +31 -0
  217. package/skills/patent-drafting/SKILL.md +108 -0
  218. package/skills/patent-drafting/trigger-cases.json +31 -0
  219. package/skills/patent-portfolio/SKILL.md +81 -0
  220. package/skills/patent-portfolio/trigger-cases.json +31 -0
  221. package/skills/pdf-toolkit/trigger-cases.json +31 -0
  222. package/skills/perf-optimize/trigger-cases.json +31 -0
  223. package/skills/pivot-crosstab/trigger-cases.json +30 -0
  224. package/skills/policy-analysis/trigger-cases.json +31 -0
  225. package/skills/portfolio-analysis/trigger-cases.json +31 -0
  226. package/skills/ppt-chain/SKILL.md +14 -6
  227. package/skills/ppt-chain/trigger-cases.json +31 -0
  228. package/skills/pptx-author/SKILL.md +86 -33
  229. package/skills/pptx-author/scripts/__pycache__/pptx_check.cpython-312.pyc +0 -0
  230. package/skills/pptx-author/scripts/__pycache__/pptx_deck.cpython-312.pyc +0 -0
  231. package/skills/pptx-author/scripts/__pycache__/pptx_layout.cpython-312.pyc +0 -0
  232. package/skills/pptx-author/scripts/pptx_battery.py +178 -0
  233. package/skills/pptx-author/scripts/pptx_build.py +119 -0
  234. package/skills/pptx-author/scripts/pptx_check.py +1182 -0
  235. package/skills/pptx-author/scripts/pptx_deck.py +736 -145
  236. package/skills/pptx-author/scripts/pptx_layout.py +384 -0
  237. package/skills/pptx-author/trigger-cases.json +15 -0
  238. package/skills/pr-comms/trigger-cases.json +30 -0
  239. package/skills/procurement-supply/trigger-cases.json +31 -0
  240. package/skills/product-design/trigger-cases.json +31 -0
  241. package/skills/production-planning/trigger-cases.json +31 -0
  242. package/skills/project-management/trigger-cases.json +31 -0
  243. package/skills/project-proposal/trigger-cases.json +31 -0
  244. package/skills/prose-standard/SKILL.md +53 -0
  245. package/skills/prose-standard/trigger-cases.json +23 -0
  246. package/skills/qa-api-automation/trigger-cases.json +31 -0
  247. package/skills/qa-mobile-automation/trigger-cases.json +31 -0
  248. package/skills/qa-ui-automation/trigger-cases.json +31 -0
  249. package/skills/quant-analysis/trigger-cases.json +31 -0
  250. package/skills/rag-triage/SKILL.md +64 -0
  251. package/skills/rag-triage/evals.json +57 -0
  252. package/skills/rag-triage/references/triage-playbook.md +75 -0
  253. package/skills/rag-triage/trigger-cases.json +31 -0
  254. package/skills/real-estate-property/trigger-cases.json +30 -0
  255. package/skills/refactor-safely/SKILL.md +1 -1
  256. package/skills/refactor-safely/trigger-cases.json +30 -0
  257. package/skills/regression-forecast/trigger-cases.json +31 -0
  258. package/skills/release-checklist/trigger-cases.json +31 -0
  259. package/skills/report-craft/SKILL.md +76 -0
  260. package/skills/report-craft/references/feasibility.md +118 -0
  261. package/skills/report-craft/references/review-checklist.md +51 -0
  262. package/skills/report-craft/references/visuals.md +114 -0
  263. package/skills/report-craft/references/writing.md +80 -0
  264. package/skills/report-craft/scripts/__pycache__/chart_render.cpython-312.pyc +0 -0
  265. package/skills/report-craft/scripts/__pycache__/fin_model.cpython-312.pyc +0 -0
  266. package/skills/report-craft/scripts/__pycache__/project_facts.cpython-312.pyc +0 -0
  267. package/skills/report-craft/scripts/chart_render.py +1222 -0
  268. package/skills/report-craft/scripts/fin_model.py +602 -0
  269. package/skills/report-craft/scripts/project_facts.py +580 -0
  270. package/skills/report-craft/scripts/report_battery.py +349 -0
  271. package/skills/report-craft/trigger-cases.json +15 -0
  272. package/skills/retail-store-ops/trigger-cases.json +30 -0
  273. package/skills/risk-compliance/trigger-cases.json +31 -0
  274. package/skills/scope-creep/SKILL.md +45 -0
  275. package/skills/scope-creep/trigger-cases.json +7 -0
  276. package/skills/sec-auth/trigger-cases.json +31 -0
  277. package/skills/sec-compliance/trigger-cases.json +31 -0
  278. package/skills/securities-chain/trigger-cases.json +31 -0
  279. package/skills/securities-research/trigger-cases.json +31 -0
  280. package/skills/security-audit/trigger-cases.json +31 -0
  281. package/skills/slides-html/SKILL.md +25 -10
  282. package/skills/slides-html/trigger-cases.json +11 -0
  283. package/skills/sql-analysis/SKILL.md +110 -0
  284. package/skills/sql-analysis/trigger-cases.json +34 -0
  285. package/skills/sql-tuning/trigger-cases.json +31 -0
  286. package/skills/statistical-testing/trigger-cases.json +31 -0
  287. package/skills/strategy-planning/trigger-cases.json +30 -0
  288. package/skills/supply-chain/trigger-cases.json +31 -0
  289. package/skills/tax-compliance/trigger-cases.json +30 -0
  290. package/skills/tech-doc/SKILL.md +262 -0
  291. package/skills/tech-doc/scripts/__pycache__/archive_battery.cpython-312.pyc +0 -0
  292. package/skills/tech-doc/scripts/__pycache__/archive_build.cpython-312.pyc +0 -0
  293. package/skills/tech-doc/scripts/__pycache__/archive_check.cpython-312.pyc +0 -0
  294. package/skills/tech-doc/scripts/__pycache__/archive_spec.cpython-312.pyc +0 -0
  295. package/skills/tech-doc/scripts/__pycache__/doc_templates.cpython-312.pyc +0 -0
  296. package/skills/tech-doc/scripts/archive_battery.py +860 -0
  297. package/skills/tech-doc/scripts/archive_build.py +599 -0
  298. package/skills/tech-doc/scripts/archive_check.py +1307 -0
  299. package/skills/tech-doc/scripts/archive_spec.py +499 -0
  300. package/skills/tech-doc/scripts/doc_templates.py +624 -0
  301. package/skills/tech-doc/trigger-cases.json +57 -0
  302. package/skills/tech-research/trigger-cases.json +31 -0
  303. package/skills/tender-bidding/trigger-cases.json +31 -0
  304. package/skills/translation-pro/trigger-cases.json +30 -0
  305. package/skills/treasury-mgmt/trigger-cases.json +31 -0
  306. package/skills/trim-cot-leakage/SKILL.md +58 -0
  307. package/skills/trim-cot-leakage/trigger-cases.json +23 -0
  308. package/skills/web-craft/SKILL.md +103 -0
  309. package/skills/web-craft/references/craft-checklist.md +75 -0
  310. package/skills/web-craft/references/design-direction.md +122 -0
  311. package/skills/web-craft/references/h5-mobile.md +100 -0
  312. package/skills/web-craft/references/motion.md +136 -0
  313. package/skills/web-craft/references/recipes.md +74 -0
  314. package/skills/web-craft/templates/wedding-invitation.html +1180 -0
  315. package/skills/web-craft/trigger-cases.json +14 -0
  316. package/skills/web-scraping/trigger-cases.json +34 -0
  317. package/skills/web-search/SKILL.md +11 -10
  318. package/skills/web-search/trigger-cases.json +31 -0
  319. package/skills/weekly-report/SKILL.md +134 -0
  320. package/skills/weekly-report/trigger-cases.json +11 -0
  321. package/skills/write-tests/trigger-cases.json +31 -0
  322. package/skills/xlsx-analysis/SKILL.md +143 -77
  323. package/skills/xlsx-analysis/scripts/__pycache__/data_profile.cpython-312.pyc +0 -0
  324. package/skills/xlsx-analysis/scripts/__pycache__/xlsx_build.cpython-312.pyc +0 -0
  325. package/skills/xlsx-analysis/scripts/__pycache__/xlsx_check.cpython-312.pyc +0 -0
  326. package/skills/xlsx-analysis/scripts/__pycache__/xlsx_layout.cpython-312.pyc +0 -0
  327. package/skills/xlsx-analysis/scripts/__pycache__/xlsx_toolkit.cpython-312.pyc +0 -0
  328. package/skills/xlsx-analysis/scripts/data_profile.py +391 -0
  329. package/skills/xlsx-analysis/scripts/xlsx_battery.py +389 -0
  330. package/skills/xlsx-analysis/scripts/xlsx_build.py +522 -0
  331. package/skills/xlsx-analysis/scripts/xlsx_check.py +924 -0
  332. package/skills/xlsx-analysis/scripts/xlsx_layout.py +235 -0
  333. package/skills/xlsx-analysis/scripts/xlsx_style.py +28 -66
  334. package/skills/xlsx-analysis/scripts/xlsx_toolkit.py +61 -5
  335. package/skills/xlsx-analysis/trigger-cases.json +59 -0
  336. package/squads/hc-defense.md +47 -0
  337. package/squads/hc-rdarchive.md +110 -0
  338. package/squads/hc-redteam.md +50 -0
  339. package/squads/hc-weekly.md +125 -0
  340. package/src/account.js +1 -1
  341. package/src/acp.js +1 -0
  342. package/src/advisor.js +1 -1
  343. package/src/agent.js +1 -1
  344. package/src/api.js +1 -1
  345. package/src/archaeology.js +1 -0
  346. package/src/ask-ui.js +1 -0
  347. package/src/assets-import.js +1 -1
  348. package/src/autofix.js +1 -1
  349. package/src/automation-tools.js +1 -1
  350. package/src/automation.js +1 -1
  351. package/src/autorun.js +1 -1
  352. package/src/banner.js +1 -1
  353. package/src/capability-probe.js +1 -0
  354. package/src/checkpoints.js +1 -1
  355. package/src/code-tools.js +1 -0
  356. package/src/codeindex.js +1 -1
  357. package/src/codemode.js +1 -0
  358. package/src/command-bridge.js +1 -0
  359. package/src/command-ui.js +1 -0
  360. package/src/commands.js +1 -1
  361. package/src/compaction.js +1 -1
  362. package/src/computer.js +1 -1
  363. package/src/config.js +1 -1
  364. package/src/consult.js +1 -1
  365. package/src/context-report.js +1 -1
  366. package/src/context-window.js +1 -0
  367. package/src/context.js +1 -1
  368. package/src/crew.js +1 -0
  369. package/src/crush.js +1 -0
  370. package/src/daemon.js +1 -1
  371. package/src/decisions.js +1 -1
  372. package/src/depaudit.js +1 -0
  373. package/src/device.js +1 -1
  374. package/src/diagram-draw.js +1 -0
  375. package/src/diagram-layouts.js +1 -0
  376. package/src/diagram-raster.js +1 -0
  377. package/src/diagram.js +1 -0
  378. package/src/dictation.js +1 -0
  379. package/src/diffview.js +1 -1
  380. package/src/doctor.js +1 -1
  381. package/src/docx-tools.js +1 -0
  382. package/src/engineering.js +1 -0
  383. package/src/errkind.js +1 -1
  384. package/src/evidence.js +1 -0
  385. package/src/executors.js +1 -1
  386. package/src/expert-catalog.js +1 -1
  387. package/src/experts-store.js +1 -1
  388. package/src/experts.js +1 -1
  389. package/src/external-agents.js +1 -0
  390. package/src/forks.js +1 -1
  391. package/src/fs-observe.js +1 -0
  392. package/src/gitflow.js +1 -1
  393. package/src/goalround.js +1 -0
  394. package/src/hooks.js +1 -1
  395. package/src/ide.js +1 -1
  396. package/src/input.js +1 -1
  397. package/src/insights.js +1 -1
  398. package/src/jobs.js +1 -0
  399. package/src/kbsync.js +1 -1
  400. package/src/lsp.js +1 -0
  401. package/src/mcp-apps.js +1 -0
  402. package/src/mcp.js +1 -1
  403. package/src/memory.js +1 -1
  404. package/src/notify.js +1 -1
  405. package/src/permissions.js +1 -1
  406. package/src/plan-limits.js +1 -0
  407. package/src/policy.js +1 -0
  408. package/src/pptx-tools.js +1 -0
  409. package/src/presence.js +1 -1
  410. package/src/privatedir.js +1 -0
  411. package/src/pyruntime.js +1 -1
  412. package/src/radar.js +1 -0
  413. package/src/render.js +1 -1
  414. package/src/repl.js +1 -1
  415. package/src/report-tools.js +1 -0
  416. package/src/routing.js +1 -0
  417. package/src/sandbox-probe.js +1 -0
  418. package/src/sandbox-win-launcher.mjs +156 -0
  419. package/src/sandbox.js +1 -0
  420. package/src/scan.js +1 -1
  421. package/src/schedule.js +1 -1
  422. package/src/scopecreep.js +1 -0
  423. package/src/sdk.js +1 -0
  424. package/src/selection.js +1 -0
  425. package/src/session-events.js +1 -0
  426. package/src/session.js +1 -1
  427. package/src/sessionindex.js +1 -0
  428. package/src/sessionlog.js +1 -0
  429. package/src/skill-catalog.js +1 -0
  430. package/src/skill-lint.js +1 -0
  431. package/src/skill-optimize.js +1 -0
  432. package/src/skill-scan.js +1 -0
  433. package/src/skills.js +1 -1
  434. package/src/spill.js +1 -0
  435. package/src/squad.js +1 -1
  436. package/src/subagent.js +1 -1
  437. package/src/surface-state.js +1 -0
  438. package/src/tapd.js +1 -0
  439. package/src/terminal-select.js +1 -0
  440. package/src/terminal.js +1 -0
  441. package/src/test-runner.js +1 -0
  442. package/src/todo.js +1 -1
  443. package/src/toolpipe.js +1 -0
  444. package/src/tools.js +1 -1
  445. package/src/toon.js +1 -0
  446. package/src/transcript.js +1 -1
  447. package/src/tui/app.js +1 -1
  448. package/src/tui/command-menu.js +1 -0
  449. package/src/tui/progress.js +1 -0
  450. package/src/tui/scroll.js +1 -0
  451. package/src/tui/welcome.js +1 -0
  452. package/src/tui/workbench.js +1 -0
  453. package/src/ui-spec.js +1 -0
  454. package/src/uitree.js +1 -0
  455. package/src/uninstall.js +1 -1
  456. package/src/vision.js +1 -1
  457. package/src/visual.js +1 -1
  458. package/src/voice-form.js +1 -0
  459. package/src/voice.js +1 -0
  460. package/src/watch.js +1 -1
  461. package/src/web-audit.js +1 -0
  462. package/src/web-cdp.js +1 -0
  463. package/src/web-inspect.js +1 -0
  464. package/src/websearch.js +1 -0
  465. package/src/weekly.js +1 -0
  466. package/src/workflow.js +1 -0
  467. package/src/worklog.js +1 -0
  468. package/src/xlsx-tools.js +1 -0
  469. package/ui/command-picker.js +79 -0
  470. package/skills/ab-testing/scripts/__pycache__/ab_test.cpython-312.pyc +0 -0
  471. package/skills/accounting-ops/scripts/__pycache__/acct_tools.cpython-312.pyc +0 -0
  472. package/skills/anomaly-detection/scripts/__pycache__/anomaly.cpython-312.pyc +0 -0
  473. package/skills/audit-assist/scripts/__pycache__/audit_sampling.cpython-312.pyc +0 -0
  474. package/skills/banking-credit/scripts/__pycache__/credit_metrics.cpython-312.pyc +0 -0
  475. package/skills/data-report-pro/scripts/__pycache__/bigdata.cpython-312.pyc +0 -0
  476. package/skills/data-wrangling/scripts/__pycache__/join_tools.cpython-312.pyc +0 -0
  477. package/skills/ecommerce-ops/scripts/__pycache__/gmv_decompose.cpython-312.pyc +0 -0
  478. package/skills/funnel-cohort/scripts/__pycache__/funnel.cpython-312.pyc +0 -0
  479. package/skills/management-accounting/scripts/__pycache__/costing.cpython-312.pyc +0 -0
  480. package/skills/manufacturing-quality/scripts/__pycache__/spc.cpython-312.pyc +0 -0
  481. package/skills/marketing-analytics/scripts/__pycache__/rfm.cpython-312.pyc +0 -0
  482. package/skills/optimization-solver/scripts/__pycache__/solver.cpython-312.pyc +0 -0
  483. package/skills/pivot-crosstab/scripts/__pycache__/pivot_tools.cpython-312.pyc +0 -0
  484. package/skills/portfolio-analysis/scripts/__pycache__/portfolio.cpython-312.pyc +0 -0
  485. package/skills/procurement-supply/scripts/__pycache__/supply.cpython-312.pyc +0 -0
  486. package/skills/production-planning/scripts/__pycache__/mrp_capacity.cpython-312.pyc +0 -0
  487. package/skills/project-management/scripts/__pycache__/cpm.cpython-312.pyc +0 -0
  488. package/skills/quant-analysis/scripts/__pycache__/quant.cpython-312.pyc +0 -0
  489. package/skills/real-estate-property/scripts/__pycache__/property_calc.cpython-312.pyc +0 -0
  490. package/skills/regression-forecast/scripts/__pycache__/regress.cpython-312.pyc +0 -0
  491. package/skills/securities-research/scripts/__pycache__/valuation.cpython-312.pyc +0 -0
  492. package/skills/statistical-testing/scripts/__pycache__/stat_tests.cpython-312.pyc +0 -0
  493. package/skills/treasury-mgmt/scripts/__pycache__/cashflow_forecast.cpython-312.pyc +0 -0
package/bin/huicai.js CHANGED
@@ -12,6 +12,12 @@ import { startRepl, runOnce } from '../src/repl.js';
12
12
  import { buildSystemPrompt } from '../src/context.js';
13
13
  import * as sessions from '../src/session.js';
14
14
  import { loadLocalSkills, skillDirs, writeSkillToDir, readSkillDirForPush } from '../src/skills.js';
15
+ import { scanSkillPackage, formatScanReport } from '../src/skill-scan.js';
16
+ import { refreshPlan, isPlanLimitError } from '../src/plan-limits.js';
17
+ import fs from 'node:fs';
18
+ import { lintSkillLibrary } from '../src/skill-lint.js';
19
+ import { tokenize } from '../src/codeindex.js';
20
+ import { createUpdater, displayVersion } from './update.js';
15
21
 
16
22
  // 版本从 package.json 读取(versionDisplay 年月日展示式,与 VSCode 扩展、IDEA 插件一致);勿手改,用 scripts/next-version.cjs
17
23
  const _pkg = createRequire(import.meta.url)('../package.json');
@@ -63,6 +69,9 @@ function parse(argv) {
63
69
  case '--overwrite':
64
70
  flags.overwrite = true;
65
71
  break;
72
+ case '--force-unsafe':
73
+ flags.forceUnsafe = true;
74
+ break;
66
75
  case '--paste':
67
76
  flags.paste = true;
68
77
  break;
@@ -111,62 +120,63 @@ function parse(argv) {
111
120
 
112
121
  function usage() {
113
122
  process.stdout.write(`
114
- ${c.bold('huicai')} — 终端智能体,以 HuiCai_AI 平台为模型后端,在本机执行工具。
123
+ ${c.bold('huicai')} — 终端智能体,以HuiCai_AI平台为模型后端,在本机执行工具。
115
124
 
116
125
  用法:
117
- huicai 进入交互式会话(当前目录)
126
+ huicai进入交互式会话(当前目录)
118
127
  huicai "帮我修复登录bug" 进入会话并先执行该指令
119
128
  huicai -p "运行测试并总结" 一次性执行后退出(脚本/CI;写/执行需 --yolo)
120
129
  cat err.log | huicai -p "分析这段日志" 管道内容自动作为上下文
121
130
  huicai --agent <id> 采用某已发布智能体的人格(工具仍在本机执行)
122
131
  huicai -c ["prompt"] 继续当前目录最近一次会话
123
- huicai -r 从当前目录历史会话中选择恢复
132
+ huicai -r从当前目录历史会话中选择恢复
124
133
  huicai resume <id> 恢复指定会话
125
- huicai sessions [-a] 列出历史会话(-a 跨目录全部)
126
- huicai login 浏览器授权登录(内置平台地址,无需输入网关)
127
- huicai login --paste 无浏览器环境:手动粘贴 API 令牌
128
- huicai logout 退出登录(清除本机保存的令牌)
129
- huicai models 列出可用模型
130
- huicai usage 查看 Token 用量窗口(5小时/7天,按会员等级)
131
- huicai skills 列出本地 + 平台技能(Agent Skills)
132
- huicai daemon 调度守护:按 cron 真正运行 /schedule 登记的定时任务
134
+ huicai sessions [-a] 列出历史会话(-a跨目录全部)
135
+ huicai login浏览器授权登录(内置平台地址,无需输入网关)
136
+ huicai login --paste无浏览器环境:手动粘贴API令牌
137
+ huicai logout退出登录(清除本机保存的令牌)
138
+ huicai models列出可用模型
139
+ huicai usage查看Token用量窗口(5小时/7天,按会员等级)
140
+ huicai skills列出本地 + 平台技能(Agent Skills)
141
+ huicai daemon调度守护:按cron真正运行 /schedule登记的定时任务
133
142
  huicai watch ["*.js"] [-p] 文件监听:变更即触发一个智能体任务(如保存即跑测试)
134
- huicai pr [commit] 自动提交并开 PR(生成规范 commit→建分支→push→gh 开 PR)
135
- huicai kb-sync <id> [ref] 配合 git diff 增量同步知识库,保鲜 RAG(--dry 试运行)
136
- huicai skills pull [name] 平台技能 → 本地(默认 ~/.huicai/skills;--project 放入项目)
137
- huicai skills push <name> 本地技能 → 平台(默认同名跳过;--overwrite 覆盖)
138
- huicai python [setup] 托管 Python 运行时:状态/预装/整包打包(pack)/重置(数据分析与办公文档的地基)
139
- huicai uninstall [--yes] 清理本机所有 CLI 数据(~/.huicai:配置/令牌/会话/记忆/技能…)
140
- huicai help 显示本帮助
143
+ huicai pr [commit] 自动提交并开PR(生成规范commit→建分支→push→gh开PR)
144
+ huicai kb-sync <id> [ref] 配合git diff增量同步知识库,保鲜RAG(--dry试运行)
145
+ huicai skills lint校验本地技能(结构 + 触发路由;离线,不改文件)
146
+ huicai skills pull [name] 平台技能 → 本地(默认 ~/.huicai/skills;--project放入项目)
147
+ huicai skills push <name> 本地技能 → 平台(默认同名跳过;--overwrite覆盖)
148
+ huicai python [setup] 托管Python运行时:状态/预装/整包打包(pack)/重置(数据分析与办公文档的地基)
149
+ huicai uninstall [--yes] 清理本机所有CLI数据(~/.huicai:配置/令牌/会话/记忆/技能…)
150
+ huicai help显示本帮助
141
151
 
142
152
  选项:
143
153
  -m, --model <id> 指定模型(覆盖配置)
144
- --agent <id> 采用平台智能体人格(分享令牌或 agent-xxx)
154
+ --agent <id> 采用平台智能体人格(分享令牌或agent-xxx)
145
155
  --consult <ref> 混合模式:本机驱动模型 + 平台智能体/工作流/数字人/专家团(agent-/workflow-/datahuman-/squad-xxx)作咨询工具
146
- -c, --continue 继续最近一次会话(当前目录)
147
- -r, --resume 选择并恢复历史会话(当前目录)
156
+ -c, --continue继续最近一次会话(当前目录)
157
+ -r, --resume选择并恢复历史会话(当前目录)
148
158
  --base <url> 覆盖内置平台地址(自建 / 联调用)
149
- --key <sk-...> API 令牌(覆盖配置)
159
+ --key <sk-...> API令牌(覆盖配置)
150
160
  --cwd <dir> 指定工作目录(默认当前目录)
151
- --yolo 自动放行写/执行工具(谨慎)
152
- --tui / --plain 强制富 TUI(ink)/ 普通 REPL(默认 TTY 下自动用 TUI)
153
- -p, --print 一次性非交互模式
154
- --output-format <fmt> -p 输出格式:text(默认)| json(结构化,脚本集成)
161
+ --yolo自动放行写/执行工具(谨慎)
162
+ --tui / --plain全屏工作台 / 普通REPL(默认TTY下全屏,非TTY使用普通模式)
163
+ -p, --print一次性非交互模式
164
+ --output-format <fmt> -p输出格式:text(默认)| json(结构化,脚本集成)
155
165
  --max-turns <n> 单回合最大工具轮数(默认 60)
156
166
  --system-prompt <s> 完全替换系统提示词(-p/新会话)
157
167
  --append-system-prompt <s> 在系统提示词末尾追加指示
158
- -h, --help 帮助
159
- -v, --version 版本
168
+ -h, --help帮助
169
+ -v, --version版本
160
170
 
161
171
  交互技巧:
162
- /help 查看命令 · @文件 引用文件(PDF/Word/Excel 等自动解析为文本、图片作为视觉输入) · !命令 直通 shell(输出进上下文)
163
- 模型 -m auto 或 /model auto:按账号自动选择可用模型(与 VSCode 扩展一致)
164
- 自定义命令:.huicai/commands/<名>.md($ARGUMENTS 为参数占位符)
172
+ /help查看命令 · @文件 引用文件(PDF/Word/Excel等自动解析为文本、图片作为视觉输入) · !命令 直通shell(输出进上下文)
173
+ 模型 -m auto或 /model auto:按账号自动选择可用模型(与VSCode扩展一致)
174
+ 自定义命令:.huicai/commands/<名>.md($ARGUMENTS为参数占位符)
165
175
  权限规则:.huicai/settings.json {"permissions":{"allow":["run_bash(git *)"]}}
166
176
 
167
- 会话默认自动保存到 ~/.huicai/sessions(按项目目录归属),随时可 -c/-r 恢复。
177
+ 会话默认自动保存到 ~/.huicai/sessions(按项目目录归属),随时可 -c/-r恢复。
168
178
 
169
- 配置: ${CONFIG_PATH}(或环境变量 HUICAI_BASE_URL / HUICAI_API_KEY / HUICAI_MODEL / HUICAI_MAX_TURNS)
179
+ 配置: ${CONFIG_PATH}(或环境变量HUICAI_BASE_URL / HUICAI_API_KEY / HUICAI_MODEL / HUICAI_MAX_TURNS)
170
180
  `);
171
181
  }
172
182
 
@@ -178,17 +188,17 @@ async function login(flags = {}) {
178
188
  let key = cur.apiKey;
179
189
  if (!flags.paste) {
180
190
  // 默认:直接打开浏览器授权(设备码流),无需任何输入
181
- process.stdout.write(c.bold('\n登录 huicai') + c.gray(` · ${normBase}`) + '\n');
191
+ process.stdout.write(c.bold('\n登录huicai') + c.gray(` · ${normBase}`) + '\n');
182
192
  try {
183
193
  key = await deviceLogin(normBase);
184
194
  } catch (e) {
185
- process.stdout.write(c.yellow(`浏览器授权未完成(${e.message}),可改用 huicai login --paste 手动粘贴令牌。`) + '\n');
195
+ process.stdout.write(c.yellow(`浏览器授权未完成(${e.message}),可改用huicai login --paste手动粘贴令牌。`) + '\n');
186
196
  return;
187
197
  }
188
198
  } else {
189
199
  // 显式 --paste:无浏览器环境下手动粘贴令牌
190
200
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
191
- key = (await new Promise((r) => rl.question(`API 令牌 (sk-huicai-…)${cur.apiKey ? ' [回车保留已保存]' : ''}: `, r))).trim()
201
+ key = (await new Promise((r) => rl.question(`API令牌 (sk-huicai-…)${cur.apiKey ? ' [回车保留已保存]' : ''}: `, r))).trim()
192
202
  || cur.apiKey;
193
203
  rl.close();
194
204
  if (!key) {
@@ -220,15 +230,15 @@ async function login(flags = {}) {
220
230
  saveConfig({ baseUrl: normBase, apiKey: key, model });
221
231
  if (tokenOk) {
222
232
  process.stdout.write(c.green('登录成功') + (model ? c.gray(` · 默认模型 ${model}`) : '') + '\n');
223
- process.stdout.write(c.gray(`已保存到 ${CONFIG_PATH},直接运行 huicai 开始。`) + '\n');
233
+ process.stdout.write(c.gray(`已保存到 ${CONFIG_PATH},直接运行huicai开始。`) + '\n');
224
234
  } else {
225
- process.stdout.write(c.yellow(`令牌已保存到 ${CONFIG_PATH},但校验未通过——请重试 huicai login 或联系管理员。`) + '\n');
235
+ process.stdout.write(c.yellow(`令牌已保存到 ${CONFIG_PATH},但校验未通过——请重试huicai login或联系管理员。`) + '\n');
226
236
  }
227
237
  }
228
238
 
229
239
  function validateAuth(config) {
230
- if (!config.baseUrl) return c.red('未配置平台地址。运行 `huicai login` 或设置 HUICAI_BASE_URL。');
231
- if (!config.apiKey) return c.red('未配置 API 令牌。运行 `huicai login` 或设置 HUICAI_API_KEY。');
240
+ if (!config.baseUrl) return c.red('未配置平台地址。运行 `huicai login` 或设置HUICAI_BASE_URL。');
241
+ if (!config.apiKey) return c.red('未配置API令牌。运行 `huicai login` 或设置HUICAI_API_KEY。');
232
242
  return null;
233
243
  }
234
244
 
@@ -280,7 +290,7 @@ async function cmdUsage(config) {
280
290
  process.stderr.write(c.red('拉取用量失败:平台未返回用量数据(请确认平台已支持 /v1/usage)') + '\n');
281
291
  process.exit(1);
282
292
  }
283
- process.stdout.write(c.bold('Token 用量窗口(按会员等级)') + '\n');
293
+ process.stdout.write(c.bold('Token用量窗口(按会员等级)') + '\n');
284
294
  process.stdout.write(' 近 5 小时:' + fmt(u.used5h, u.limit5h) + '\n');
285
295
  process.stdout.write(' 近 7 天 :' + fmt(u.used7d, u.limit7d) + '\n');
286
296
  if (!u.allowed && u.message) {
@@ -308,7 +318,7 @@ async function cmdPython(config, rest) {
308
318
  if (action === 'status') {
309
319
  const s = py.runtimeStatus(config);
310
320
  const mark = (ok) => (ok ? c.green('✓') : c.yellow('•'));
311
- process.stdout.write(c.bold('托管 Python 运行时') + c.gray('(' + s.dir + ')') + '\n');
321
+ process.stdout.write(c.bold('托管Python运行时') + c.gray('(' + s.dir + ')') + '\n');
312
322
  process.stdout.write(` ${mark(s.uv)} uv ${s.uv ? '已就绪' + (s.uvVersion ? '(' + s.uvVersion + ')' : '') : '未安装'}\n`);
313
323
  process.stdout.write(` ${mark(s.python)} CPython ${s.python ? s.pythonVersion + ' 已就绪' : '未安装'}\n`);
314
324
  process.stdout.write(` ${mark(s.venv)} 虚拟环境 ${s.venv ? s.venvPython : '未创建'}\n`);
@@ -319,7 +329,7 @@ async function cmdPython(config, rest) {
319
329
  const mir = [s.mirrors.bundle && '整包=' + s.mirrors.bundle, s.mirrors.uv && 'uv=' + s.mirrors.uv,
320
330
  s.mirrors.python && 'python=' + s.mirrors.python, s.mirrors.pypi && 'PyPI=' + s.mirrors.pypi].filter(Boolean);
321
331
  if (mir.length) process.stdout.write(c.gray(' 镜像:' + mir.join(' ')) + '\n');
322
- if (!s.ready) process.stdout.write(c.gray(' (huicai python setup 立即安装;或首次数据分析任务时自动安装)') + '\n');
332
+ if (!s.ready) process.stdout.write(c.gray(' (huicai python setup立即安装;或首次数据分析任务时自动安装)') + '\n');
323
333
  return;
324
334
  }
325
335
 
@@ -349,7 +359,7 @@ async function cmdPython(config, rest) {
349
359
  const r = await py.packRuntime({ outDir, config, log: (line) => process.stdout.write(c.gray(' ' + line) + '\n') });
350
360
  process.stdout.write(c.green('✅ 整包完成:') + r.file + c.gray(`(${Math.round(r.size / 1024 / 1024)}MB)`) + '\n');
351
361
  process.stdout.write(c.gray(' 清单已更新:' + r.manifest) + '\n');
352
- process.stdout.write(c.gray(' 托管到静态目录后配置 HUICAI_PYRT_BUNDLE=<基址> 即启用整包直下') + '\n');
362
+ process.stdout.write(c.gray(' 托管到静态目录后配置HUICAI_PYRT_BUNDLE=<基址> 即启用整包直下') + '\n');
353
363
  } catch (e) {
354
364
  process.stderr.write(c.red('打包失败:' + e.message) + '\n');
355
365
  process.exit(1);
@@ -363,11 +373,11 @@ async function cmdPython(config, rest) {
363
373
  process.exit(1);
364
374
  }
365
375
  py.resetRuntime();
366
- process.stdout.write(c.green('✅ 已清空托管 Python 运行时(下次使用时自动重装)') + '\n');
376
+ process.stdout.write(c.green('✅ 已清空托管Python运行时(下次使用时自动重装)') + '\n');
367
377
  return;
368
378
  }
369
379
 
370
- process.stderr.write(c.red(`未知子命令:python ${action}(可用:status / setup / pack [--out 目录] / reset --yes)`) + '\n');
380
+ process.stderr.write(c.red(`未知子命令:python ${action}(可用:status / setup / pack [--out目录] / reset --yes)`) + '\n');
371
381
  process.exit(1);
372
382
  }
373
383
 
@@ -375,6 +385,7 @@ async function cmdPython(config, rest) {
375
385
  * skills 子命令:本地技能与平台云端技能库的查看/同步。
376
386
  * huicai skills 列出本地 + 平台技能
377
387
  * huicai skills pull [name] 平台 → 本地(默认 ~/.huicai/skills;--project 放入项目 .huicai/skills)
388
+ * 落盘前过安全扫描;扫出严重风险即拦截,--force-unsafe 可强行拉取
378
389
  * huicai skills push <name|目录> 本地 → 平台(默认同名跳过;--overwrite 覆盖)
379
390
  */
380
391
  async function cmdSkills(config, args, flags, cwd) {
@@ -382,9 +393,9 @@ async function cmdSkills(config, args, flags, cwd) {
382
393
  const locals = loadLocalSkills(cwd);
383
394
 
384
395
  if (action === 'list') {
385
- process.stdout.write(c.bold('本地技能') + c.gray('(.huicai/skills 与 ~/.huicai/skills)') + '\n');
396
+ process.stdout.write(c.bold('本地技能') + c.gray('(.huicai/skills与 ~/.huicai/skills)') + '\n');
386
397
  if (!locals.length) {
387
- process.stdout.write(c.gray(' (无。huicai skills pull 可从平台拉取)') + '\n');
398
+ process.stdout.write(c.gray(' (无。huicai skills pull可从平台拉取)') + '\n');
388
399
  } else {
389
400
  for (const s of locals) {
390
401
  process.stdout.write(` ${s.name}${s.version ? c.gray(' v' + s.version) : ''}`
@@ -394,7 +405,7 @@ async function cmdSkills(config, args, flags, cwd) {
394
405
  }
395
406
  const problem = validateAuth(config);
396
407
  if (problem) {
397
- process.stdout.write(c.gray('(未登录,跳过平台技能列表;huicai login 后可 pull/push)') + '\n');
408
+ process.stdout.write(c.gray('(未登录,跳过平台技能列表;huicai login后可pull/push)') + '\n');
398
409
  return;
399
410
  }
400
411
  try {
@@ -417,6 +428,30 @@ async function cmdSkills(config, args, flags, cwd) {
417
428
  return;
418
429
  }
419
430
 
431
+ // 校验(纯本地、离线,放在登录门禁之前)
432
+ if (action === 'lint') {
433
+ const roots = args.slice(1).filter((a) => !a.startsWith('--'));
434
+ const targets = roots.length ? roots : skillDirs(cwd).filter((d) => fs.existsSync(d));
435
+ if (!targets.length) {
436
+ process.stdout.write(c.gray('没有可校验的技能库(项目 .huicai/skills与 ~/.huicai/skills都不存在)') + '\n');
437
+ return;
438
+ }
439
+ const rep = lintSkillLibrary(targets, tokenize, { strict: !!flags.strict });
440
+ for (const r of rep.results) {
441
+ if (!r.errors.length && !r.warnings.length) continue;
442
+ process.stdout.write(`${r.errors.length ? c.red('✗') : c.yellow('·')} ${r.name}\n`);
443
+ for (const m of r.errors) process.stdout.write(' ' + c.red('错误 ') + m + '\n');
444
+ for (const m of r.warnings) process.stdout.write(' ' + c.yellow('警告 ') + m + '\n');
445
+ }
446
+ for (const m of rep.route.errors) process.stdout.write(c.red('✗ 触发路由 ') + m + '\n');
447
+ for (const m of rep.route.warnings) process.stdout.write(c.yellow('· 触发路由 ') + m + '\n');
448
+ const { skills, errors, warnings } = rep.counts;
449
+ const verdict = errors ? c.red('未通过') : c.green('通过');
450
+ process.stdout.write(`${verdict} — ${skills} 个技能,${errors} 个错误,${warnings} 个警告\n`);
451
+ if (errors) process.exit(1);
452
+ return;
453
+ }
454
+
420
455
  const problem = validateAuth(config);
421
456
  if (problem) {
422
457
  process.stderr.write(problem + '\n');
@@ -433,13 +468,41 @@ async function cmdSkills(config, args, flags, cwd) {
433
468
  process.stderr.write(c.red(wanted ? `平台上没有技能:${wanted}` : '平台上没有可拉取的文档技能') + '\n');
434
469
  process.exit(1);
435
470
  }
471
+ let blocked = 0;
472
+ // 拉到本地的新技能占会员「技能插件」额度(覆盖已有的同名技能不占):先取最新上限,装满即停
473
+ await refreshPlan(config);
474
+ let limited = '';
475
+ let unpulled = 0;
436
476
  for (const s of targets) {
477
+ const isNew = !fs.existsSync(path.join(baseDir, String(s.name || '').replace(/[^a-zA-Z0-9_-]/g, '-'), 'SKILL.md'));
478
+ if (limited && isNew) { unpulled++; continue; }
437
479
  const detail = await getPlatformSkill(config.baseUrl, config.apiKey, s.id);
438
- const dir = writeSkillToDir(baseDir, detail);
480
+ // 落盘前先过安全扫描(P0-A)。这条路径直接调 writeSkillToDir、不走 installSkillPackage,
481
+ // 所以闸门必须在这里再挡一道——否则 CLI 就是一扇没装门的侧门。
482
+ const scan = scanSkillPackage({ name: s.name, content: detail?.content, files: detail?.files || [] });
483
+ if (scan.verdict === 'blocked' && !flags.forceUnsafe) {
484
+ blocked++;
485
+ process.stderr.write(c.red(`已拦截 ${s.name}:安全扫描发现严重风险,未落盘`) + '\n');
486
+ process.stderr.write(formatScanReport(scan) + '\n');
487
+ process.stderr.write(c.gray('逐条审阅确无问题后,可加 --force-unsafe重试。') + '\n');
488
+ continue;
489
+ }
490
+ let dir;
491
+ try {
492
+ dir = writeSkillToDir(baseDir, detail);
493
+ } catch (e) {
494
+ if (!isPlanLimitError(e)) throw e;
495
+ limited = e.message;
496
+ unpulled++;
497
+ continue;
498
+ }
499
+ const warnNote = scan.counts.warn ? c.yellow(`(安全扫描 ${scan.counts.warn} 项警告)`) : '';
439
500
  process.stdout.write(c.green('已拉取 ') + s.name
440
- + c.gray(`(${detail.files?.length || 0} 附件)→ ${dir}`) + '\n');
501
+ + c.gray(`(${detail.files?.length || 0} 附件)→ ${dir}`) + warnNote + '\n');
441
502
  }
442
- process.stdout.write(c.gray('新会话中生效(系统提示词注入技能目录,load_skill 按需载入)。') + '\n');
503
+ if (blocked) process.stderr.write(c.red(`共 ${blocked} 个技能因安全扫描未被拉取。`) + '\n');
504
+ if (limited) process.stderr.write(c.red(`${limited}(${unpulled} 个技能未拉取)`) + '\n');
505
+ process.stdout.write(c.gray('新会话中生效(系统提示词注入技能目录,load_skill按需载入)。') + '\n');
443
506
  } catch (e) {
444
507
  process.stderr.write(c.red('拉取失败:' + e.message) + '\n');
445
508
  process.exit(1);
@@ -460,7 +523,7 @@ async function cmdSkills(config, args, flags, cwd) {
460
523
  try {
461
524
  payload = readSkillDirForPush(dir);
462
525
  } catch (e) {
463
- process.stderr.write(c.red(`读取技能失败(目录须含 SKILL.md):${e.message}`) + '\n');
526
+ process.stderr.write(c.red(`读取技能失败(目录须含SKILL.md):${e.message}`) + '\n');
464
527
  process.exit(1);
465
528
  }
466
529
  try {
@@ -468,7 +531,7 @@ async function cmdSkills(config, args, flags, cwd) {
468
531
  ...payload, conflict: flags.overwrite ? 'overwrite' : 'skip',
469
532
  });
470
533
  const label = r.status === 'imported' ? '已推送(新建)'
471
- : r.status === 'overwritten' ? '已推送(覆盖同名)' : '已跳过:平台已有同名技能(--overwrite 可覆盖)';
534
+ : r.status === 'overwritten' ? '已推送(覆盖同名)' : '已跳过:平台已有同名技能(--overwrite可覆盖)';
472
535
  process.stdout.write((r.status === 'skipped' ? c.yellow(label) : c.green(label))
473
536
  + c.gray(` · ${payload.filename} → ${config.baseUrl}`) + '\n');
474
537
  for (const w of r.warnings || []) {
@@ -527,15 +590,16 @@ async function main() {
527
590
  process.stdout.write(c.gray('卸载命令本体:npm uninstall -g @huicai/cli') + '\n');
528
591
  return;
529
592
  }
530
- process.stdout.write('将永久删除以下 HuiCai CLI 本机数据(' + info.dir + ',共 ' + fmtSize(info.total) + '):\n');
593
+ process.stdout.write('将永久删除以下HuiCai CLI本机数据(' + info.dir + ',共 ' + fmtSize(info.total) + '):\n');
531
594
  for (const e of info.entries) {
532
- process.stdout.write(' - ' + e.name + (e.kind === 'dir' ? '/' : '') + c.gray(' ' + fmtSize(e.size)) + '\n');
595
+ process.stdout.write(' - ' + e.name + (e.kind === 'dir' ? '/' : '')
596
+ + c.gray(' ' + fmtSize(e.size) + (e.label ? ' ' + e.label : '')) + '\n');
533
597
  }
534
598
  process.stdout.write(c.gray(' 含登录令牌、会话历史、长期记忆、技能与自定义命令等,删除不可撤销。') + '\n');
535
599
  const yes = positional.includes('--yes') || positional.includes('-y') || flags.yolo;
536
600
  if (!yes) {
537
601
  if (!process.stdin.isTTY) {
538
- process.stderr.write(c.red('非交互环境:请加 --yes 确认删除。') + '\n');
602
+ process.stderr.write(c.red('非交互环境:请加 --yes确认删除。') + '\n');
539
603
  process.exit(1);
540
604
  }
541
605
  const ans = await new Promise((resolve) => {
@@ -548,8 +612,8 @@ async function main() {
548
612
  }
549
613
  }
550
614
  const r = purgeData();
551
- process.stdout.write(c.green('✅ 已清理所有 HuiCai CLI 本机数据:' + r.dir) + '\n');
552
- process.stdout.write(c.gray('卸载命令本体:npm uninstall -g @huicai/cli(其 preuninstall 钩子也会自动清理本目录)') + '\n');
615
+ process.stdout.write(c.green('✅ 已清理所有HuiCai CLI本机数据:' + r.dir) + '\n');
616
+ process.stdout.write(c.gray('卸载命令本体:npm uninstall -g @huicai/cli(其preuninstall钩子也会自动清理本目录)') + '\n');
553
617
  return;
554
618
  }
555
619
 
@@ -588,6 +652,15 @@ async function main() {
588
652
  return;
589
653
  }
590
654
 
655
+ if (sub === 'acp') {
656
+ // ACP 服务端:编辑器/自动化客户端经 JSON-RPC over stdio 长驻驱动惠彩。
657
+ // 与 -p 的分工:那个跑完就退出,这个在同一段上下文里连续对话。
658
+ // 注意 stdout 从这一刻起被协议帧独占(acp.js 启动时会把杂音改道 stderr)。
659
+ const { runAcpServer } = await import('../src/acp.js');
660
+ await runAcpServer({ config, cwd, yolo: flags.yolo });
661
+ return;
662
+ }
663
+
591
664
  if (sub === 'daemon') {
592
665
  // 内置调度守护:按 cron 真正运行 /schedule 登记的任务(Ctrl-C 退出)
593
666
  const { runDaemon } = await import('../src/daemon.js');
@@ -641,7 +714,7 @@ async function main() {
641
714
  if (!kbId) {
642
715
  process.stderr.write(c.red('用法:huicai kb-sync <知识库ID> [ref] [--dry]') + '\n'
643
716
  + c.gray(' 例:huicai kb-sync 12 # 同步本地未提交改动到知识库 12') + '\n'
644
- + c.gray(' huicai kb-sync 12 origin/main # 同步相对 origin/main 的改动(CI 常用)') + '\n');
717
+ + c.gray(' huicai kb-sync 12 origin/main # 同步相对origin/main的改动(CI常用)') + '\n');
645
718
  process.exit(1);
646
719
  }
647
720
  const authProblem = validateAuth(config);
@@ -660,12 +733,12 @@ async function main() {
660
733
  }
661
734
  if (r.dry) {
662
735
  for (const f of r.preview) process.stdout.write((f.deleted ? c.red(' − ') : c.green(' + ')) + f.path + '\n');
663
- process.stdout.write(c.gray(`试运行:${r.added} 新增/修改,${r.removed} 删除${r.skipped ? `,跳过 ${r.skipped}` : ''}(加 --dry 之外的调用即实际同步)`) + '\n');
736
+ process.stdout.write(c.gray(`试运行:${r.added} 新增/修改,${r.removed} 删除${r.skipped ? `,跳过 ${r.skipped}` : ''}(加 --dry之外的调用即实际同步)`) + '\n');
664
737
  return;
665
738
  }
666
739
  process.stdout.write(c.green('✅ 知识库已保鲜:') + r.message + '\n');
667
740
  } catch (e) {
668
- process.stderr.write(c.red('✗ kb-sync 失败:' + e.message) + '\n');
741
+ process.stderr.write(c.red('✗ kb-sync失败:' + e.message) + '\n');
669
742
  process.exit(1);
670
743
  }
671
744
  return;
@@ -694,7 +767,7 @@ async function main() {
694
767
  // --consult:混合模式——把平台伪模型作为 consult_platform 工具(本机原始驱动 + 平台编排咨询)
695
768
  if (flags.consult) {
696
769
  if (!/^(agent|workflow|datahuman|squad)-/.test(flags.consult)) {
697
- process.stderr.write(c.red('--consult 需平台伪模型 id:agent-xxx / workflow-xxx / datahuman-xxx(分享码见分享窗口)') + '\n');
770
+ process.stderr.write(c.red('--consult需平台伪模型id:agent-xxx / workflow-xxx / datahuman-xxx(分享码见分享窗口)') + '\n');
698
771
  process.exit(1);
699
772
  }
700
773
  config.consult = flags.consult;
@@ -774,24 +847,32 @@ async function main() {
774
847
  }
775
848
 
776
849
  // 交互式:默认富 TUI(ink,需已安装依赖 + TTY);--plain 强制普通 REPL;TUI 不可用则自动回退
850
+ const updater = process.stdin.isTTY && process.stdout.isTTY ? createUpdater({ current: _pkg.version }) : null;
851
+ const finishUpdate = (result) => {
852
+ updater?.dispose();
853
+ if (result?.updated) process.stdout.write(c.green(`已更新到 v${displayVersion(result.updated)},请重新运行 huicai。登录、历史与配置已保留。\n`));
854
+ };
777
855
  // 偏好顺序:命令行 --tui/--plain > 配置 tui(rich/plain) > auto(TTY 下用 TUI)
778
- const wantTui = flags.tui || config.tui === 'rich'
779
- || (!flags.plain && config.tui !== 'plain' && process.stdout.isTTY && process.stdin.isTTY);
856
+ const wantTui = !flags.plain && process.stdout.isTTY && process.stdin.isTTY && process.env.TERM !== 'dumb'
857
+ && (flags.tui || config.tui !== 'plain');
780
858
  if (wantTui) {
781
- let ran = null;
859
+ let runInk;
782
860
  try {
783
- const { runInk } = await import('../src/tui/app.js');
784
- ran = (await runInk({ config, cwd, session, yolo: flags.yolo, initialPrompt: prompt || null, version: VERSION })) || {};
861
+ ({ runInk } = await import('../src/tui/app.js'));
785
862
  } catch (e) {
786
- process.stderr.write(c.gray('(未启用 TUI:' + e.message + ',回退普通模式)') + '\n');
863
+ process.stderr.write(c.gray('(未启用TUI:' + e.message + ',回退普通模式)') + '\n');
787
864
  }
788
- // 重新登录放在 try 外:登录流程自身失败不该被误读成「TUI 不可用」而回退去开普通 REPL
789
- if (ran) {
865
+ // Only dependency loading may fall back. A runtime failure must never replay
866
+ // the initial prompt after it may already have edited files or run commands.
867
+ if (runInk) {
868
+ const ran = await runInk({ config, cwd, session, yolo: flags.yolo, initialPrompt: prompt || null, version: VERSION, updater });
869
+ finishUpdate(ran);
790
870
  await reloginIfNeeded(ran, flags);
791
871
  return;
792
872
  }
793
873
  }
794
- const r = await startRepl({ config, cwd, yolo: flags.yolo, initialPrompt: prompt || null, session, version: VERSION });
874
+ const r = await startRepl({ config, cwd, yolo: flags.yolo, initialPrompt: prompt || null, session, version: VERSION, updater });
875
+ finishUpdate(r);
795
876
  await reloginIfNeeded(r, flags);
796
877
  }
797
878
 
@@ -834,7 +915,7 @@ async function pickSession(cwd) {
834
915
  function cmdSessions(cwd, all) {
835
916
  const list = sessions.listSessions(all ? null : cwd);
836
917
  if (!list.length) {
837
- process.stdout.write(all ? '暂无历史会话。\n' : '当前目录暂无历史会话(-a/--all 查看全部)。\n');
918
+ process.stdout.write(all ? '暂无历史会话。\n' : '当前目录暂无历史会话(-a/--all查看全部)。\n');
838
919
  return;
839
920
  }
840
921
  for (const s of list) {
@@ -843,7 +924,7 @@ function cmdSessions(cwd, all) {
843
924
  );
844
925
  if (all) process.stdout.write(c.gray(` ${s.cwd || ''}`) + '\n');
845
926
  }
846
- process.stdout.write(c.gray('\n恢复:huicai resume <id> 或 huicai -c(最近一次)\n'));
927
+ process.stdout.write(c.gray('\n恢复:huicai resume <id> 或huicai -c(最近一次)\n'));
847
928
  }
848
929
 
849
930
  main().catch((e) => {
package/bin/update.js ADDED
@@ -0,0 +1,97 @@
1
+ // CLI 更新只由入口启用;IDE 内嵌核心不会自行安装全局软件。
2
+ import { execFile } from 'node:child_process';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { promisify } from 'node:util';
7
+ const exec = promisify(execFile);
8
+ const PACKAGE = '@huicai/cli';
9
+ const stable = (v) => typeof v === 'string' && /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.test(v);
10
+ export function newer(a, b) {
11
+ if (!stable(a) || !stable(b)) return false;
12
+ const aa = a.split('.').map(BigInt), bb = b.split('.').map(BigInt);
13
+ for (let i = 0; i < 3; i++) if (aa[i] !== bb[i]) return aa[i] > bb[i];
14
+ return false;
15
+ }
16
+ export function displayVersion(v) {
17
+ const [year, md, patch] = v.split('.').map(Number);
18
+ const month = Math.floor(md / 100), day = md % 100;
19
+ return year >= 2020 && month >= 1 && month <= 12 && day >= 1 && day <= 31
20
+ ? `${year}.${String(month).padStart(2, '0')}.${String(day).padStart(2, '0')}${patch ? '.' + patch : ''}` : v;
21
+ }
22
+
23
+ // 直接执行 npm 的 JS 入口,兼容 Windows,避免 cmd/shell 插值及命令注入。
24
+ export function npmExecutable(env = process.env) {
25
+ const dirs = [path.dirname(process.execPath), ...(env.PATH || '').split(path.delimiter)];
26
+ for (const dir of dirs) {
27
+ for (const file of ['npm', 'node_modules/npm/bin/npm-cli.js', '../lib/node_modules/npm/bin/npm-cli.js']) {
28
+ try {
29
+ const resolved = fs.realpathSync(path.resolve(dir, file));
30
+ if (resolved.endsWith('npm-cli.js')) return resolved;
31
+ } catch { /* 继续查找同一 Node 安装或 PATH 中的 npm */ }
32
+ }
33
+ }
34
+ throw new Error('未找到 npm,请安装 Node.js 附带的 npm 后重试。');
35
+ }
36
+
37
+ export function createUpdater({ current, packageRoot = fileURLToPath(new URL('..', import.meta.url)), env = process.env, run = exec } = {}) {
38
+ const controller = new AbortController();
39
+ let installing;
40
+ let installAbort;
41
+ const npm = async (args, timeout = 10000, signal = controller.signal) => {
42
+ const result = await run(process.execPath, [npmExecutable(env), ...args], {
43
+ env: { ...env, HUICAI_UPDATING: '1', npm_config_update_notifier: 'false' },
44
+ cwd: path.dirname(process.execPath), timeout, maxBuffer: 1024 * 1024,
45
+ signal, windowsHide: true,
46
+ });
47
+ return result.stdout.trim();
48
+ };
49
+ const check = npm(['view', PACKAGE + '@latest', 'version', '--json', '--fetch-retries=0', '--fetch-timeout=6000'])
50
+ .then((raw) => JSON.parse(raw)).then((version) => newer(version, current) ? version : null)
51
+ .catch(() => null); // 后台检测断网、未发布或损坏响应时静默,不影响启动。
52
+ return {
53
+ check,
54
+ dispose: () => { controller.abort(); installAbort?.abort(); },
55
+ menu: (version) => ({ title: `HuiCai AI 有新版本 v${displayVersion(version)}`, current: 'later', searchable: false,
56
+ options: [{ value: 'update', label: '更新到最新版本', description: '自动安装;保留登录、历史与配置,完成后重新运行 huicai' },
57
+ { value: 'later', label: '稍后', description: '继续当前会话,下次启动时再提醒' }] }),
58
+ install(version, { signal } = {}) {
59
+ if (installing) return installing;
60
+ installAbort = new AbortController();
61
+ const abort = () => installAbort?.abort();
62
+ signal?.addEventListener('abort', abort, { once: true });
63
+ if (signal?.aborted || controller.signal.aborted) installAbort.abort();
64
+ const installSignal = installAbort.signal;
65
+ installing = (async () => {
66
+ if (!newer(version, current)) throw new Error('无有效的新版本,已停止安装。');
67
+ // npm 7+ 不执行卸载钩子;旧 npm 可能在替换包时误删 ~/.huicai。
68
+ const npmVersion = await npm(['--version'], 10000, installSignal);
69
+ if (!/^\d+\./.test(npmVersion) || Number(npmVersion.split('.')[0]) < 7) throw new Error('自动更新需要 npm 7 或更新版本,请先升级 npm。');
70
+ let prefix;
71
+ const root = fs.realpathSync(packageRoot);
72
+ const suffix = path.join('lib', 'node_modules', '@huicai', 'cli');
73
+ const windowsSuffix = path.join('node_modules', '@huicai', 'cli');
74
+ // 已全局安装时固定原安装位置,避免 PATH 上另一个 npm 更新到错误目录。
75
+ if (root.endsWith(path.sep + suffix)) prefix = root.slice(0, -suffix.length);
76
+ else if (process.platform === 'win32' && root.endsWith(path.sep + windowsSuffix)) prefix = root.slice(0, -windowsSuffix.length);
77
+ else prefix = await npm(['prefix', '--global'], 10000, installSignal);
78
+ await npm(['install', '--global', '--prefix', prefix, PACKAGE + '@' + version,
79
+ '--no-audit', '--no-fund', '--fetch-retries=1', '--fetch-timeout=30000'], 300000, installSignal);
80
+ const installedRoot = path.join(prefix, ...(process.platform === 'win32' ? [] : ['lib']), 'node_modules', '@huicai', 'cli');
81
+ const installed = JSON.parse(fs.readFileSync(path.join(installedRoot, 'package.json'), 'utf8'));
82
+ if (installed.version !== version) throw new Error('安装后的版本校验未通过,请重试。');
83
+ // 用真实的新入口确认可启动,而非仅凭 npm 的退出码报告成功。
84
+ await run(process.execPath, [path.join(installedRoot, 'bin', 'huicai.js'), '--version'], {
85
+ env, timeout: 15000, maxBuffer: 65536, windowsHide: true, signal: installSignal,
86
+ });
87
+ return version;
88
+ })().catch((error) => {
89
+ installing = null;
90
+ if (installSignal.aborted) throw new Error('更新已中断,可输入 /update 重试。');
91
+ const denied = /EACCES|EPERM/.test(String(error.stderr || error.message));
92
+ throw new Error(denied ? '安装目录没有写入权限,请使用可写的 npm 全局目录后重试。' : '更新未完成,请检查网络或 npm 配置后重试。' + (error.message?.startsWith('Command failed') ? '' : ` ${error.message}`));
93
+ }).finally(() => { signal?.removeEventListener('abort', abort); installAbort = null; });
94
+ return installing;
95
+ },
96
+ };
97
+ }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@huicai/cli",
3
- "version": "2026.814.0",
4
- "versionDisplay": "2026.08.14",
5
- "description": "在终端运行的智能体 CLI:以 HuiCai_AI 平台的 OpenAI 兼容 /v1 为模型后端,在用户本机执行文件/命令工具。",
3
+ "version": "2026.1021.0",
4
+ "versionDisplay": "2026.10.21",
5
+ "description": "在终端运行的智能体CLI:以HuiCai_AI平台的OpenAI兼容 /v1 为模型后端,在用户本机执行文件/命令工具。",
6
6
  "type": "module",
7
7
  "bin": {
8
8
  "huicai": "bin/huicai.js"
@@ -11,21 +11,32 @@
11
11
  "node": ">=18"
12
12
  },
13
13
  "files": [
14
+ "LICENSE",
15
+ "README.md",
14
16
  "bin",
15
- "src",
16
17
  "skills",
17
18
  "squads",
18
- "README.md",
19
- "LICENSE"
19
+ "src",
20
+ "ui"
20
21
  ],
21
22
  "scripts": {
22
23
  "start": "node bin/huicai.js",
23
24
  "check": "node --check bin/huicai.js",
25
+ "gates": "node scripts/gates/run-gates.cjs local",
26
+ "gates:prepush": "node scripts/gates/run-gates.cjs pre-push",
27
+ "gates:ci": "node scripts/gates/run-gates.cjs ci",
28
+ "gen:catalogs": "node scripts/gates/gen-tool-catalog.cjs --write && node scripts/gates/gen-command-catalog.cjs --write",
24
29
  "test": "node --test --test-concurrency=1 test/*.test.mjs",
25
30
  "version:next": "node scripts/next-version.cjs",
26
31
  "pack:release": "node scripts/pack-release.cjs",
27
32
  "preuninstall": "node bin/preuninstall.cjs",
28
- "prepublishOnly": "node --check bin/huicai.js"
33
+ "prepublishOnly": "npm run gates:ci",
34
+ "battery:weekly": "node scripts/weekly-battery.mjs",
35
+ "battery:web": "node scripts/web-battery.mjs",
36
+ "battery:report": "node scripts/report-battery.mjs",
37
+ "mutest:weekly": "node scripts/weekly-mutest.mjs",
38
+ "lint:skills": "node scripts/skill-lint.cjs --strict --quiet",
39
+ "optimize:skill": "node scripts/skill-optimize.cjs"
29
40
  },
30
41
  "keywords": [
31
42
  "cli",
@@ -51,6 +62,14 @@
51
62
  },
52
63
  "dependencies": {
53
64
  "ink": "^7.1.0",
54
- "react": "^19.2.7"
65
+ "react": "^19.2.7",
66
+ "string-width": "^7.2.0",
67
+ "strip-ansi": "^7.2.0",
68
+ "wrap-ansi": "^9.0.2"
69
+ },
70
+ "optionalDependencies": {
71
+ "@deepseek-ai/node-addon-landlock-run": "^0.1.0",
72
+ "koffi": "^2.9.0",
73
+ "node-pty": "^1.1.0"
55
74
  }
56
75
  }