@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
@@ -0,0 +1,384 @@
1
+ # PPT 版式计算内核(pptx_deck 建版 / pptx_check 体检 共用同一套度量)。
2
+ #
3
+ # 为什么必须共用:建版时算"这段字放不放得下"和体检时算"这段字有没有溢出",
4
+ # 只要用两套度量,就一定会出现"生成端说没事、体检端说溢出"的自相矛盾。
5
+ # 一份度量、两个方向用——这是本模块存在的唯一理由。
6
+ #
7
+ # 度量口径(微软雅黑 / 苹方,播放端渲染):
8
+ # · 字宽按 em 表逐字累加(中日韩全角 1.0em,数字 0.55em,小写 0.52em…);
9
+ # · 行高 1.32×字号(雅黑 ascender 2167 + descender 536 / unitsPerEm 2048);
10
+ # · 文本框内边距默认 左右 0.1"、上下 0.05"(PowerPoint 默认值)。
11
+ # 估算不可能与真实排版逐像素一致,所以判溢出留了 TOL 容差,且报告里一律带出
12
+ # "估算高 vs 可用高"的具体数字,让人能自己判断,而不是只丢一个结论。
13
+
14
+ import re
15
+
16
+ EMU_IN = 914400 # 1 英寸 = 914400 EMU
17
+ PT_IN = 72.0 # 1 英寸 = 72 磅
18
+ EMU_PT = EMU_IN / PT_IN # 1 磅 = 12700 EMU
19
+
20
+ LINE_H = 1.34 # 单倍行距 ≈ 1.34 × 字号(雅黑 (2167+536)/2048=1.32,苹方/黑体略高,取上沿)
21
+ WRAP_SAFETY = 0.98 # 建版侧折行留 2% 余量:字宽估算差一点就可能多折一行,多折一行就是溢出
22
+ INSET_LR = 0.1 * PT_IN # 文本框默认左右内边距(磅)
23
+ INSET_TB = 0.05 * PT_IN # 文本框默认上下内边距(磅)
24
+ TOL = 1.02 # 溢出容差:估算超出可用空间 2% 以内不报(度量误差带)
25
+
26
+ # ── 字宽表(em)────────────────────────────────────────────────────────────
27
+ # 取值不是拍脑袋,是量出来的:对微软雅黑(Windows 播放端的目标字体,unitsPerEm 2048)
28
+ # 与 macOS 上的替换字体(华文黑体 / 冬青黑 / 宋体)逐类实测 advance 后,
29
+ # 取"略宽于主流值"的一档——**宁可略估宽,不可估窄**:
30
+ # 估宽了最多是提前降一号字,估窄了就是"说装得下、实际被切掉",那才是要命的。
31
+ # 校准脚本见 pptx_layout.py --calibrate(本机有中文字体时可重跑)。
32
+ W_CJK = 1.0
33
+ W_DIGIT = 0.58 # 雅黑 0.550 / 华文黑 0.554 / 冬青 0.657
34
+ W_UPPER = 0.68 # 雅黑 0.635 / 华文黑 0.643 / 冬青 0.708
35
+ W_LOWER = 0.56 # 雅黑 0.537 / 华文黑 0.541 / 冬青 0.552
36
+ W_SPACE = 0.31 # 雅黑 0.264 / 华文黑 0.250 / 冬青 0.333
37
+ W_NARROW = 0.32
38
+ W_WIDE = 0.87
39
+
40
+ NARROW = set(".,;:!|'`iIljtf()[]{}-")
41
+ WIDE = set("@%&WMmw#")
42
+
43
+
44
+ def _full_width(cp):
45
+ return (
46
+ 0x1100 <= cp <= 0x115F or 0x2E80 <= cp <= 0xA4CF or 0xAC00 <= cp <= 0xD7A3
47
+ or 0xF900 <= cp <= 0xFAFF or 0xFE30 <= cp <= 0xFE6F or 0xFF00 <= cp <= 0xFF60
48
+ or 0xFFE0 <= cp <= 0xFFE6 or 0x3000 <= cp <= 0x303F
49
+ )
50
+
51
+
52
+ def char_em(ch):
53
+ """单字符宽度(em)。"""
54
+ cp = ord(ch)
55
+ if ch == ' ':
56
+ return W_SPACE
57
+ if ch == '\t':
58
+ return W_SPACE * 4
59
+ if _full_width(cp):
60
+ return W_CJK
61
+ if cp > 0xFFFF: # emoji 等星平面字符
62
+ return 1.15
63
+ if ch in NARROW:
64
+ return W_NARROW
65
+ if ch in WIDE:
66
+ return W_WIDE
67
+ if '0' <= ch <= '9':
68
+ return W_DIGIT
69
+ if 'A' <= ch <= 'Z':
70
+ return W_UPPER
71
+ if 'a' <= ch <= 'z':
72
+ return W_LOWER
73
+ if cp < 0x2E80:
74
+ return W_LOWER
75
+ return W_CJK
76
+
77
+
78
+ def measure(text, size, bold=False):
79
+ """估算一段文本的渲染宽度(磅)。size 为字号(磅)。"""
80
+ if not text:
81
+ return 0.0
82
+ em = 0.0
83
+ for ch in str(text):
84
+ em += char_em(ch)
85
+ return em * size * (1.035 if bold else 1.0)
86
+
87
+
88
+ # 不能出现在行首 / 行尾的标点(中西文)
89
+ NO_START = set(',。、;:?!)」』】》”’%,.;:?!)]}>')
90
+ NO_END = set('(「『【《“‘([{<')
91
+
92
+ _TOKEN = re.compile(r'[A-Za-z0-9_@#$%\'\-\.]+\s*|\s+|.', re.S)
93
+
94
+
95
+ def tokenize(s):
96
+ """分词:全角字符各自成 token;西文按「词 + 尾随空格」成 token。"""
97
+ out = []
98
+ for m in _TOKEN.finditer(s):
99
+ t = m.group(0)
100
+ if len(t) == 1 or not t[0].isascii():
101
+ # 单字符或首字非 ASCII:逐字拆(中文按字断行)
102
+ for ch in t:
103
+ out.append(ch)
104
+ else:
105
+ out.append(t)
106
+ return out
107
+
108
+
109
+ def wrap(text, size, max_w, bold=False):
110
+ """按最大宽度折行(中文按字断、西文按词断,含禁头禁尾标点处理)。返回行数组。"""
111
+ raw = str(text if text is not None else '').replace('\r', '')
112
+ if not raw:
113
+ return []
114
+ if max_w <= 0:
115
+ return raw.split('\n')
116
+ out = []
117
+ for para in raw.split('\n'):
118
+ if not para.strip():
119
+ out.append('')
120
+ continue
121
+ line, line_w = '', 0.0
122
+ for tk in tokenize(para):
123
+ w = measure(tk, size, bold)
124
+ if line_w > 0 and line_w + w > max_w:
125
+ carry = ''
126
+ if line and line[-1] in NO_END: # 行尾禁尾标点 → 连它一起挪下行
127
+ carry, line = line[-1], line[:-1]
128
+ out.append(line)
129
+ line = carry + tk
130
+ line_w = measure(line, size, bold)
131
+ elif line_w == 0 and w > max_w:
132
+ buf = '' # 单个超长词(长标识符/URL):硬切
133
+ for ch in tk:
134
+ if measure(buf + ch, size, bold) > max_w and buf:
135
+ out.append(buf)
136
+ buf = ''
137
+ buf += ch
138
+ line, line_w = buf, measure(buf, size, bold)
139
+ else:
140
+ line += tk
141
+ line_w += w
142
+ if out and line and line[0] in NO_START: # 禁头标点回拉上一行
143
+ out[-1] += line[0]
144
+ line = line[1:]
145
+ line_w = measure(line, size, bold)
146
+ if line:
147
+ out.append(line)
148
+ return out
149
+
150
+
151
+ def wrap_segments(segs, max_w):
152
+ """多段(字号/粗细各异)混排折行。segs=[(text,size,bold)],返回 [(行文本, 行高磅)]。
153
+
154
+ 真实幻灯片里一段话常混着不同字号的 run(正文 + 强调数字),
155
+ 按最大字号一刀切会把高度算虚。这里按 token 逐个累加,行高取该行最大字号。
156
+ """
157
+ lines = []
158
+ cur, cur_w, cur_size = '', 0.0, 0.0
159
+ for text, size, bold in segs:
160
+ for part_i, para in enumerate(str(text if text is not None else '').replace('\r', '').split('\n')):
161
+ if part_i > 0: # 段内硬换行
162
+ lines.append((cur, max(cur_size, size)))
163
+ cur, cur_w, cur_size = '', 0.0, 0.0
164
+ for tk in tokenize(para):
165
+ w = measure(tk, size, bold)
166
+ if cur_w > 0 and cur_w + w > max_w:
167
+ lines.append((cur, max(cur_size, size)))
168
+ cur, cur_w, cur_size = tk, w, size
169
+ else:
170
+ cur += tk
171
+ cur_w += w
172
+ cur_size = max(cur_size, size)
173
+ if cur or not lines:
174
+ lines.append((cur, cur_size or 18.0))
175
+ return lines
176
+
177
+
178
+ def text_height(lines, line_spacing=1.0):
179
+ """行数组(wrap_segments 结果)→ 总高(磅)。"""
180
+ return sum(h * LINE_H * line_spacing for _, h in lines)
181
+
182
+
183
+ def fit_size(text, box_w, box_h, hi=24.0, lo=14.0, bold=False, step=1.0, line_spacing=1.0):
184
+ """在 [lo, hi] 内找能装进 box 的最大字号;装不下返回 lo(调用方据此决定拆页)。"""
185
+ s = hi
186
+ while s > lo:
187
+ ls = wrap_segments([(text, s, bold)], box_w)
188
+ if text_height(ls, line_spacing) <= box_h:
189
+ return s
190
+ s -= step
191
+ return lo
192
+
193
+
194
+ def clip(text, size, max_w, max_lines, bold=False):
195
+ """按最大行数裁断并加省略号(固定高度的标签框用)。装得下就原样返回。"""
196
+ lines = wrap(text, size, max_w, bold)
197
+ if len(lines) <= max_lines:
198
+ return str(text if text is not None else '')
199
+ kept = lines[:max_lines]
200
+ last = kept[-1]
201
+ while last and measure(last + '…', size, bold) > max_w:
202
+ last = last[:-1]
203
+ kept[-1] = (last or kept[-1][:2]) + '…'
204
+ return '\n'.join(kept)
205
+
206
+
207
+ def fits(text, size, box_w, box_h, bold=False, line_spacing=1.0):
208
+ ls = wrap_segments([(text, size, bold)], box_w)
209
+ return text_height(ls, line_spacing) <= box_h
210
+
211
+
212
+ # ── 几何 ────────────────────────────────────────────────────────────────────
213
+ class Rect:
214
+ """矩形(单位任意,本库内统一用英寸)。"""
215
+
216
+ __slots__ = ('x', 'y', 'w', 'h')
217
+
218
+ def __init__(self, x, y, w, h):
219
+ self.x, self.y, self.w, self.h = float(x), float(y), float(w), float(h)
220
+
221
+ @property
222
+ def right(self):
223
+ return self.x + self.w
224
+
225
+ @property
226
+ def bottom(self):
227
+ return self.y + self.h
228
+
229
+ @property
230
+ def area(self):
231
+ return max(0.0, self.w) * max(0.0, self.h)
232
+
233
+ def inset(self, dx, dy=None):
234
+ dy = dx if dy is None else dy
235
+ return Rect(self.x + dx, self.y + dy, self.w - 2 * dx, self.h - 2 * dy)
236
+
237
+ def intersect(self, o):
238
+ x, y = max(self.x, o.x), max(self.y, o.y)
239
+ r, b = min(self.right, o.right), min(self.bottom, o.bottom)
240
+ return Rect(x, y, max(0.0, r - x), max(0.0, b - y))
241
+
242
+ def overlap_ratio(self, o):
243
+ """重叠面积 / 两者中较小者的面积(0~1)。"""
244
+ a = self.intersect(o).area
245
+ m = min(self.area, o.area)
246
+ return 0.0 if m <= 0 else a / m
247
+
248
+ def contains(self, o, tol=0.0):
249
+ return (self.x - tol <= o.x and self.y - tol <= o.y
250
+ and self.right + tol >= o.right and self.bottom + tol >= o.bottom)
251
+
252
+ def __repr__(self):
253
+ return f'Rect({self.x:.2f},{self.y:.2f},{self.w:.2f}×{self.h:.2f})'
254
+
255
+
256
+ def contain_fit(nat_w, nat_h, box):
257
+ """按原始宽高比等比放进 box 并居中(绝不拉伸——图片变形的根治法)。"""
258
+ if nat_w <= 0 or nat_h <= 0:
259
+ return Rect(box.x, box.y, box.w, box.h)
260
+ s = min(box.w / nat_w, box.h / nat_h)
261
+ w, h = nat_w * s, nat_h * s
262
+ return Rect(box.x + (box.w - w) / 2, box.y + (box.h - h) / 2, w, h)
263
+
264
+
265
+ # ── 配色与对比度 ────────────────────────────────────────────────────────────
266
+ # 配色按**角色**定义,而不是"一堆好看的颜色":每个角色都写明"画在什么底上",
267
+ # 于是对比度可以被计算、被保证——深色主题也就自然成立(页底、卡片底一起翻)。
268
+ # bg 页底 / head 标题字 / text 正文字 / muted 次要字(都画在 bg 上)
269
+ # primary 大色块填充 / on_primary 画在其上的字
270
+ # light 卡片浅底填充 / on_light 画在其上的字
271
+ # accent 强调线与小色块
272
+ THEMES = {
273
+ 'navy': dict(bg='FFFFFF', head='1F4E79', text='2F3437', muted='5F6A73',
274
+ primary='1F4E79', on_primary='FFFFFF', light='DEEBF7', on_light='1B3A57', accent='2E75B6'),
275
+ 'tech': dict(bg='FFFFFF', head='4B2E83', text='2F3437', muted='605A6B',
276
+ primary='4B2E83', on_primary='FFFFFF', light='EDE7FB', on_light='3B2467', accent='7C4DDA'),
277
+ 'mono': dict(bg='FFFFFF', head='2B2B2B', text='2F3437', muted='5E5E5E',
278
+ primary='2B2B2B', on_primary='FFFFFF', light='F1F1F1', on_light='2B2B2B', accent='595959'),
279
+ 'warm': dict(bg='FFFFFF', head='9C4708', text='3B3B3B', muted='6E5B4C',
280
+ primary='9C4708', on_primary='FFFFFF', light='FBE5D6', on_light='7A3706', accent='C55A11'),
281
+ 'green': dict(bg='FFFFFF', head='176346', text='2F3437', muted='566B60',
282
+ primary='176346', on_primary='FFFFFF', light='DFF3EA', on_light='12513A', accent='2FA37A'),
283
+ 'dark': dict(bg='0F172A', head='8FC2FF', text='E6EDF6', muted='A9B6C6',
284
+ primary='111C2E', on_primary='FFFFFF', light='1E2A3F', on_light='E6EDF6', accent='5AA9FF'),
285
+ }
286
+
287
+
288
+ def hex_rgb(s):
289
+ s = str(s or '').lstrip('#')
290
+ if len(s) != 6:
291
+ return None
292
+ try:
293
+ return tuple(int(s[i:i + 2], 16) for i in (0, 2, 4))
294
+ except ValueError:
295
+ return None
296
+
297
+
298
+ def _lin(c):
299
+ c = c / 255.0
300
+ return c / 12.92 if c <= 0.03928 else ((c + 0.055) / 1.055) ** 2.4
301
+
302
+
303
+ def luminance(rgb):
304
+ r, g, b = rgb
305
+ return 0.2126 * _lin(r) + 0.7152 * _lin(g) + 0.0722 * _lin(b)
306
+
307
+
308
+ def contrast(fg, bg):
309
+ """WCAG 对比度(1~21)。任一色解析不出返回 None(宁可不报,也不瞎报)。"""
310
+ if not fg or not bg:
311
+ return None
312
+ a, b = luminance(fg), luminance(bg)
313
+ hi, lo = max(a, b), min(a, b)
314
+ return (hi + 0.05) / (lo + 0.05)
315
+
316
+
317
+ def readable_on(bg_hex):
318
+ """给定底色,返回可读的前景色(深底出白字、浅底出深字)。"""
319
+ rgb = hex_rgb(bg_hex) or (255, 255, 255)
320
+ return 'FFFFFF' if luminance(rgb) < 0.42 else '2F3437'
321
+
322
+
323
+ def pick_fg(bg, prefer=(), min_ratio=4.5):
324
+ """在给定底色上挑一个对比度达标的前景色:按 prefer 顺序试,都不达标就退到黑/白。
325
+
326
+ 配色不该靠"看着还行",尤其是浅底浅字这种在屏幕上勉强、投影上直接消失的组合。
327
+ 建版时每次写字都过一遍这里,产物就不可能出现对比度不足。
328
+ """
329
+ b = hex_rgb(bg)
330
+ for c in list(prefer) + ['2F3437', 'FFFFFF', '000000']:
331
+ if c and (contrast(hex_rgb(c), b) or 0) >= min_ratio:
332
+ return c
333
+ return readable_on(bg)
334
+
335
+
336
+ def _calibrate(font_paths=(), corpus=()):
337
+ """把字宽表与真实字体对一遍(需要 Pillow 且本机有中文字体)。
338
+
339
+ 这张表迟早会被质疑"数字是哪来的"。答案是量出来的,而且随时可以重量:
340
+ python pptx_layout.py --calibrate
341
+ 输出每条语料的"估算 vs 真实"偏差;**低估**(负值)多且大就该调宽字宽表。
342
+ """
343
+ from PIL import ImageFont
344
+ import glob
345
+ paths = list(font_paths) or [p for p in glob.glob('/System/Library/Fonts/**/*.tt*', recursive=True)
346
+ + glob.glob('C:/Windows/Fonts/*.tt*')
347
+ + glob.glob('/usr/share/fonts/**/*.tt*', recursive=True)
348
+ if any(k in p for k in ('Heiti', 'Hiragino', 'PingFang', 'msyh', 'simhei', 'Noto'))]
349
+ corpus = list(corpus) or [
350
+ '营收 3.6 亿元,同比增长 18%', '毛利率 32.5%,环比 +1.2pct', '华东区新签 12 个大客户',
351
+ 'Q3 OKR 复盘与下季度规划', 'deployment pipeline 全链路可观测',
352
+ '这是一条相当长的要点内容,用来验证折行与溢出判定是否准确无误',
353
+ ]
354
+ out = []
355
+ for path in paths:
356
+ try:
357
+ ft = ImageFont.truetype(path, 1000)
358
+ # 真有中文字形才算数:只看 advance 会把一堆没有汉字的 Noto 分支字体
359
+ # 也当成中文字体(它们对缺字返回 .notdef 的宽度,同样 > 0)
360
+ # 真有中文字形才算数:拿一个私用区码位当"缺字"参照,字形位图一样就说明
361
+ # 这个字体根本没有汉字(只看 advance 会把一堆 Noto 分支字体误判成中文字体)
362
+ # 真有中文字形才算数:拿一个私用区码位当"缺字"参照,画出来一样就说明
363
+ # 这个字体根本没有汉字(只看 advance 会把一堆 Noto 分支字体误判成中文字体)
364
+ if bytes(ft.getmask('慧')) == bytes(ft.getmask('\ue123')):
365
+ continue
366
+ except Exception:
367
+ continue
368
+ errs = [(measure(t, 1000) - ft.getlength(t)) / max(1.0, ft.getlength(t)) for t in corpus]
369
+ out.append((path.split('/')[-1], min(errs), sum(errs) / len(errs), max(errs)))
370
+ return out
371
+
372
+
373
+ if __name__ == '__main__':
374
+ import sys as _s
375
+ if '--calibrate' in _s.argv:
376
+ rows = _calibrate()
377
+ if not rows:
378
+ print('本机未找到中文字体,跳过校准。')
379
+ for name, lo, avg, hi in rows:
380
+ # -5% 以内是接受带(建版侧还有 WRAP_SAFETY 兜 2%),超了才真该调表
381
+ flag = ' ← 低估超接受带,需调宽字宽表' if lo < -0.05 else ''
382
+ print(f'{name:28} 偏差 最低 {lo * 100:+.1f}% 平均 {avg * 100:+.1f}% 最高 {hi * 100:+.1f}%{flag}')
383
+ else:
384
+ print(__doc__ or 'pptx_layout:版式度量内核。用 --calibrate 校准字宽表。')
@@ -0,0 +1,15 @@
1
+ {
2
+ "skill": "pptx-author",
3
+ "purpose": "触发行为规格。CI 按词法跑:正样例须在描述词汇上明显压过近似负样例,且路由到自己。改 description 后必须重跑 skill-lint route。",
4
+ "intentionalOverlap": ["slides-html"],
5
+ "cases": [
6
+ { "id": "direct-ppt", "prompt": "帮我做个 PPT 汇报材料", "shouldTrigger": true },
7
+ { "id": "pptx-file", "prompt": "生成一个 pptx 演示文稿,讲季度经营情况", "shouldTrigger": true },
8
+ { "id": "slides-plain", "prompt": "做几页幻灯片把这个方案讲清楚", "shouldTrigger": true },
9
+ { "id": "check-layout", "prompt": "检查这个 PPT 的排版版式有没有问题", "shouldTrigger": true },
10
+ { "id": "fix-deck", "prompt": "演示文稿文字溢出、元素重叠,修复版式", "shouldTrigger": true },
11
+ { "id": "near-miss-word", "prompt": "帮我写一份 Word 项目总结报告", "shouldTrigger": false },
12
+ { "id": "near-miss-excel", "prompt": "把这张表做成透视表看看趋势", "shouldTrigger": false },
13
+ { "id": "near-miss-contract", "prompt": "帮我审一下这份合同", "shouldTrigger": false }
14
+ ]
15
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "skill": "pr-comms",
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,31 @@
1
+ {
2
+ "skill": "procurement-supply",
3
+ "cases": [
4
+ {
5
+ "id": "pos-1",
6
+ "prompt": "做询比价分析和供应商评估评分卡",
7
+ "shouldTrigger": true
8
+ },
9
+ {
10
+ "id": "pos-2",
11
+ "prompt": "ABC 库存分析,呆滞料怎么处理",
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
+ "lexical": false
24
+ },
25
+ {
26
+ "id": "neg-2",
27
+ "prompt": "写一份物流运费对账",
28
+ "shouldTrigger": false
29
+ }
30
+ ]
31
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "skill": "product-design",
3
+ "cases": [
4
+ {
5
+ "id": "pos-1",
6
+ "prompt": "写个 PRD 产品需求文档",
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
+ "lexical": false
24
+ },
25
+ {
26
+ "id": "neg-2",
27
+ "prompt": "写一份项目立项申请",
28
+ "shouldTrigger": false
29
+ }
30
+ ]
31
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "skill": "production-planning",
3
+ "cases": [
4
+ {
5
+ "id": "pos-1",
6
+ "prompt": "排产,这个交期能不能接",
7
+ "shouldTrigger": true
8
+ },
9
+ {
10
+ "id": "pos-2",
11
+ "prompt": "MRP 净需求运算和产能负荷怎么算",
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
+ "lexical": false
24
+ },
25
+ {
26
+ "id": "neg-2",
27
+ "prompt": "写一份设备保养计划",
28
+ "shouldTrigger": false
29
+ }
30
+ ]
31
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "skill": "project-management",
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
+ "lexical": false
24
+ },
25
+ {
26
+ "id": "neg-2",
27
+ "prompt": "写一份产品需求文档",
28
+ "shouldTrigger": false
29
+ }
30
+ ]
31
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "skill": "project-proposal",
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
+ "lexical": false
24
+ },
25
+ {
26
+ "id": "neg-2",
27
+ "prompt": "写一份商业计划书",
28
+ "shouldTrigger": false
29
+ }
30
+ ]
31
+ }
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: prose-standard
3
+ description: 判断一段注释/文档/提示词/报错文案该写多少、哪些必须写、哪些是废话。当用户说"注释太多/太少""这段说明写得怎么样""帮我精简一下文档""审查一下这些注释",或你自己在写注释与 JSDoc 拿不准该写到什么程度时使用。核心判据是「契约」:调用方依赖的义务与不变式必须写,代码已经说清的一律不写。
4
+ version: 1.0.0
5
+ ---
6
+
7
+ # 散文标准:写够契约,然后删掉其余
8
+
9
+ 一句话方法:**先把契约写足,再把推理转录、重复和装饰删干净。**
10
+
11
+ ## 什么是「契约」
12
+
13
+ 契约 = 某一方**依赖**的东西:义务、不变式、前置/后置条件、兼容性承诺。
14
+ 判断某句话该不该留,问:**去掉它之后,调用方/实现方/消费方会不会做错事?**
15
+
16
+ - 会 → 是契约,必须留(哪怕它很长)。
17
+ - 不会 → 是装饰,删掉(哪怕它很短)。
18
+
19
+ 长度不是判据。一段三十行、句句在讲「为什么必须这样、否则会怎样」的注释是资产;
20
+ 一行「// 设置 x 为 1」是负债。
21
+
22
+ ## 必须写的四类
23
+
24
+ 1. **非显然的义务**:调用方必须先做什么、不能做什么。
25
+ (「必须先 read_file 再 write_file,否则……」)
26
+ 2. **不变式**:这段代码始终为真、且靠人维护的性质。
27
+ (「这一段以下不要再添加稳定内容」)
28
+ 3. **反直觉的取舍**:为什么不用那个看起来更明显的做法。
29
+ **写成反事实,不写成变更史**——见 [trim-cot-leakage](../trim-cot-leakage/SKILL.md) 第 3 类。
30
+ 4. **失败语义**:出错时会发生什么、调用方该怎么办、什么情况下不该重试。
31
+
32
+ ## 一律不写的五类
33
+
34
+ 1. 代码已经说清的(`// 递增计数器` 配 `count++`)。
35
+ 2. 控制流复述(「先 A,然后 B,最后 C」)。
36
+ 3. 对着评审者的自辩(「这里的类型转换是安全的,因为……」——
37
+ 要么写清让它安全的那条不变式,要么删掉)。
38
+ 4. 犹豫与占位(「暂时应该够用」「先这样」)——升级成 `TODO`/`FIXME` 并写清真实边界,或删。
39
+ 5. 装饰性分节、重复的标题、把同一件事换个说法再说一遍。
40
+
41
+ ## 用法
42
+
43
+ 1. **先要范围**。没有明确范围就问,别自作主张扫全仓。
44
+ 2. **逐段判定**,每段给出三选一:`保留` / `重写为契约` / `删除`,并写明理由属于上面哪一条。
45
+ 3. **审查任务只报不改**;用户明确说了「改」「精简」「修」才动手。
46
+ 4. 报错文案、工具描述、界面提示同样适用——它们也是给人读的散文,
47
+ 而且**读它们的人正处在出错的当口**,比注释更需要「结论 + 下一步」。
48
+
49
+ ## 与相邻技能的分工
50
+
51
+ - 这条管**该写什么、写多少**。
52
+ - [trim-cot-leakage](../trim-cot-leakage/SKILL.md) 管**清掉写作过程留下的痕迹**。
53
+ - [eng-docs](../eng-docs/SKILL.md) 管**放在哪一层文档里、篇幅上限是多少**。
@@ -0,0 +1,23 @@
1
+ {
2
+ "skill": "prose-standard",
3
+ "purpose": "触发行为规格。负样例分两类:不同词汇的近邻走词法层(CI 跑),同词汇不同意图的近邻标 lexical:false 归行为层。",
4
+ "cases": [
5
+ { "id": "too-many-comments", "prompt": "这个文件注释是不是太多了,帮我看看哪些该留哪些是废话", "shouldTrigger": true },
6
+ { "id": "judge-doc-quality", "prompt": "这段说明写得怎么样,该写的契约写全了吗", "shouldTrigger": true },
7
+ { "id": "trim-prose", "prompt": "帮我精简一下这几段注释,别把有用的信息删掉", "shouldTrigger": true },
8
+ { "id": "error-message-wording", "prompt": "这条报错文案该写多少信息才够用户判断下一步", "shouldTrigger": true },
9
+ {
10
+ "id": "near-miss-translate",
11
+ "prompt": "把这份英文说明翻译成中文",
12
+ "shouldTrigger": false,
13
+ "note": "词汇不重合(翻译 vs 契约/精简),词法层能干净分开。"
14
+ },
15
+ {
16
+ "id": "near-miss-write-doc",
17
+ "prompt": "给这个模块补一份使用文档",
18
+ "shouldTrigger": false,
19
+ "lexical": false,
20
+ "note": "与「判断该写多少」共用「文档/写」——同词汇不同意图(写新文档 vs 判定既有散文),词法层分不开,归行为层。"
21
+ }
22
+ ]
23
+ }