@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.
- package/LICENSE +391 -32
- package/README.md +176 -10
- package/bin/huicai.js +166 -73
- package/package.json +27 -8
- package/skills/ab-testing/trigger-cases.json +30 -0
- package/skills/academic-writing/trigger-cases.json +30 -0
- package/skills/accounting-ops/trigger-cases.json +30 -0
- package/skills/ai-agent/trigger-cases.json +30 -0
- package/skills/ai-aiops/trigger-cases.json +30 -0
- package/skills/ai-coding/trigger-cases.json +30 -0
- package/skills/ai-compliance/trigger-cases.json +30 -0
- package/skills/ai-eval/trigger-cases.json +30 -0
- package/skills/ai-llm-app/trigger-cases.json +30 -0
- package/skills/ai-mlops/trigger-cases.json +30 -0
- package/skills/ai-multimodal/trigger-cases.json +30 -0
- package/skills/ai-prompt/trigger-cases.json +30 -0
- package/skills/ai-rag/trigger-cases.json +30 -0
- package/skills/anomaly-detection/trigger-cases.json +30 -0
- package/skills/api-design/trigger-cases.json +31 -0
- package/skills/api-integration/trigger-cases.json +31 -0
- package/skills/arch-design/trigger-cases.json +12 -0
- package/skills/arch-diagram/SKILL.md +118 -0
- package/skills/arch-diagram/trigger-cases.json +30 -0
- package/skills/arch-distributed/trigger-cases.json +30 -0
- package/skills/arch-multitenant/trigger-cases.json +30 -0
- package/skills/audio-brief/SKILL.md +65 -0
- package/skills/audio-brief/trigger-cases.json +30 -0
- package/skills/audit-assist/trigger-cases.json +30 -0
- package/skills/audit-chain/trigger-cases.json +31 -0
- package/skills/banking-credit/trigger-cases.json +30 -0
- package/skills/brand-design/trigger-cases.json +30 -0
- package/skills/business-plan/trigger-cases.json +30 -0
- package/skills/capital-ops/trigger-cases.json +30 -0
- package/skills/cicd-pipeline/trigger-cases.json +31 -0
- package/skills/code-archaeology/SKILL.md +55 -0
- package/skills/code-archaeology/trigger-cases.json +9 -0
- package/skills/code-quality/SKILL.md +138 -0
- package/skills/code-quality/references/languages.md +107 -0
- package/skills/code-quality/scripts/__pycache__/code_battery.cpython-312.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_check.cpython-312.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_check.cpython-313.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_csharp.cpython-312.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_csharp.cpython-313.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_fix.cpython-312.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_fix.cpython-313.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_java.cpython-312.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_java.cpython-313.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_jsts.cpython-312.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_jsts.cpython-313.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_lens.cpython-312.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_lens.cpython-313.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_python.cpython-312.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_python.cpython-313.pyc +0 -0
- package/skills/code-quality/scripts/__pycache__/code_testplan.cpython-312.pyc +0 -0
- package/skills/code-quality/scripts/code_battery.py +1072 -0
- package/skills/code-quality/scripts/code_check.py +1269 -0
- package/skills/code-quality/scripts/code_csharp.py +371 -0
- package/skills/code-quality/scripts/code_fix.py +201 -0
- package/skills/code-quality/scripts/code_java.py +695 -0
- package/skills/code-quality/scripts/code_jsts.py +313 -0
- package/skills/code-quality/scripts/code_lens.py +1079 -0
- package/skills/code-quality/scripts/code_python.py +536 -0
- package/skills/code-quality/scripts/code_testplan.py +239 -0
- package/skills/code-quality/trigger-cases.json +45 -0
- package/skills/code-review/SKILL.md +24 -0
- package/skills/code-review/trigger-cases.json +35 -0
- package/skills/commit-and-pr/trigger-cases.json +31 -0
- package/skills/content-creation/trigger-cases.json +30 -0
- package/skills/corporate-governance/trigger-cases.json +30 -0
- package/skills/crawl-chain/trigger-cases.json +31 -0
- package/skills/customer-service/trigger-cases.json +30 -0
- package/skills/data-analysis/trigger-cases.json +30 -0
- package/skills/data-chain/SKILL.md +1 -1
- package/skills/data-chain/trigger-cases.json +31 -0
- package/skills/data-governance/trigger-cases.json +30 -0
- package/skills/data-report-pro/trigger-cases.json +30 -0
- package/skills/data-streaming/trigger-cases.json +30 -0
- package/skills/data-wrangling/SKILL.md +1 -1
- package/skills/data-wrangling/trigger-cases.json +30 -0
- package/skills/db-es/trigger-cases.json +30 -0
- package/skills/db-migration/trigger-cases.json +30 -0
- package/skills/db-mysql/trigger-cases.json +30 -0
- package/skills/db-postgres/trigger-cases.json +30 -0
- package/skills/db-redis/trigger-cases.json +30 -0
- package/skills/debug-root-cause/trigger-cases.json +30 -0
- package/skills/dependency-audit/SKILL.md +56 -0
- package/skills/dependency-audit/trigger-cases.json +7 -0
- package/skills/dependency-upgrade/trigger-cases.json +31 -0
- package/skills/dev-cpp/trigger-cases.json +30 -0
- package/skills/dev-cross-platform/trigger-cases.json +30 -0
- package/skills/dev-csharp/SKILL.md +23 -0
- package/skills/dev-csharp/trigger-cases.json +30 -0
- package/skills/dev-frontend/SKILL.md +19 -0
- package/skills/dev-frontend/trigger-cases.json +30 -0
- package/skills/dev-go/trigger-cases.json +30 -0
- package/skills/dev-harmony/trigger-cases.json +30 -0
- package/skills/dev-java/SKILL.md +20 -0
- package/skills/dev-java/trigger-cases.json +30 -0
- package/skills/dev-mobile/trigger-cases.json +30 -0
- package/skills/dev-node/trigger-cases.json +30 -0
- package/skills/dev-php/trigger-cases.json +30 -0
- package/skills/dev-python/SKILL.md +21 -0
- package/skills/dev-python/trigger-cases.json +30 -0
- package/skills/dev-rust/trigger-cases.json +30 -0
- package/skills/dev-toolchain/trigger-cases.json +31 -0
- package/skills/doc-chain/trigger-cases.json +31 -0
- package/skills/doc-compare/trigger-cases.json +30 -0
- package/skills/docx-author/SKILL.md +127 -25
- package/skills/docx-author/scripts/__pycache__/docx_battery.cpython-312.pyc +0 -0
- package/skills/docx-author/scripts/__pycache__/docx_build.cpython-312.pyc +0 -0
- package/skills/docx-author/scripts/__pycache__/docx_check.cpython-312.pyc +0 -0
- package/skills/docx-author/scripts/__pycache__/docx_layout.cpython-312.pyc +0 -0
- package/skills/docx-author/scripts/__pycache__/zh_prose.cpython-312.pyc +0 -0
- package/skills/docx-author/scripts/docx_battery.py +586 -0
- package/skills/docx-author/scripts/docx_build.py +995 -0
- package/skills/docx-author/scripts/docx_check.py +1306 -0
- package/skills/docx-author/scripts/docx_doc.py +14 -154
- package/skills/docx-author/scripts/docx_layout.py +490 -0
- package/skills/docx-author/scripts/zh_prose.py +639 -0
- package/skills/docx-author/trigger-cases.json +58 -0
- package/skills/echo-brief/SKILL.md +84 -0
- package/skills/echo-brief/references/echo-format.md +68 -0
- package/skills/echo-brief/trigger-cases.json +40 -0
- package/skills/ecommerce-ops/trigger-cases.json +30 -0
- package/skills/education-training/trigger-cases.json +30 -0
- package/skills/ehs-safety/trigger-cases.json +30 -0
- package/skills/email-writing/trigger-cases.json +30 -0
- package/skills/eng-ai/trigger-cases.json +30 -0
- package/skills/eng-architecture/trigger-cases.json +31 -0
- package/skills/eng-automation/trigger-cases.json +31 -0
- package/skills/eng-collaboration/trigger-cases.json +30 -0
- package/skills/eng-complex-env/trigger-cases.json +30 -0
- package/skills/eng-data-platform/trigger-cases.json +31 -0
- package/skills/eng-database/trigger-cases.json +31 -0
- package/skills/eng-develop/trigger-cases.json +30 -0
- package/skills/eng-docs/SKILL.md +24 -0
- package/skills/eng-docs/trigger-cases.json +30 -0
- package/skills/eng-efficiency/trigger-cases.json +30 -0
- package/skills/eng-infra/trigger-cases.json +30 -0
- package/skills/eng-integration/trigger-cases.json +31 -0
- package/skills/eng-legacy/trigger-cases.json +31 -0
- package/skills/eng-observability/trigger-cases.json +31 -0
- package/skills/eng-ops/trigger-cases.json +31 -0
- package/skills/eng-performance/trigger-cases.json +31 -0
- package/skills/eng-planning/trigger-cases.json +31 -0
- package/skills/eng-quality/SKILL.md +8 -0
- package/skills/eng-quality/trigger-cases.json +31 -0
- package/skills/eng-release/trigger-cases.json +31 -0
- package/skills/eng-reliability/trigger-cases.json +31 -0
- package/skills/eng-requirements/trigger-cases.json +12 -0
- package/skills/eng-research/trigger-cases.json +30 -0
- package/skills/eng-security/trigger-cases.json +31 -0
- package/skills/eng-ux/trigger-cases.json +30 -0
- package/skills/engineering-chain/trigger-cases.json +30 -0
- package/skills/env-offline/trigger-cases.json +31 -0
- package/skills/env-private-deploy/trigger-cases.json +31 -0
- package/skills/env-xinchuang/trigger-cases.json +31 -0
- package/skills/equipment-tpm/trigger-cases.json +30 -0
- package/skills/esg-report/trigger-cases.json +30 -0
- package/skills/event-management/trigger-cases.json +30 -0
- package/skills/excel-analysis-chain/SKILL.md +17 -4
- package/skills/excel-analysis-chain/trigger-cases.json +31 -0
- package/skills/explain-codebase/trigger-cases.json +11 -0
- package/skills/file-ingest/trigger-cases.json +30 -0
- package/skills/finance-analysis/trigger-cases.json +31 -0
- package/skills/finance-chain/trigger-cases.json +31 -0
- package/skills/financial-modeling/trigger-cases.json +31 -0
- package/skills/find-simplifications/SKILL.md +43 -0
- package/skills/find-simplifications/trigger-cases.json +23 -0
- package/skills/foreign-trade/trigger-cases.json +30 -0
- package/skills/funnel-cohort/trigger-cases.json +30 -0
- package/skills/gov-document/trigger-cases.json +30 -0
- package/skills/gui-change-evidence/SKILL.md +47 -0
- package/skills/gui-change-evidence/trigger-cases.json +23 -0
- package/skills/hr-chain/trigger-cases.json +31 -0
- package/skills/hr-operations/trigger-cases.json +30 -0
- package/skills/info-disclosure/trigger-cases.json +31 -0
- package/skills/infra-gateway/trigger-cases.json +31 -0
- package/skills/infra-k8s/trigger-cases.json +31 -0
- package/skills/infra-mq/trigger-cases.json +30 -0
- package/skills/insurance-advisory/trigger-cases.json +30 -0
- package/skills/internal-audit/trigger-cases.json +30 -0
- package/skills/ip-management/trigger-cases.json +31 -0
- package/skills/ipo-listing/trigger-cases.json +31 -0
- package/skills/it-audit/trigger-cases.json +31 -0
- package/skills/itsm-ops/trigger-cases.json +31 -0
- package/skills/knowledge-sop/trigger-cases.json +31 -0
- package/skills/legal-chain/trigger-cases.json +31 -0
- package/skills/legal-contract/trigger-cases.json +30 -0
- package/skills/litigation-support/trigger-cases.json +31 -0
- package/skills/logistics-warehouse/trigger-cases.json +30 -0
- package/skills/long-doc-analysis/trigger-cases.json +31 -0
- package/skills/management-accounting/trigger-cases.json +30 -0
- package/skills/manufacturing-chain/trigger-cases.json +31 -0
- package/skills/manufacturing-quality/trigger-cases.json +30 -0
- package/skills/marketing-analytics/trigger-cases.json +31 -0
- package/skills/marketing-chain/trigger-cases.json +31 -0
- package/skills/meeting-minutes/trigger-cases.json +30 -0
- package/skills/metrics-system/trigger-cases.json +31 -0
- package/skills/negotiation-prep/trigger-cases.json +30 -0
- package/skills/obs-prometheus/trigger-cases.json +31 -0
- package/skills/office-automation/trigger-cases.json +31 -0
- package/skills/okr-review/trigger-cases.json +30 -0
- package/skills/ops-fleet/trigger-cases.json +31 -0
- package/skills/ops-linux/trigger-cases.json +31 -0
- package/skills/optimization-solver/trigger-cases.json +30 -0
- package/skills/patent-disclosure/SKILL.md +105 -0
- package/skills/patent-disclosure/references/figures.md +110 -0
- package/skills/patent-disclosure/references/outline.md +162 -0
- package/skills/patent-disclosure/scripts/patent_docx.py +230 -0
- package/skills/patent-disclosure/trigger-cases.json +31 -0
- package/skills/patent-drafting/SKILL.md +108 -0
- package/skills/patent-drafting/trigger-cases.json +31 -0
- package/skills/patent-portfolio/SKILL.md +81 -0
- package/skills/patent-portfolio/trigger-cases.json +31 -0
- package/skills/pdf-toolkit/trigger-cases.json +31 -0
- package/skills/perf-optimize/trigger-cases.json +31 -0
- package/skills/pivot-crosstab/trigger-cases.json +30 -0
- package/skills/policy-analysis/trigger-cases.json +31 -0
- package/skills/portfolio-analysis/trigger-cases.json +31 -0
- package/skills/ppt-chain/SKILL.md +14 -6
- package/skills/ppt-chain/trigger-cases.json +31 -0
- package/skills/pptx-author/SKILL.md +86 -33
- package/skills/pptx-author/scripts/__pycache__/pptx_check.cpython-312.pyc +0 -0
- package/skills/pptx-author/scripts/__pycache__/pptx_deck.cpython-312.pyc +0 -0
- package/skills/pptx-author/scripts/__pycache__/pptx_layout.cpython-312.pyc +0 -0
- package/skills/pptx-author/scripts/pptx_battery.py +178 -0
- package/skills/pptx-author/scripts/pptx_build.py +119 -0
- package/skills/pptx-author/scripts/pptx_check.py +1182 -0
- package/skills/pptx-author/scripts/pptx_deck.py +736 -145
- package/skills/pptx-author/scripts/pptx_layout.py +384 -0
- package/skills/pptx-author/trigger-cases.json +15 -0
- package/skills/pr-comms/trigger-cases.json +30 -0
- package/skills/procurement-supply/trigger-cases.json +31 -0
- package/skills/product-design/trigger-cases.json +31 -0
- package/skills/production-planning/trigger-cases.json +31 -0
- package/skills/project-management/trigger-cases.json +31 -0
- package/skills/project-proposal/trigger-cases.json +31 -0
- package/skills/prose-standard/SKILL.md +53 -0
- package/skills/prose-standard/trigger-cases.json +23 -0
- package/skills/qa-api-automation/trigger-cases.json +31 -0
- package/skills/qa-mobile-automation/trigger-cases.json +31 -0
- package/skills/qa-ui-automation/trigger-cases.json +31 -0
- package/skills/quant-analysis/trigger-cases.json +31 -0
- package/skills/rag-triage/SKILL.md +64 -0
- package/skills/rag-triage/evals.json +57 -0
- package/skills/rag-triage/references/triage-playbook.md +75 -0
- package/skills/rag-triage/trigger-cases.json +31 -0
- package/skills/real-estate-property/trigger-cases.json +30 -0
- package/skills/refactor-safely/SKILL.md +1 -1
- package/skills/refactor-safely/trigger-cases.json +30 -0
- package/skills/regression-forecast/trigger-cases.json +31 -0
- package/skills/release-checklist/trigger-cases.json +31 -0
- package/skills/report-craft/SKILL.md +76 -0
- package/skills/report-craft/references/feasibility.md +118 -0
- package/skills/report-craft/references/review-checklist.md +51 -0
- package/skills/report-craft/references/visuals.md +114 -0
- package/skills/report-craft/references/writing.md +80 -0
- package/skills/report-craft/scripts/__pycache__/chart_render.cpython-312.pyc +0 -0
- package/skills/report-craft/scripts/__pycache__/fin_model.cpython-312.pyc +0 -0
- package/skills/report-craft/scripts/__pycache__/project_facts.cpython-312.pyc +0 -0
- package/skills/report-craft/scripts/chart_render.py +1222 -0
- package/skills/report-craft/scripts/fin_model.py +602 -0
- package/skills/report-craft/scripts/project_facts.py +580 -0
- package/skills/report-craft/scripts/report_battery.py +349 -0
- package/skills/report-craft/trigger-cases.json +15 -0
- package/skills/retail-store-ops/trigger-cases.json +30 -0
- package/skills/risk-compliance/trigger-cases.json +31 -0
- package/skills/scope-creep/SKILL.md +45 -0
- package/skills/scope-creep/trigger-cases.json +7 -0
- package/skills/sec-auth/trigger-cases.json +31 -0
- package/skills/sec-compliance/trigger-cases.json +31 -0
- package/skills/securities-chain/trigger-cases.json +31 -0
- package/skills/securities-research/trigger-cases.json +31 -0
- package/skills/security-audit/trigger-cases.json +31 -0
- package/skills/slides-html/SKILL.md +25 -10
- package/skills/slides-html/trigger-cases.json +11 -0
- package/skills/sql-analysis/SKILL.md +110 -0
- package/skills/sql-analysis/trigger-cases.json +34 -0
- package/skills/sql-tuning/trigger-cases.json +31 -0
- package/skills/statistical-testing/trigger-cases.json +31 -0
- package/skills/strategy-planning/trigger-cases.json +30 -0
- package/skills/supply-chain/trigger-cases.json +31 -0
- package/skills/tax-compliance/trigger-cases.json +30 -0
- package/skills/tech-doc/SKILL.md +262 -0
- package/skills/tech-doc/scripts/__pycache__/archive_battery.cpython-312.pyc +0 -0
- package/skills/tech-doc/scripts/__pycache__/archive_build.cpython-312.pyc +0 -0
- package/skills/tech-doc/scripts/__pycache__/archive_check.cpython-312.pyc +0 -0
- package/skills/tech-doc/scripts/__pycache__/archive_spec.cpython-312.pyc +0 -0
- package/skills/tech-doc/scripts/__pycache__/doc_templates.cpython-312.pyc +0 -0
- package/skills/tech-doc/scripts/archive_battery.py +860 -0
- package/skills/tech-doc/scripts/archive_build.py +599 -0
- package/skills/tech-doc/scripts/archive_check.py +1307 -0
- package/skills/tech-doc/scripts/archive_spec.py +499 -0
- package/skills/tech-doc/scripts/doc_templates.py +624 -0
- package/skills/tech-doc/trigger-cases.json +57 -0
- package/skills/tech-research/trigger-cases.json +31 -0
- package/skills/tender-bidding/trigger-cases.json +31 -0
- package/skills/translation-pro/trigger-cases.json +30 -0
- package/skills/treasury-mgmt/trigger-cases.json +31 -0
- package/skills/trim-cot-leakage/SKILL.md +58 -0
- package/skills/trim-cot-leakage/trigger-cases.json +23 -0
- package/skills/web-craft/SKILL.md +103 -0
- package/skills/web-craft/references/craft-checklist.md +75 -0
- package/skills/web-craft/references/design-direction.md +122 -0
- package/skills/web-craft/references/h5-mobile.md +100 -0
- package/skills/web-craft/references/motion.md +136 -0
- package/skills/web-craft/references/recipes.md +74 -0
- package/skills/web-craft/templates/wedding-invitation.html +1180 -0
- package/skills/web-craft/trigger-cases.json +14 -0
- package/skills/web-scraping/trigger-cases.json +34 -0
- package/skills/web-search/SKILL.md +11 -10
- package/skills/web-search/trigger-cases.json +31 -0
- package/skills/weekly-report/SKILL.md +134 -0
- package/skills/weekly-report/trigger-cases.json +11 -0
- package/skills/write-tests/trigger-cases.json +31 -0
- package/skills/xlsx-analysis/SKILL.md +143 -77
- package/skills/xlsx-analysis/scripts/__pycache__/data_profile.cpython-312.pyc +0 -0
- package/skills/xlsx-analysis/scripts/__pycache__/xlsx_build.cpython-312.pyc +0 -0
- package/skills/xlsx-analysis/scripts/__pycache__/xlsx_check.cpython-312.pyc +0 -0
- package/skills/xlsx-analysis/scripts/__pycache__/xlsx_layout.cpython-312.pyc +0 -0
- package/skills/xlsx-analysis/scripts/__pycache__/xlsx_toolkit.cpython-312.pyc +0 -0
- package/skills/xlsx-analysis/scripts/data_profile.py +391 -0
- package/skills/xlsx-analysis/scripts/xlsx_battery.py +389 -0
- package/skills/xlsx-analysis/scripts/xlsx_build.py +522 -0
- package/skills/xlsx-analysis/scripts/xlsx_check.py +924 -0
- package/skills/xlsx-analysis/scripts/xlsx_layout.py +235 -0
- package/skills/xlsx-analysis/scripts/xlsx_style.py +28 -66
- package/skills/xlsx-analysis/scripts/xlsx_toolkit.py +61 -5
- package/skills/xlsx-analysis/trigger-cases.json +59 -0
- package/squads/hc-defense.md +47 -0
- package/squads/hc-rdarchive.md +110 -0
- package/squads/hc-redteam.md +50 -0
- package/squads/hc-weekly.md +125 -0
- package/src/account.js +1 -0
- package/src/acp.js +1 -0
- package/src/advisor.js +1 -1
- package/src/agent.js +1 -1
- package/src/api.js +1 -1
- package/src/archaeology.js +1 -0
- package/src/ask-ui.js +1 -0
- package/src/assets-import.js +1 -1
- package/src/autofix.js +1 -1
- package/src/automation-tools.js +1 -0
- package/src/automation.js +1 -1
- package/src/autorun.js +1 -1
- package/src/banner.js +1 -1
- package/src/capability-probe.js +1 -0
- package/src/checkpoints.js +1 -1
- package/src/code-tools.js +1 -0
- package/src/codeindex.js +1 -1
- package/src/codemode.js +1 -0
- package/src/command-bridge.js +1 -0
- package/src/command-ui.js +1 -0
- package/src/commands.js +1 -1
- package/src/compaction.js +1 -1
- package/src/computer.js +1 -0
- package/src/config.js +1 -1
- package/src/consult.js +1 -1
- package/src/context-report.js +1 -1
- package/src/context-window.js +1 -0
- package/src/context.js +1 -1
- package/src/crew.js +1 -0
- package/src/crush.js +1 -0
- package/src/daemon.js +1 -1
- package/src/decisions.js +1 -1
- package/src/depaudit.js +1 -0
- package/src/device.js +1 -1
- package/src/diagram-draw.js +1 -0
- package/src/diagram-layouts.js +1 -0
- package/src/diagram-raster.js +1 -0
- package/src/diagram.js +1 -0
- package/src/dictation.js +1 -0
- package/src/diffview.js +1 -1
- package/src/doctor.js +1 -1
- package/src/docx-tools.js +1 -0
- package/src/errkind.js +1 -0
- package/src/evidence.js +1 -0
- package/src/executors.js +1 -1
- package/src/expert-catalog.js +1 -1
- package/src/experts-store.js +1 -1
- package/src/experts.js +1 -1
- package/src/external-agents.js +1 -0
- package/src/forks.js +1 -1
- package/src/fs-observe.js +1 -0
- package/src/gitflow.js +1 -1
- package/src/goalround.js +1 -0
- package/src/hooks.js +1 -1
- package/src/input.js +1 -1
- package/src/insights.js +1 -1
- package/src/jobs.js +1 -0
- package/src/kbsync.js +1 -1
- package/src/lsp.js +1 -0
- package/src/mcp-apps.js +1 -0
- package/src/mcp.js +1 -1
- package/src/memory.js +1 -1
- package/src/notify.js +1 -0
- package/src/permissions.js +1 -1
- package/src/plan-limits.js +1 -0
- package/src/policy.js +1 -0
- package/src/pptx-tools.js +1 -0
- package/src/presence.js +1 -0
- package/src/privatedir.js +1 -0
- package/src/pyruntime.js +1 -1
- package/src/radar.js +1 -0
- package/src/render.js +1 -1
- package/src/repl.js +1 -1
- package/src/report-tools.js +1 -0
- package/src/routing.js +1 -0
- package/src/sandbox-probe.js +1 -0
- package/src/sandbox-win-launcher.mjs +156 -0
- package/src/sandbox.js +1 -0
- package/src/scan.js +1 -1
- package/src/schedule.js +1 -1
- package/src/scopecreep.js +1 -0
- package/src/sdk.js +1 -0
- package/src/selection.js +1 -0
- package/src/session-events.js +1 -0
- package/src/session.js +1 -1
- package/src/sessionindex.js +1 -0
- package/src/sessionlog.js +1 -0
- package/src/skill-catalog.js +1 -0
- package/src/skill-lint.js +1 -0
- package/src/skill-optimize.js +1 -0
- package/src/skill-scan.js +1 -0
- package/src/skills.js +1 -1
- package/src/spill.js +1 -0
- package/src/squad.js +1 -1
- package/src/subagent.js +1 -1
- package/src/surface-state.js +1 -0
- package/src/tapd.js +1 -0
- package/src/terminal-select.js +1 -0
- package/src/terminal.js +1 -0
- package/src/test-runner.js +1 -0
- package/src/todo.js +1 -1
- package/src/toolpipe.js +1 -0
- package/src/tools.js +1 -1
- package/src/toon.js +1 -0
- package/src/transcript.js +1 -1
- package/src/tui/app.js +1 -1
- package/src/tui/command-menu.js +1 -0
- package/src/tui/progress.js +1 -0
- package/src/tui/scroll.js +1 -0
- package/src/tui/welcome.js +1 -0
- package/src/tui/workbench.js +1 -0
- package/src/ui-spec.js +1 -0
- package/src/uitree.js +1 -0
- package/src/uninstall.js +1 -1
- package/src/vision.js +1 -0
- package/src/visual.js +1 -0
- package/src/voice-form.js +1 -0
- package/src/voice.js +1 -0
- package/src/watch.js +1 -1
- package/src/web-audit.js +1 -0
- package/src/web-cdp.js +1 -0
- package/src/web-inspect.js +1 -0
- package/src/websearch.js +1 -0
- package/src/weekly.js +1 -0
- package/src/workflow.js +1 -0
- package/src/worklog.js +1 -0
- package/src/xlsx-tools.js +1 -0
- package/ui/command-picker.js +79 -0
- package/skills/ab-testing/scripts/__pycache__/ab_test.cpython-312.pyc +0 -0
- package/skills/accounting-ops/scripts/__pycache__/acct_tools.cpython-312.pyc +0 -0
- package/skills/anomaly-detection/scripts/__pycache__/anomaly.cpython-312.pyc +0 -0
- package/skills/audit-assist/scripts/__pycache__/audit_sampling.cpython-312.pyc +0 -0
- package/skills/banking-credit/scripts/__pycache__/credit_metrics.cpython-312.pyc +0 -0
- package/skills/data-report-pro/scripts/__pycache__/bigdata.cpython-312.pyc +0 -0
- package/skills/data-wrangling/scripts/__pycache__/join_tools.cpython-312.pyc +0 -0
- package/skills/ecommerce-ops/scripts/__pycache__/gmv_decompose.cpython-312.pyc +0 -0
- package/skills/funnel-cohort/scripts/__pycache__/funnel.cpython-312.pyc +0 -0
- package/skills/management-accounting/scripts/__pycache__/costing.cpython-312.pyc +0 -0
- package/skills/manufacturing-quality/scripts/__pycache__/spc.cpython-312.pyc +0 -0
- package/skills/marketing-analytics/scripts/__pycache__/rfm.cpython-312.pyc +0 -0
- package/skills/optimization-solver/scripts/__pycache__/solver.cpython-312.pyc +0 -0
- package/skills/pivot-crosstab/scripts/__pycache__/pivot_tools.cpython-312.pyc +0 -0
- package/skills/portfolio-analysis/scripts/__pycache__/portfolio.cpython-312.pyc +0 -0
- package/skills/procurement-supply/scripts/__pycache__/supply.cpython-312.pyc +0 -0
- package/skills/production-planning/scripts/__pycache__/mrp_capacity.cpython-312.pyc +0 -0
- package/skills/project-management/scripts/__pycache__/cpm.cpython-312.pyc +0 -0
- package/skills/quant-analysis/scripts/__pycache__/quant.cpython-312.pyc +0 -0
- package/skills/real-estate-property/scripts/__pycache__/property_calc.cpython-312.pyc +0 -0
- package/skills/regression-forecast/scripts/__pycache__/regress.cpython-312.pyc +0 -0
- package/skills/securities-research/scripts/__pycache__/valuation.cpython-312.pyc +0 -0
- package/skills/statistical-testing/scripts/__pycache__/stat_tests.cpython-312.pyc +0 -0
- package/skills/treasury-mgmt/scripts/__pycache__/cashflow_forecast.cpython-312.pyc +0 -0
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
# 研发项目文档归档规范(内置体例从真实归档套件逐份抽取,不是凭印象编的)。
|
|
2
|
+
#
|
|
3
|
+
# 为什么要有「档案级」这一层:单份文档体检得再干净,也看不见下面这些——
|
|
4
|
+
# 同一个项目 41 份文档里项目名称有三种写法(含一个被截断的)、研发任务书写 ZY202501003
|
|
5
|
+
# 而验收申请表写 ZY202501006、项目建议书把「联系人/电话/编制人」三个字段填串了、
|
|
6
|
+
# 12 期月度验收报告一份没交。这些全是**跨文档**的事实,只有把整个项目目录一起看才发现得了,
|
|
7
|
+
# 而它们恰恰是验收与审计现场最容易被挑出来的问题。
|
|
8
|
+
#
|
|
9
|
+
# 体例可换:内置 `hengtong`(技术中心研发部通行的那套编号目录),
|
|
10
|
+
# 也可以传自定义 JSON 覆盖——`load(name_or_path)`。
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
import os
|
|
14
|
+
import re
|
|
15
|
+
|
|
16
|
+
# ── 统一封面信息栏 ─────────────────────────────────────────────────────────
|
|
17
|
+
# 这套体例里几乎每份正式文档都带同一张封面信息表 + 单位落款 + 日期。
|
|
18
|
+
# 字段名在各文档间略有出入(有的叫「编制人」有的叫「报告编写人」),归一到下面这组语义键。
|
|
19
|
+
FIELD_ALIASES = {
|
|
20
|
+
'项目名称': ['项目名称', '项 目 名 称', '总项目名称'],
|
|
21
|
+
'项目编号': ['项目编号', '项目编码'],
|
|
22
|
+
'项目负责人': ['项目负责人', '项目经理'],
|
|
23
|
+
'项目联系人': ['项目联系人'],
|
|
24
|
+
'联系电话': ['联系电话', '联 系 电 话', '联系电话(手机)', '电话'],
|
|
25
|
+
'建设单位': ['建设单位', '建 设 单 位', '项目承建单位', '项目承担单位', '单位'],
|
|
26
|
+
'编制人': ['编制人', '编 制 人', '报告编写人', '编写人', '申请人'],
|
|
27
|
+
'编制时间': ['编制时间', '编 制 时 间', '编制日期', '编 制 日 期', '完成时间',
|
|
28
|
+
'立项时间', '申请日期', '提交时间'],
|
|
29
|
+
'起止时间': ['项目起止时间', '起止时间', '研究起止时间'],
|
|
30
|
+
'申请部门': ['申请部门', '部门'],
|
|
31
|
+
}
|
|
32
|
+
FIELD_KEYS = list(FIELD_ALIASES)
|
|
33
|
+
|
|
34
|
+
# 反查表:归一化后的字面 → 语义键
|
|
35
|
+
_ALIAS_INDEX = {}
|
|
36
|
+
for _k, _vs in FIELD_ALIASES.items():
|
|
37
|
+
for _v in _vs:
|
|
38
|
+
_ALIAS_INDEX[re.sub(r'[\s ]', '', _v).rstrip('::')] = _k
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def field_key(raw):
|
|
42
|
+
"""把文档里的字段名归一到语义键;认不出返回 None。"""
|
|
43
|
+
return _ALIAS_INDEX.get(re.sub(r'[\s ]', '', str(raw or '')).rstrip('::'))
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# ── 各文档的章节骨架 ───────────────────────────────────────────────────────
|
|
47
|
+
# 每条 = (章节名, 子节, 级别, 别名)。级别两档,是**按真实归档语料标定的**,不是拍脑袋:
|
|
48
|
+
# must —— 模板要求且两个真实项目都写了 → 缺了报必修;
|
|
49
|
+
# should —— 模板里有、但真实项目普遍省略 → 缺了只报建议(照模板一刀切会对每个
|
|
50
|
+
# 正常项目都误报一次,那种噪声比漏报更快让人关掉检查)。
|
|
51
|
+
# 别名来自真实文档的改名习惯(「验收标准和验收工作安排」实际写成「验收标准」),
|
|
52
|
+
# 不给别名就会把改了名的合规章节判成缺失。
|
|
53
|
+
SECTIONS = {
|
|
54
|
+
'项目建议书': [
|
|
55
|
+
('文档介绍', ['文档目的', '文档范围', '读者对象', '参考文献', '术语与缩写解释'], 'should', []),
|
|
56
|
+
('产品介绍', ['产品定义', '产品开发背景', '产品主要功能和特色', '产品范围'], 'must', []),
|
|
57
|
+
('市场概述', ['客户需求', '市场规模与发展趋势'], 'should', ['市场分析']),
|
|
58
|
+
('产品发展目标', [], 'must', []),
|
|
59
|
+
('产品技术方案', ['产品体系结构', '关键技术'], 'must', []),
|
|
60
|
+
('产品优缺点分析', [], 'should', []),
|
|
61
|
+
('Make-or-Buy决策', ['项目团队', '软硬件资源估算', '成本估算'], 'must', []),
|
|
62
|
+
('项目计划', [], 'should', ['进度安排']),
|
|
63
|
+
('市场营销计划', [], 'should', []),
|
|
64
|
+
('成本效益分析', [], 'must', []),
|
|
65
|
+
('总结', [], 'must', []),
|
|
66
|
+
],
|
|
67
|
+
# 真实体例是科技计划项目可研那一套十一节,两个项目逐字一致——
|
|
68
|
+
# 早先用的通用「总论/技术方案/投资估算」骨架在这套语料上一条都对不上。
|
|
69
|
+
'可行性研究报告': [
|
|
70
|
+
('立项的背景与意义', [], 'must', ['立项背景']),
|
|
71
|
+
('国内外研究现状与发展趋势', [], 'must', ['研究现状']),
|
|
72
|
+
('项目实施主要内容、技术关键与创新点、预期目标',
|
|
73
|
+
['实施主要内容', '预期目标'], 'must', ['实施主要内容']),
|
|
74
|
+
('现有工作基础、条件和优势', [], 'must', ['现有工作基础']),
|
|
75
|
+
('项目实施方案、组织方式与课题分解', [], 'must', ['项目实施方案']),
|
|
76
|
+
('进度安排与年度计划内容', [], 'must', ['进度安排']),
|
|
77
|
+
('承担单位和主要研究人员简况', [], 'must', ['承担单位']),
|
|
78
|
+
('经费预算来源、使用计划及还款能力分析', [], 'must', ['经费预算']),
|
|
79
|
+
('应用或产业化前景与市场需求分析', [], 'must', ['产业化前景', '市场需求分析']),
|
|
80
|
+
('经济、社会效益分析', [], 'must', ['经济效益', '社会效益']),
|
|
81
|
+
('项目的风险分析与对策', [], 'must', ['风险分析']),
|
|
82
|
+
],
|
|
83
|
+
'立项申请书': [
|
|
84
|
+
('项目立项背景', [], 'must', []),
|
|
85
|
+
('项目主要研究(实验或推广)内容', [], 'must', ['主要研究内容']),
|
|
86
|
+
('项目拟解决的技术关键及解决措施', [], 'must', ['技术关键']),
|
|
87
|
+
('项目考核指标', [], 'must', ['考核指标']),
|
|
88
|
+
('进度安排', [], 'must', []),
|
|
89
|
+
('项目验收时间', [], 'must', []),
|
|
90
|
+
('项目经费预算', [], 'must', ['经费预算']),
|
|
91
|
+
('项目主要参加人员', [], 'must', ['主要参加人员']),
|
|
92
|
+
('审批意见', [], 'must', []),
|
|
93
|
+
],
|
|
94
|
+
'研发任务书': [
|
|
95
|
+
('项目概述', ['项目摘要', '项目背景与目的', '项目主要设计与改进说明'], 'must', []),
|
|
96
|
+
('目标及要求', ['技术选型', '项目目标'], 'must', []),
|
|
97
|
+
('项目人员', [], 'must', []),
|
|
98
|
+
('费用预算', [], 'must', []),
|
|
99
|
+
('项目开发计划', [], 'must', []),
|
|
100
|
+
('结项条件', [], 'must', []),
|
|
101
|
+
],
|
|
102
|
+
'项目研发实施计划': [
|
|
103
|
+
('引言', ['编写目的', '背景'], 'must', []),
|
|
104
|
+
('定义', ['专门术语', '缩写'], 'must', []),
|
|
105
|
+
('项目概述', ['工作内容', '主要参与人员'], 'must', []),
|
|
106
|
+
('绩效与考核机制', [], 'should', ['考核机制']),
|
|
107
|
+
('研发计划', [], 'should', []),
|
|
108
|
+
('产品及成果', [], 'must', []),
|
|
109
|
+
('验收标准和验收工作安排', ['代码的验收', '文档验收标准', '服务验收'], 'must', ['验收标准']),
|
|
110
|
+
('审批记录', [], 'must', []),
|
|
111
|
+
],
|
|
112
|
+
'研发进度报告': [
|
|
113
|
+
('编写目的', [], 'must', []),
|
|
114
|
+
('项目概述', [], 'must', []),
|
|
115
|
+
('项目进度概述', ['项目进度情况', '费用情况'], 'must', []),
|
|
116
|
+
('外部情况分析', [], 'must', []),
|
|
117
|
+
('审批记录', [], 'must', []),
|
|
118
|
+
],
|
|
119
|
+
'工作总结报告': [
|
|
120
|
+
('项目执行概述', [], 'must', []),
|
|
121
|
+
('项目来源', ['项目立项背景', '项目立项的依据和来源'], 'must', []),
|
|
122
|
+
('实施完成情况', ['项目研究内容完成情况', '项目考核指标完成情况', '项目取得的主要成果'], 'must', []),
|
|
123
|
+
('经费支出情况', [], 'must', []),
|
|
124
|
+
('存在的问题及改进意见', [], 'must', ['存在的问题']),
|
|
125
|
+
],
|
|
126
|
+
'技术总结报告': [
|
|
127
|
+
('项目简介', [], 'must', []),
|
|
128
|
+
('主要研究内容开展及完成情况', ['项目研究总体设计与技术路线'], 'must',
|
|
129
|
+
['主要研究的内容', '主要研究内容']),
|
|
130
|
+
('技术创新成果', [], 'must', ['主要技术创新点', '技术创新点', '技术创新']),
|
|
131
|
+
('存在的问题与建议', [], 'must', ['存在问题及建议', '存在的问题及建议', '存在问题与建议']),
|
|
132
|
+
],
|
|
133
|
+
'项目验收报告': [
|
|
134
|
+
('目标任务完成情况', ['项目主要研究内容', '考核技术指标', '考核经济指标',
|
|
135
|
+
'考核社会生态效益指标', '考核科技产出指标'], 'must', []),
|
|
136
|
+
('项目经费决算表', [], 'must', ['经费决算']),
|
|
137
|
+
('项目主要参加人员名单', [], 'must', ['主要参加人员']),
|
|
138
|
+
('验收委员会名单', [], 'must', ['验收委员会']),
|
|
139
|
+
('项目验收意见', [], 'must', ['验收意见']),
|
|
140
|
+
],
|
|
141
|
+
'项目验收申请表': [], # 表单式:主体是字段表,无章节
|
|
142
|
+
'研发评价总结纪要': [],
|
|
143
|
+
'产品开发需求申请': [],
|
|
144
|
+
'项目开发需求申请': [],
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
# 表单式文档的必填字段(缺项就会被退回,失分点几乎全在这里而不在文采)
|
|
148
|
+
FORM_FIELDS = {
|
|
149
|
+
'项目验收申请表': ['项目名称', '项目承建单位', '项目立项文件', '项目编号', '项目负责人',
|
|
150
|
+
'联系电话(手机)', '项目联系人', '项目起止时间', '合同规定验收时间',
|
|
151
|
+
'项目承建单位申请意见', '项目经理意见', '技术分管副总意见', '总经理意见'],
|
|
152
|
+
'研发评价总结纪要': ['对外合作', '合作单位', '费用合计', '起止时间', '研发过程情况',
|
|
153
|
+
'该项目的专利情况', '该项目研发存在的主要问题及今后的设想',
|
|
154
|
+
'项目研究成果的主体内容', '分管副总意见', '总经理意见'],
|
|
155
|
+
'项目开发需求申请': ['项目名称', '版本号', '申请时间', '申请部门', '开发类型', '需求内容概述',
|
|
156
|
+
'可行性分析', '需求申请人', '技术分管经理', '需求方部门领导',
|
|
157
|
+
'技术分管副总', '需求方分管副总', '总经理'],
|
|
158
|
+
'产品开发需求申请': ['申请人', '申请部门', '申请日期', '项目名称', '提交时间',
|
|
159
|
+
'产品功能及服务要求', '市场负责人意见', '技术负责人意见', '总经理意见'],
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
# 各文档必须有的签批栏(少一级签批 = 流程没走完,交上去会被退)
|
|
163
|
+
APPROVALS = {
|
|
164
|
+
'立项申请书': ['技术负责人意见', '财务负责人意见', '总经理意见'],
|
|
165
|
+
'研发任务书': ['项目负责人意见', '技术负责人意见'],
|
|
166
|
+
'项目研发实施计划': ['项目经理意见', '分管副总意见'],
|
|
167
|
+
'研发进度报告': ['项目经理意见', '技术副总意见', '财务负责人意见', '市场负责人意见', '总经理意见'],
|
|
168
|
+
'项目验收申请表': ['项目经理意见', '技术分管副总意见', '总经理意见'],
|
|
169
|
+
'研发评价总结纪要': ['分管副总意见', '总经理意见'],
|
|
170
|
+
'项目开发需求申请': ['技术分管经理', '技术分管副总', '总经理'],
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
# ── 归档目录规范 ───────────────────────────────────────────────────────────
|
|
174
|
+
# match 用正则而不是精确文件名:真实项目会把「6-研发实施计划」改成「6-项目研发实施计划」,
|
|
175
|
+
# 按精确名核对会把改了名的合规文件误报成缺失。
|
|
176
|
+
ARCHIVE_ITEMS = [
|
|
177
|
+
{'dir': '1-立项文档', 'kind': '项目建议书', 'file': '1-项目建议书.docx',
|
|
178
|
+
'match': r'项目建议书', 'required': True, 'stage': '立项'},
|
|
179
|
+
{'dir': '1-立项文档', 'kind': '可行性研究报告', 'file': '2-可行性研究报告.docx',
|
|
180
|
+
'match': r'可行性(研究)?报告|可研', 'required': True, 'stage': '立项'},
|
|
181
|
+
{'dir': '1-立项文档', 'kind': '立项申请书', 'file': '3-立项申请书.docx',
|
|
182
|
+
'match': r'立项申请书', 'required': True, 'stage': '立项'},
|
|
183
|
+
{'dir': '1-立项文档', 'kind': '项目立项的决议', 'file': '4-项目立项的决议.docx',
|
|
184
|
+
'match': r'立项的?决议', 'required': True, 'stage': '立项'},
|
|
185
|
+
{'dir': '', 'kind': '产品开发需求申请', 'file': '产品开发需求申请.docx',
|
|
186
|
+
'match': r'产品开发需求申请', 'required': True, 'stage': '需求'},
|
|
187
|
+
{'dir': '', 'kind': '项目开发需求申请', 'file': '项目开发需求申请.docx',
|
|
188
|
+
'match': r'项目开发需求申请', 'required': True, 'stage': '需求'},
|
|
189
|
+
{'dir': '', 'kind': '研发任务书', 'file': '5-研发任务书.docx',
|
|
190
|
+
'match': r'研发任务书', 'required': True, 'stage': '任务下达'},
|
|
191
|
+
{'dir': '', 'kind': '项目研发实施计划', 'file': '6-项目研发实施计划.docx',
|
|
192
|
+
'match': r'(研发|项目研发)实施计划', 'required': True, 'stage': '计划'},
|
|
193
|
+
{'dir': '7-进度表', 'kind': '项目研发进度表-计划', 'file': '1-项目研发进度表-计划.xlsx',
|
|
194
|
+
'match': r'进度表.*计划|进度计划', 'required': True, 'stage': '计划'},
|
|
195
|
+
{'dir': '', 'kind': '年度研发支出预算表', 'file': '8-研发支出预算表.xls',
|
|
196
|
+
'match': r'研发支出预算', 'required': True, 'stage': '预算'},
|
|
197
|
+
{'dir': '9-10验收', 'kind': '项目验收申请表', 'file': '项目验收申请表.docx',
|
|
198
|
+
'match': r'验收申请表', 'required': True, 'stage': '验收'},
|
|
199
|
+
{'dir': '9-10验收', 'kind': '项目验收报告', 'file': '项目验收报告.docx',
|
|
200
|
+
'match': r'验收报告', 'required': True, 'stage': '验收'},
|
|
201
|
+
{'dir': '9-10验收', 'kind': '工作总结报告', 'file': '工作总结报告.docx',
|
|
202
|
+
'match': r'工作总结报告', 'required': True, 'stage': '验收'},
|
|
203
|
+
{'dir': '9-10验收', 'kind': '技术总结报告', 'file': '技术总结报告.docx',
|
|
204
|
+
'match': r'技术总结报告', 'required': True, 'stage': '验收'},
|
|
205
|
+
{'dir': '9-10验收', 'kind': '研发评价总结纪要', 'file': '研发评价总结纪要.docx',
|
|
206
|
+
'match': r'研发评价总结纪要|评价总结纪要', 'required': True, 'stage': '验收'},
|
|
207
|
+
{'dir': '', 'kind': '档案清册', 'file': '档案清册.xlsx',
|
|
208
|
+
'match': r'档案清册', 'required': False, 'stage': '归档'},
|
|
209
|
+
{'dir': '', 'kind': '借阅台账', 'file': '借阅台账.xlsx',
|
|
210
|
+
'match': r'借阅台账', 'required': False, 'stage': '归档'},
|
|
211
|
+
]
|
|
212
|
+
|
|
213
|
+
# 周期性文档:份数是硬指标——12 期少一期,加计扣除与高企核查都会追问
|
|
214
|
+
PERIODIC = [
|
|
215
|
+
{'kind': '研发进度报告', 'dir': '周期性文档/研发进度报告',
|
|
216
|
+
'pattern': '研发进度报告-{n:02d}.docx', 'match': r'研发进度报告[-_]?(\d{1,2})',
|
|
217
|
+
'bare': r'研发进度报告', 'freq': '月', 'count': 12, 'required': True},
|
|
218
|
+
{'kind': '月度验收报告', 'dir': '周期性文档/月度验收报告',
|
|
219
|
+
'pattern': '项目月度验收报告{n:02d}.docx', 'match': r'月度验收报告[-_]?(\d{1,2})',
|
|
220
|
+
'bare': r'月度验收报告', 'freq': '月', 'count': 12, 'required': True},
|
|
221
|
+
{'kind': '项目研发进度表-实际', 'dir': '7-进度表',
|
|
222
|
+
'pattern': '1-项目研发进度表-实际-第{n}季度.xlsx', 'match': r'实际[-_]?第?(\d)\s*季度',
|
|
223
|
+
'bare': r'项目研发进度表[-_]?实际', 'freq': '季', 'count': 4, 'required': True},
|
|
224
|
+
# 下面两类规范目录里有、但两个真实项目都没做——**列为选做**:
|
|
225
|
+
# 缺席不报缺,只是让 kind_of 认得出来(认不出会被归到「不在规范目录内」,
|
|
226
|
+
# 那等于告诉用户「这份文件不知道是什么」,比不列更糟)。
|
|
227
|
+
{'kind': '项目研发周报', 'dir': '周期性文档/工作周报',
|
|
228
|
+
'pattern': '项目研发周报-{n:02d}.docx', 'match': r'研发周报[-_]?(\d{1,2})',
|
|
229
|
+
'bare': r'研发周报', 'freq': '周', 'count': 52, 'required': False},
|
|
230
|
+
{'kind': '月度开发报告', 'dir': '周期性文档/月度开发报告',
|
|
231
|
+
'pattern': '项目月度开发报告{n:02d}.xlsx', 'match': r'月度开发报告[-_]?(\d{1,2})',
|
|
232
|
+
'bare': r'月度开发报告', 'freq': '月', 'count': 12, 'required': False},
|
|
233
|
+
]
|
|
234
|
+
|
|
235
|
+
# 阶段评审:每个阶段一份评审报告(xls) + 一份会议签到表(docx),缺一半就是流程没闭环
|
|
236
|
+
REVIEWS = [
|
|
237
|
+
{'stage': '立项', 'match': r'立项评审', 'report': '1-软件立项评审报告.xls',
|
|
238
|
+
'signin': '1-软件立项评审会议签到表.docx'},
|
|
239
|
+
{'stage': '设计', 'match': r'设计评审', 'report': '2-软件设计评审报告.xls',
|
|
240
|
+
'signin': '2-软件设计评审会议签到表.docx'},
|
|
241
|
+
{'stage': '测试用例', 'match': r'测试用例评审|软件测试评审', 'report': '3-系统测试用例评审报告.xls',
|
|
242
|
+
'signin': '3-系统测试用例评审会议签到表.docx'},
|
|
243
|
+
{'stage': '验收', 'match': r'验收评审', 'report': '4-项目验收评审报告.xls',
|
|
244
|
+
'signin': '4-项目验收评审会议签到表.docx'},
|
|
245
|
+
{'stage': '结项', 'match': r'结项评审', 'report': '5-项目结项评审报告.xls',
|
|
246
|
+
'signin': '5-项目结项评审会议签到表.docx'},
|
|
247
|
+
]
|
|
248
|
+
|
|
249
|
+
# 条件性目录:**只在发生了对应事件时才需要**,缺席不算缺陷(照抄模板目录去要求它们
|
|
250
|
+
# 会对每个顺利执行的项目都误报一次——这类噪声比漏报更快让人关掉检查)
|
|
251
|
+
CONDITIONAL = [
|
|
252
|
+
{'dir': '变更文档', 'when': '发生过人员/预算/范围/延期变更'},
|
|
253
|
+
{'dir': '委外文档', 'when': '有委外开发'},
|
|
254
|
+
{'dir': '测试文档', 'when': '有独立测试环节归档要求'},
|
|
255
|
+
]
|
|
256
|
+
|
|
257
|
+
# ── 模板残留 ───────────────────────────────────────────────────────────────
|
|
258
|
+
# 模板里成片的「提示:…」是写作指引,正式文档必须删干净;XX/XXX 是待替换占位符。
|
|
259
|
+
# 模板写给「填表人」的批注(不是写给读者的注释)。正式交付件里必须删干净。
|
|
260
|
+
# 判据用**明确的指令性措辞**而不是笼统的「注:」——「注:数据口径以合同为准」是正经注释,
|
|
261
|
+
# 「注:由项目单位如实填写实际完成情况,下同。」才是模板批注。两者只差几个字,判错就天天误报。
|
|
262
|
+
TEMPLATE_NOTES = [
|
|
263
|
+
r'注[::]\s*由[^。;\n]{0,24}(?:填写|摘抄|提供)',
|
|
264
|
+
r'请选择以下结论',
|
|
265
|
+
r'如实填写',
|
|
266
|
+
r'摘抄约定内容',
|
|
267
|
+
r'下同[。.]',
|
|
268
|
+
r'正式文档中需删除',
|
|
269
|
+
r'注[::]\s*[^。;\n]{0,12}请(?:选择|填写|注明|按)',
|
|
270
|
+
]
|
|
271
|
+
# 需要勾选的选项:一组括号**一个都没填** = 这道题没做。
|
|
272
|
+
# 只判括号不判方框:方框是多选/单选题,选完必然剩下未选项,剩几个是正常的。
|
|
273
|
+
EMPTY_CHOICE_RE = re.compile(r'[((][ ]{1,6}[))]')
|
|
274
|
+
# 「已勾选」只认**勾选记号**,或两侧带空格的数字。
|
|
275
|
+
# 不能把裸的「(1)」算作已勾——那是标题自动编号(本项目的四级标题就是「(1)」),
|
|
276
|
+
# 一份带四级编号的文档会因此永远不报「选择项未勾」,静默漏报。
|
|
277
|
+
FILLED_CHOICE_RE = re.compile(r'[((][ ]*[√✓✔☑■×✗xX][ ]*[))]'
|
|
278
|
+
r'|[((][ ]+[\d一二三四五六七八九][ ]+[))]')
|
|
279
|
+
# 方框型选择题:**一个都没勾** = 这道题一道都没做。
|
|
280
|
+
# 与括号型分开判,判据也不同:方框常是多选,选完必然剩下未选项,「剩几个」不算问题;
|
|
281
|
+
# 但整份文档里一个勾都找不到(真实归档的人员变更申请表就是「□是 □否」原样交出去),
|
|
282
|
+
# 那就是从头到尾没人填过。
|
|
283
|
+
EMPTY_BOX_RE = re.compile(r'[□☐]')
|
|
284
|
+
FILLED_BOX_RE = re.compile(r'[■☑☒▣✔✓√]')
|
|
285
|
+
|
|
286
|
+
# ── 模板写死的字数上限 ────────────────────────────────────────────────────
|
|
287
|
+
# 模板正文里白纸黑字写着「(500字内)」「(200字内,包括立项文件号、合同号、研究起止时间)」。
|
|
288
|
+
# 这不是建议而是填表要求:真实交付件把「项目立项背景」写到 4000+ 字(限 500),
|
|
289
|
+
# 高企认定/加计扣除的审查人是按模板逐条核的。
|
|
290
|
+
# 数字取自模板原文,不是我定的——改之前先去模板里找到那句话。
|
|
291
|
+
WORD_LIMITS = [
|
|
292
|
+
('工作总结报告', '项目立项背景', 500, ''),
|
|
293
|
+
('工作总结报告', '项目立项的依据和来源', 200, '包括立项文件号、合同号、研究起止时间'),
|
|
294
|
+
('技术总结报告', '项目简介', 500, '重点说明本项目解决的技术问题'),
|
|
295
|
+
]
|
|
296
|
+
# 超出多少才报:模板写「500字内」「500字左右」,卡死 500 会把 520 字也报出来,没意义。
|
|
297
|
+
WORD_LIMIT_SLACK = 1.5
|
|
298
|
+
|
|
299
|
+
# 跨文档类型的样板段落:同一段话逐字出现在**多种不同用途**的文档里。
|
|
300
|
+
# 与「周期性文档雷同」不是一回事——那是 12 期月报互比(同类),
|
|
301
|
+
# 这是一段 449 字的技术描述同时出现在项目建议书、进度报告、验收总结、研发任务书里。
|
|
302
|
+
#
|
|
303
|
+
# 阈值量自真语料:立项三件套(建议书→可研→立项申请书)共享背景是**正当的**,
|
|
304
|
+
# 可研本就是建议书的展开——它们只占 3 种类型,所以门槛定在 **≥4 种**。
|
|
305
|
+
# 真实两个项目分别有 13 段和 34 段越过这条线(后者最严重的一段横跨 9 种类型、20 份文件)。
|
|
306
|
+
# 60 字下限排掉标题、表头、固定表述这些天然重复的短句。
|
|
307
|
+
BOILER_MIN_CHARS = 60
|
|
308
|
+
BOILER_MIN_KINDS = 4
|
|
309
|
+
|
|
310
|
+
# 模板点名「这一节必须包含什么」。两个参考项目的立项依据都只写了「依据…文件精神」,
|
|
311
|
+
# 文件号与合同号一个都没有——审查人按模板逐项对,这是当场会被问的。
|
|
312
|
+
SECTION_MUST_MENTION = [
|
|
313
|
+
('工作总结报告', '项目立项的依据和来源', [
|
|
314
|
+
('立项文件号', re.compile(r'第?[〔\[((]?\d{2,4}[〕\]))]?\s*[号第]|文件号|批复号')),
|
|
315
|
+
('合同号', re.compile(r'合同[号编]|合同编号')),
|
|
316
|
+
('研究起止时间', re.compile(r'20\d{2}\s*年.{0,6}(?:至|—|-|到).{0,6}20\d{2}\s*年|起止')),
|
|
317
|
+
]),
|
|
318
|
+
]
|
|
319
|
+
|
|
320
|
+
# 签到表的与会人表:表头有「姓名」,底下却一行都没填 = 这个会没有任何与会记录。
|
|
321
|
+
# 判建议档不判必修:纸质签到表原件常在线下,电子件留空是常见做法。
|
|
322
|
+
SIGNIN_HEADER = ('姓名', '签名')
|
|
323
|
+
|
|
324
|
+
# ── 项目名称 ─────────────────────────────────────────────────────────────
|
|
325
|
+
# 「基于X的Y系统(的)研发」这一族。末尾不吃「项目」二字,否则会把
|
|
326
|
+
# 「…系统的研发项目提供了以下平台」整句吞进来当成一个项目名。
|
|
327
|
+
PROJECT_NAME_RE = re.compile(r'基于[一-龥]{2,14}?的?[一-龥]{2,16}?(?:系统|平台)(?:的研发|研发)?')
|
|
328
|
+
# 简称是正常的:真实归档里「…系统的研发」「…系统研发」「…系统」三种写法混用 144 次,
|
|
329
|
+
# 归一化后相等就一律放过——把它们报出来只会淹掉真正的错字。
|
|
330
|
+
_NAME_TRIM = re.compile(r'的|\s|项目$|的研发$|研发$')
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def name_key(name):
|
|
334
|
+
"""项目名归一化:去掉「的」、空白与「(的)研发/项目」后缀。
|
|
335
|
+
归一化后仍不相等,才可能是错字或另一个项目。"""
|
|
336
|
+
prev = None
|
|
337
|
+
cur = (name or '').strip()
|
|
338
|
+
while cur != prev: # 「…系统的研发项目」要连剥两层
|
|
339
|
+
prev = cur
|
|
340
|
+
cur = _NAME_TRIM.sub('', cur)
|
|
341
|
+
return cur
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
# 表单类归档件:会议名称/项目名称栏里**只该出现本项目**。
|
|
345
|
+
# 真实归档两个项目各抓到一处:深度学习的结项评审签到表写着联邦学习的项目名,
|
|
346
|
+
# 联邦学习的软件设计评审签到表写着「基于信用模型算法的供应商管理系统研发」——
|
|
347
|
+
# 都是拿上一个项目的文件改的,改漏了标题。
|
|
348
|
+
FORM_KINDS = ('签到表', '评审报告', '进度表', '预算表', '申请表', '申请书', '通知', '决议')
|
|
349
|
+
|
|
350
|
+
# 这几类文档没有图基本说不过去——技术路线、架构、流程总要画出来
|
|
351
|
+
FIGURE_EXPECTED = ('技术总结报告', '可行性研究报告', '项目建议书', '概要设计说明书',
|
|
352
|
+
'详细设计说明书', '项目研发实施计划')
|
|
353
|
+
|
|
354
|
+
# 验收/总结类文档的「实际完成情况」栏里,这些措辞等于承认没完成——
|
|
355
|
+
# 而文档本身正在做验收。真实归档里出现过「进行中,指标为预计完成指标」,
|
|
356
|
+
# 两个项目都有,专家审查栏还是空的。
|
|
357
|
+
UNFINISHED_WORDS = ('进行中', '预计完成', '尚未完成', '暂未', '待完成', '未开展',
|
|
358
|
+
'正在推进', '后续完成', '有待')
|
|
359
|
+
# 验收类文档:这些栏位里出现未完成措辞才算问题(研究内容描述里出现是正常的)
|
|
360
|
+
ACCEPT_KINDS = ('项目验收报告', '工作总结报告', '技术总结报告')
|
|
361
|
+
|
|
362
|
+
LEAK_PATTERNS = [
|
|
363
|
+
('hint', re.compile(r'提示[::]'), 'error', '模板提示块未删除',
|
|
364
|
+
'模板里明确写了「正式文档中需删除提示内容」,留着交出去等于把说明书当正文'),
|
|
365
|
+
('placeholder', re.compile(r'(?<![A-Za-z])XX+(?![A-Za-z])|××'), 'error', '残留 XX 占位符',
|
|
366
|
+
'模板占位没替换:XX 部 / XX 项目 / XX 年度'),
|
|
367
|
+
('todo', re.compile(r'待补充|待完善|TBD|待定(?![常义])|此处填写|请填写'), 'warn', '留了待办占位',
|
|
368
|
+
''),
|
|
369
|
+
]
|
|
370
|
+
|
|
371
|
+
# 全档一致性字段:这几个在真实归档里出错最多,逐份核对
|
|
372
|
+
CONSISTENCY_FIELDS = ['项目名称', '项目编号', '项目负责人', '项目联系人',
|
|
373
|
+
'联系电话', '建设单位', '起止时间']
|
|
374
|
+
|
|
375
|
+
# 字段串位检测:这几个字段的取值有明确形态,填错位一眼可判
|
|
376
|
+
FIELD_SHAPES = {
|
|
377
|
+
'联系电话': (re.compile(r'^\+?\d[\d\s\-]{6,19}$'), '应为电话号码'),
|
|
378
|
+
'项目联系人': (re.compile(r'^[^\d]{2,20}$'), '应为人名,不是号码'),
|
|
379
|
+
'项目负责人': (re.compile(r'^[^\d]{2,20}$'), '应为人名,不是号码'),
|
|
380
|
+
'编制人': (re.compile(r'^[^\d]{2,20}$'), '应为人名,不是号码'),
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
SPEC = {
|
|
384
|
+
'name': 'hengtong',
|
|
385
|
+
'label': '研发项目归档规范(编号目录体例:1 立项 / 5 任务书 / 6 实施计划 / 7 进度表 / '
|
|
386
|
+
'8 预算 / 9-10 验收 + 评审文件 + 周期性文档)',
|
|
387
|
+
'org_line': '{company}技术中心{dept}',
|
|
388
|
+
'cover_fields': FIELD_KEYS,
|
|
389
|
+
'items': ARCHIVE_ITEMS,
|
|
390
|
+
'periodic': PERIODIC,
|
|
391
|
+
'reviews': REVIEWS,
|
|
392
|
+
'conditional': CONDITIONAL,
|
|
393
|
+
'sections': SECTIONS,
|
|
394
|
+
'form_fields': FORM_FIELDS,
|
|
395
|
+
'approvals': APPROVALS,
|
|
396
|
+
'consistency': CONSISTENCY_FIELDS,
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def load(name_or_path='hengtong'):
|
|
401
|
+
"""取规范。传路径则读自定义 JSON(只覆盖给出的键,其余沿用内置)。"""
|
|
402
|
+
s = str(name_or_path or 'hengtong')
|
|
403
|
+
if s in ('hengtong', '', 'default'):
|
|
404
|
+
return dict(SPEC)
|
|
405
|
+
if os.path.exists(s):
|
|
406
|
+
over = json.load(open(s, encoding='utf-8'))
|
|
407
|
+
out = dict(SPEC)
|
|
408
|
+
out.update(over)
|
|
409
|
+
return out
|
|
410
|
+
return dict(SPEC)
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def kind_of(filename, spec=None):
|
|
414
|
+
"""按文件名判断这是哪一类文档(用正则,容忍改名)。认不出返回 None。"""
|
|
415
|
+
spec = spec or SPEC
|
|
416
|
+
base = os.path.basename(str(filename))
|
|
417
|
+
stem = os.path.splitext(base)[0]
|
|
418
|
+
for p in spec['periodic']:
|
|
419
|
+
if re.search(p['match'], stem):
|
|
420
|
+
return p['kind']
|
|
421
|
+
# 模板件没有期号(「XX项目研发进度报告-季度.docx」「2-项目研发进度表-实际.xlsx」),
|
|
422
|
+
# 带期号的正则认不出它们。认不出就会被归进「不在规范目录内」——
|
|
423
|
+
# 等于告诉用户「这份文件不知道是什么」,而它明明就是规范里的那一类。
|
|
424
|
+
for p in spec['periodic']:
|
|
425
|
+
if p.get('bare') and re.search(p['bare'], stem):
|
|
426
|
+
return p['kind']
|
|
427
|
+
for r in spec['reviews']:
|
|
428
|
+
if re.search(r['match'], stem):
|
|
429
|
+
return f"{r['stage']}评审" + ('签到表' if '签到' in stem else '报告')
|
|
430
|
+
# 长匹配优先:「项目验收申请表」不能被「验收报告」的规则先抢走
|
|
431
|
+
best = None
|
|
432
|
+
for it in spec['items']:
|
|
433
|
+
m = re.search(it['match'], stem)
|
|
434
|
+
if m and (best is None or len(m.group(0)) > best[1]):
|
|
435
|
+
best = (it['kind'], len(m.group(0)))
|
|
436
|
+
return best[0] if best else None
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
def outline(kind, spec=None):
|
|
440
|
+
"""出某类文档的 Markdown 骨架(章节 + 表单字段 + 签批栏)。"""
|
|
441
|
+
spec = spec or SPEC
|
|
442
|
+
secs = spec['sections'].get(kind)
|
|
443
|
+
if secs is None:
|
|
444
|
+
return f'未收录「{kind}」。已收录:' + '、'.join(spec['sections'])
|
|
445
|
+
out = [f'# {kind}', '']
|
|
446
|
+
fields = spec['form_fields'].get(kind)
|
|
447
|
+
if fields:
|
|
448
|
+
out += ['本类为**表单式**文档,主体是字段表(用 create_doc 的 type:"kv"),不是散文。字段:', '']
|
|
449
|
+
out += [f'- {f}:' for f in fields] + ['']
|
|
450
|
+
for title, subs, level, _al in secs:
|
|
451
|
+
out.append(f'## {title}' + ('' if level == 'must' else '(模板有,实践中常省略)'))
|
|
452
|
+
for s in subs:
|
|
453
|
+
out.append(f'### {s}')
|
|
454
|
+
out.append('')
|
|
455
|
+
ap = spec['approvals'].get(kind)
|
|
456
|
+
if ap:
|
|
457
|
+
out += ['## 审批栏(缺一级就是流程没走完)', ''] + [f'- {a}:' for a in ap] + ['']
|
|
458
|
+
return '\n'.join(out)
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
def self_test():
|
|
462
|
+
assert field_key('项 目 名 称:') == '项目名称'
|
|
463
|
+
assert field_key('联 系 电 话') == '联系电话'
|
|
464
|
+
assert field_key('报告编写人') == '编制人'
|
|
465
|
+
assert field_key('编制日期') == '编制时间', '生成器用「编制日期」、模板用「编制时间」,别名必须打通'
|
|
466
|
+
assert kind_of('6-项目研发实施计划.docx') == '项目研发实施计划', kind_of('6-项目研发实施计划.docx')
|
|
467
|
+
assert kind_of('研发进度报告-03.docx') == '研发进度报告'
|
|
468
|
+
assert kind_of('1-项目研发进度表-实际-第2季度.xlsx') == '项目研发进度表-实际'
|
|
469
|
+
assert kind_of('软件立项评审报告_01.xls') == '立项评审报告'
|
|
470
|
+
assert kind_of('1-软件立项评审会议签到表.docx') == '立项评审签到表'
|
|
471
|
+
assert kind_of('项目验收申请表.docx') == '项目验收申请表', kind_of('项目验收申请表.docx')
|
|
472
|
+
assert kind_of('项目验收报告.docx') == '项目验收报告'
|
|
473
|
+
assert kind_of('毫不相干的文件.txt') is None
|
|
474
|
+
assert '项目考核指标' in outline('立项申请书')
|
|
475
|
+
assert '立项的背景与意义' in outline('可行性研究报告'), '可研必须用真实体例'
|
|
476
|
+
assert '技术负责人意见' in outline('立项申请书')
|
|
477
|
+
assert '表单式' in outline('项目验收申请表')
|
|
478
|
+
assert LEAK_PATTERNS[0][1].search('提示:这里要写清楚')
|
|
479
|
+
import re as _re
|
|
480
|
+
_tn = _re.compile('|'.join(TEMPLATE_NOTES))
|
|
481
|
+
for _t in ('注:由项目单位如实填写实际完成情况,下同。', '注:专家请选择以下结论。',
|
|
482
|
+
'注:由项目单位对照《立项申请书》摘抄约定内容'):
|
|
483
|
+
assert _tn.search(_t), _t
|
|
484
|
+
for _t in ('注:数据口径以合同附件三为准。', '注:金额单位为万元。', '注:本表由财务部填报后归档'):
|
|
485
|
+
assert not _tn.search(_t), f'正经注释被误判:{_t}'
|
|
486
|
+
assert EMPTY_CHOICE_RE.search('完成70%及以上( )') and not EMPTY_CHOICE_RE.search('(√)')
|
|
487
|
+
assert FILLED_CHOICE_RE.search('(√)') and FILLED_CHOICE_RE.search('( 1 )')
|
|
488
|
+
assert not FILLED_CHOICE_RE.search('(1)本节说明'), '标题编号「(1)」被当成了勾选'
|
|
489
|
+
assert not FILLED_CHOICE_RE.search('(二)技术路线'), '标题编号「(二)」被当成了勾选'
|
|
490
|
+
assert LEAK_PATTERNS[1][1].search('技术中心XX部') and not LEAK_PATTERNS[1][1].search('XXL 号')
|
|
491
|
+
ok, _ = FIELD_SHAPES['联系电话']
|
|
492
|
+
assert ok.match('13809475135') and not ok.match('陈波')
|
|
493
|
+
print(f'[archive_spec] self-test OK · {len(ARCHIVE_ITEMS)} 项必备文档 / '
|
|
494
|
+
f'{len(PERIODIC)} 类周期性({sum(p["count"] for p in PERIODIC)} 期)/ '
|
|
495
|
+
f'{len(REVIEWS)} 个阶段评审 / {len(SECTIONS)} 类章节骨架')
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
if __name__ == '__main__':
|
|
499
|
+
self_test()
|