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