@chongyan/autospec 1.0.1 → 1.0.2
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 +21 -21
- package/README.en.md +447 -321
- package/README.md +418 -286
- package/knowledge/01-principles/00-principles-hierarchy.md +247 -0
- package/knowledge/01-principles/01-first-principles.md +241 -0
- package/knowledge/01-principles/02-strategic-principles.md +286 -0
- package/knowledge/01-principles/03-tactical-principles.md +385 -0
- package/knowledge/01-principles/04-operational-principles.md +275 -0
- package/knowledge/01-principles/05-domain-principles.md +539 -0
- package/knowledge/01-principles/06-methodology-principles.md +281 -0
- package/knowledge/01-principles/07-cognitive-principles.md +277 -0
- package/knowledge/01-principles/08-auto-fix-principles.md +320 -0
- package/knowledge/01-principles/09-constitution.md +220 -0
- package/knowledge/{principles/evolution.md → 01-principles/10-evolution-mechanism.md} +160 -14
- package/knowledge/01-principles/README.en.md +385 -0
- package/knowledge/01-principles/README.md +385 -0
- package/knowledge/{process/overview.md → 02-process/00-overview.md} +90 -5
- package/knowledge/02-process/README.en.md +143 -0
- package/knowledge/02-process/README.md +186 -0
- package/knowledge/{guides/support/pipeline-protocol.md → 03-guides/00-pipeline-protocol.md} +10 -10
- package/knowledge/{guides/support/team-orchestrator.md → 03-guides/01-team-orchestrator.md} +53 -8
- package/knowledge/{guides/stages/requirement-analyzer.md → 03-guides/02-analyze-requirement.md} +3 -3
- package/knowledge/{guides/stages/ai-effect-evaluator.md → 03-guides/08-evaluate-ai-effect.md} +14 -7
- package/knowledge/{guides/support/skill-distiller.md → 03-guides/19-distill-skill.md} +3 -3
- package/knowledge/{guides/support/skill-updater.md → 03-guides/20-update-skill.md} +1 -1
- package/knowledge/{guides/support/methodology-extractor.md → 03-guides/22-extract-methodology.md} +2 -2
- package/knowledge/{guides/support/complexity-assessor.md → 03-guides/24-assess-complexity.md} +6 -4
- package/knowledge/{guides/support/tech-stack-analyzer.md → 03-guides/26-analyze-tech-stack.md} +1 -1
- package/knowledge/{guides/domain-driven-design.md → 03-guides/42-apply-ddd.md} +1 -1
- package/knowledge/{process/ai-sdlc.md → 03-guides/43-run-ai-sdlc.md} +1 -1
- package/knowledge/{guides/knowledge-management.md → 03-guides/44-manage-knowledge.md} +4 -4
- package/knowledge/03-guides/README.en.md +212 -0
- package/knowledge/03-guides/README.md +212 -0
- package/knowledge/{checklists/requirement.md → 04-checklists/00-requirement.md} +1 -1
- package/knowledge/{checklists/design.md → 04-checklists/01-design.md} +1 -1
- package/knowledge/{checklists/code.md → 04-checklists/02-code.md} +16 -1
- package/knowledge/{checklists/release.md → 04-checklists/04-release.md} +1 -1
- package/knowledge/04-checklists/README.en.md +119 -0
- package/knowledge/04-checklists/README.md +123 -0
- package/knowledge/{config/validation-patterns.yaml → 05-config/00-validation-patterns.yaml} +1 -1
- package/knowledge/{config/team-tasks.yaml → 05-config/02-team-tasks.yaml} +2 -2
- package/knowledge/05-config/03-role-composition.yaml +346 -0
- package/knowledge/{config/skill-compositions.yaml → 05-config/05-skill-compositions.yaml} +24 -24
- package/knowledge/05-config/README.en.md +54 -0
- package/knowledge/05-config/README.md +132 -0
- package/knowledge/06-environment/00-template-registry.md +310 -0
- package/knowledge/06-environment/01-detection-patterns.yaml +1692 -0
- package/knowledge/{environment → 06-environment}/README.en.md +4 -0
- package/knowledge/{environment → 06-environment}/README.md +66 -25
- package/knowledge/{standards/coding-style.md → 07-standards/00-coding-style.md} +123 -4
- package/knowledge/{standards/code-review.md → 07-standards/01-code-review.md} +3 -3
- package/knowledge/{standards/data-consistency.md → 07-standards/02-data-consistency.md} +1 -1
- package/knowledge/{standards/document-versioning.md → 07-standards/03-document-versioning.md} +1 -1
- package/knowledge/{standards/risk-detection.md → 07-standards/04-risk-detection.md} +5 -5
- package/knowledge/07-standards/README.en.md +119 -0
- package/knowledge/07-standards/README.md +123 -0
- package/knowledge/08-organization/00-vision-mission.md +113 -0
- package/knowledge/{organization/ai-native-team.md → 08-organization/01-ai-native-culture.md} +1 -1
- package/knowledge/{organization/team-metrics.md → 08-organization/02-team-metrics.md} +1 -1
- package/knowledge/08-organization/03-committee-structure.md +54 -0
- package/knowledge/08-organization/04-governance-metrics.md +55 -0
- package/knowledge/08-organization/05-improvement-process.md +71 -0
- package/knowledge/08-organization/README.en.md +165 -0
- package/knowledge/08-organization/README.md +165 -0
- package/knowledge/09-templates/00-requirement-proposal.md +344 -0
- package/knowledge/09-templates/01-architecture-design.md +494 -0
- package/knowledge/09-templates/02-api-design.md +408 -0
- package/knowledge/09-templates/03-database-design.md +313 -0
- package/knowledge/09-templates/04-product-design.md +237 -0
- package/knowledge/09-templates/05-domain-business.md +388 -0
- package/knowledge/09-templates/06-test-design.md +268 -0
- package/knowledge/09-templates/07-evaluation-design.md +372 -0
- package/knowledge/09-templates/08-component-knowledge.md +272 -0
- package/knowledge/09-templates/09-best-practices.md +218 -0
- package/knowledge/{environment/middleware-knowledge.md → 09-templates/10-middleware-knowledge.md} +106 -1
- package/knowledge/09-templates/README.en.md +222 -0
- package/knowledge/09-templates/README.md +216 -0
- package/knowledge/README.en.md +372 -0
- package/knowledge/README.md +354 -99
- package/package.json +1 -1
- package/plugins/.claude-plugin/plugin.json +460 -81
- package/plugins/agents/roles/ceo.md +1 -1
- package/plugins/agents/roles/product-owner.md +1 -1
- package/plugins/agents/roles/tech-lead.md +1 -1
- package/plugins/agents/support/consistency-checker.md +36 -3
- package/plugins/agents/support/monitoring-agent.md +215 -0
- package/plugins/agents/support/safety-auditor.md +2 -2
- package/plugins/agents/support/stage-gate-evaluator.md +95 -11
- package/plugins/agents/support/test-coverage-reviewer.md +1 -1
- package/plugins/benchmarks/templates/README.md +165 -13
- package/plugins/benchmarks/templates/commands/apply-template.yaml +108 -0
- package/plugins/benchmarks/templates/commands/archive-template.yaml +65 -0
- package/plugins/benchmarks/templates/commands/env-export-template.yaml +64 -0
- package/plugins/benchmarks/templates/commands/env-sync-template.yaml +104 -0
- package/plugins/benchmarks/templates/commands/env-template-template.yaml +96 -0
- package/plugins/benchmarks/templates/commands/env-template.yaml +58 -0
- package/plugins/benchmarks/templates/commands/env-update-template.yaml +110 -0
- package/plugins/benchmarks/templates/commands/env-validate-template.yaml +95 -0
- package/plugins/benchmarks/templates/commands/field-evolve-template.yaml +104 -0
- package/plugins/benchmarks/templates/commands/project-evolve-template.yaml +104 -0
- package/plugins/benchmarks/templates/commands/propose-template.yaml +88 -0
- package/plugins/benchmarks/templates/commands/review-template.yaml +124 -0
- package/plugins/benchmarks/templates/commands/run-template.yaml +127 -0
- package/plugins/benchmarks/templates/commands/test-template.yaml +149 -0
- package/plugins/benchmarks/templates/pipeline/experiment-template.yaml +92 -0
- package/plugins/benchmarks/templates/pipeline/hotfix-template.yaml +81 -0
- package/plugins/benchmarks/templates/skills/agile-iteration-template.yaml +78 -0
- package/plugins/benchmarks/templates/skills/benchmark-executor-template.yaml +114 -0
- package/plugins/benchmarks/templates/skills/benchmark-generator-template.yaml +52 -0
- package/plugins/benchmarks/templates/skills/delivery-stage-template.yaml +130 -0
- package/plugins/benchmarks/templates/skills/design-stage-template.yaml +131 -0
- package/plugins/benchmarks/templates/skills/experiment-iteration-template.yaml +60 -0
- package/plugins/benchmarks/templates/skills/exploration-phase-template.yaml +114 -0
- package/plugins/benchmarks/templates/skills/field-evolve-analyzer-template.yaml +51 -0
- package/plugins/benchmarks/templates/skills/field-evolve-distiller-template.yaml +34 -0
- package/plugins/benchmarks/templates/skills/field-evolve-executor-template.yaml +50 -0
- package/plugins/benchmarks/templates/skills/field-evolve-fixer-template.yaml +52 -0
- package/plugins/benchmarks/templates/skills/field-evolve-learner-template.yaml +33 -0
- package/plugins/benchmarks/templates/skills/field-evolve-scanner-template.yaml +74 -0
- package/plugins/benchmarks/templates/skills/field-evolve-template.yaml +71 -0
- package/plugins/benchmarks/templates/skills/field-evolve-verifier-template.yaml +51 -0
- package/plugins/benchmarks/templates/skills/hotfix-iteration-template.yaml +54 -0
- package/plugins/benchmarks/templates/skills/implementation-stage-template.yaml +127 -0
- package/plugins/benchmarks/templates/skills/layer1-validation-template.yaml +121 -0
- package/plugins/benchmarks/templates/skills/project-evolve-analyzer-template.yaml +51 -0
- package/plugins/benchmarks/templates/skills/project-evolve-fixer-template.yaml +52 -0
- package/plugins/benchmarks/templates/skills/project-evolve-generator-template.yaml +34 -0
- package/plugins/benchmarks/templates/skills/project-evolve-learner-template.yaml +50 -0
- package/plugins/benchmarks/templates/skills/project-evolve-reviewer-template.yaml +50 -0
- package/plugins/benchmarks/templates/skills/project-evolve-scanner-template.yaml +75 -0
- package/plugins/benchmarks/templates/skills/project-evolve-template.yaml +72 -0
- package/plugins/benchmarks/templates/skills/project-evolve-verifier-template.yaml +51 -0
- package/plugins/benchmarks/templates/skills/skill-forge-template.yaml +117 -0
- package/plugins/benchmarks/templates/skills/startup-guard-template.yaml +103 -0
- package/plugins/benchmarks/templates/skills/testing-stage-template.yaml +146 -0
- package/plugins/benchmarks/templates/skills/waterfall-iteration-template.yaml +55 -0
- package/plugins/commands/README.en.md +2 -2
- package/plugins/commands/README.md +2 -2
- package/plugins/commands/apply.md +102 -16
- package/plugins/commands/archive.md +60 -4
- package/plugins/commands/env-sync.md +1047 -406
- package/plugins/commands/env-template.md +11 -135
- package/plugins/commands/env-update.md +1 -1
- package/plugins/commands/env-validate.md +3 -3
- package/plugins/commands/explore.md +118 -1
- package/plugins/commands/field-evolve.md +51 -175
- package/plugins/commands/project-evolve.md +167 -68
- package/plugins/commands/propose.md +97 -6
- package/plugins/commands/review.md +5 -5
- package/plugins/commands/run.md +841 -13
- package/plugins/commands/status.md +138 -17
- package/plugins/commands/test.md +389 -0
- package/plugins/hooks/constitution-guard.js +1 -1
- package/plugins/hooks/environment-autocommit.js +366 -24
- package/plugins/hooks/environment-manager.js +3 -2
- package/plugins/hooks/execution-tracker.js +109 -4
- package/plugins/hooks/layer1-validator.js +117 -1
- package/plugins/hooks/lib/auto-fix-loop.js +605 -0
- package/plugins/hooks/lib/environment-config-loader.js +11 -7
- package/plugins/hooks/lib/hook-state-manager.js +98 -0
- package/plugins/hooks/lib/memory-extractor.js +27 -5
- package/plugins/hooks/lib/memory-manager.js +1 -1
- package/plugins/hooks/lib/test-auto-fix.test.js +194 -0
- package/plugins/hooks/monitoring-trigger.js +467 -0
- package/plugins/skills/README.en.md +15 -3
- package/plugins/skills/README.md +21 -11
- package/plugins/skills/agile-iteration/SKILL.md +187 -0
- package/plugins/skills/delivery-stage/SKILL.md +133 -12
- package/plugins/skills/design-stage/SKILL.md +103 -12
- package/plugins/skills/experiment-evaluator/SKILL.md +271 -0
- package/plugins/skills/experiment-iteration/SKILL.md +154 -0
- package/plugins/skills/exploration-phase/SKILL.md +93 -10
- package/plugins/skills/field-evolve-analyzer/SKILL.md +65 -0
- package/plugins/skills/field-evolve-distiller/SKILL.md +66 -0
- package/plugins/skills/field-evolve-executor/SKILL.md +94 -0
- package/plugins/skills/field-evolve-executor/executor.js +342 -0
- package/plugins/skills/field-evolve-fixer/SKILL.md +69 -0
- package/plugins/skills/field-evolve-learner/SKILL.md +65 -0
- package/plugins/skills/field-evolve-scanner/SKILL.md +87 -0
- package/plugins/skills/field-evolve-scanner/scripts/fallback-scanner.js +288 -0
- package/plugins/skills/field-evolve-verifier/SKILL.md +64 -0
- package/plugins/skills/hotfix-iteration/SKILL.md +279 -0
- package/plugins/skills/implementation-stage/SKILL.md +156 -15
- package/plugins/skills/layer1-validation/SKILL.md +1 -1
- package/plugins/skills/pending-dashboard/SKILL.md +9 -8
- package/plugins/skills/project-evolve-analyzer/SKILL.md +95 -0
- package/plugins/skills/project-evolve-fixer/SKILL.md +99 -0
- package/plugins/skills/project-evolve-generator/SKILL.md +149 -0
- package/plugins/skills/project-evolve-learner/SKILL.md +103 -0
- package/plugins/skills/project-evolve-reviewer/SKILL.md +104 -0
- package/plugins/skills/project-evolve-scanner/SKILL.md +95 -0
- package/plugins/skills/project-evolve-scanner/scripts/dependency-reuse-checker.js +395 -0
- package/plugins/skills/project-evolve-scanner/scripts/subsystem-coverage.js +315 -0
- package/plugins/skills/project-evolve-verifier/SKILL.md +105 -0
- package/plugins/skills/requirement-stage/SKILL.md +47 -13
- package/plugins/skills/skill-forge/SKILL.md +2 -2
- package/plugins/skills/testing-stage/SKILL.md +583 -8
- package/plugins/skills/waterfall-iteration/SKILL.md +115 -0
- package/scripts/cli/index.js +1 -1
- package/scripts/cli/init.js +30 -4
- package/scripts/cli/list.js +3 -2
- package/scripts/config/commands.config.js +8 -8
- package/scripts/config/hooks.config.js +1 -1
- package/scripts/install/constants.js +204 -165
- package/scripts/state.js +210 -1
- package/knowledge/config/README.en.md +0 -44
- package/knowledge/config/README.md +0 -44
- package/knowledge/config/role-composition.yaml +0 -98
- package/knowledge/config/team-triggers.yaml +0 -198
- package/knowledge/domain/README.md +0 -115
- package/knowledge/domain/flows/README.md +0 -194
- package/knowledge/domain/glossary.md +0 -143
- package/knowledge/domain/rules.md +0 -138
- package/knowledge/environment/component-knowledge.md +0 -316
- package/knowledge/environment/detection-patterns.yaml +0 -502
- package/knowledge/environment/template-registry.md +0 -321
- package/knowledge/guides/requirement-engineering.md +0 -329
- package/knowledge/guides/system-design.md +0 -352
- package/knowledge/principles/constitution.md +0 -134
- package/knowledge/principles/core-principles.md +0 -368
- package/knowledge/principles/design-philosophy.md +0 -877
- package/knowledge/process/README.en.md +0 -38
- package/knowledge/process/README.md +0 -48
- package/knowledge/templates/ai-evaluation.md +0 -150
- package/knowledge/templates/api-design.md +0 -117
- package/knowledge/templates/database-design.md +0 -132
- package/knowledge/templates/domain-driven-design.md +0 -321
- package/knowledge/templates/product-proposal.md +0 -201
- package/knowledge/templates/system-design.md +0 -227
- package/knowledge/templates/task-breakdown.md +0 -107
- package/knowledge/templates/test-case.md +0 -170
- package/plugins/commands/validate.md +0 -108
- package/plugins/skills/benchmark-executor/README.md +0 -93
- package/plugins/skills/evolution-process/SKILL.md +0 -291
- package/plugins/skills/project-evolution/SKILL.md +0 -847
- package/scripts/evolution/evolution-router.js +0 -273
- package/scripts/evolution/evolution-signal-collector.js +0 -307
- package/scripts/evolution/knowledge-loader.js +0 -346
- package/scripts/evolution/marketplace.js +0 -317
- package/scripts/evolution/version-manager.js +0 -371
- /package/knowledge/{process → 02-process}/01-requirement.md +0 -0
- /package/knowledge/{process → 02-process}/02-design.md +0 -0
- /package/knowledge/{process → 02-process}/03-implementation.md +0 -0
- /package/knowledge/{process → 02-process}/04-review.md +0 -0
- /package/knowledge/{process → 02-process}/05-testing.md +0 -0
- /package/knowledge/{process → 02-process}/06-delivery.md +0 -0
- /package/knowledge/{guides/stages/design-planner.md → 03-guides/03-design-solution.md} +0 -0
- /package/knowledge/{guides/stages/code-implementer.md → 03-guides/04-implement-code.md} +0 -0
- /package/knowledge/{guides/stages/test-planner.md → 03-guides/05-plan-testing.md} +0 -0
- /package/knowledge/{guides/stages/test-generator.md → 03-guides/06-generate-tests.md} +0 -0
- /package/knowledge/{guides/stages/release-checker.md → 03-guides/07-check-release.md} +0 -0
- /package/knowledge/{guides/stages/requirement-reviewer.md → 03-guides/09-review-requirement.md} +0 -0
- /package/knowledge/{guides/stages/design-reviewer.md → 03-guides/10-review-design.md} +0 -0
- /package/knowledge/{guides/stages/code-reviewer.md → 03-guides/11-review-code.md} +0 -0
- /package/knowledge/{guides/stages/test-reviewer.md → 03-guides/12-review-testing.md} +0 -0
- /package/knowledge/{guides/stages/security-reviewer.md → 03-guides/13-audit-security.md} +0 -0
- /package/knowledge/{guides/stages/consistency-checker.md → 03-guides/14-check-consistency.md} +0 -0
- /package/knowledge/{guides/stages/unit-test-runner.md → 03-guides/15-run-unit-tests.md} +0 -0
- /package/knowledge/{guides/stages/integration-test-runner.md → 03-guides/16-run-integration-tests.md} +0 -0
- /package/knowledge/{guides/stages/test-context-analyzer.md → 03-guides/17-analyze-test-context.md} +0 -0
- /package/knowledge/{guides/support/practice-logger.md → 03-guides/18-log-practice.md} +0 -0
- /package/knowledge/{guides/support/skill-validator.md → 03-guides/21-validate-skill.md} +0 -0
- /package/knowledge/{guides/support/scope-inference.md → 03-guides/23-infer-scope.md} +0 -0
- /package/knowledge/{guides/support/component-discovery.md → 03-guides/25-discover-component.md} +0 -0
- /package/knowledge/{guides/support/environment-scanner.md → 03-guides/27-scan-environment.md} +0 -0
- /package/knowledge/{guides/support/environment-validator.md → 03-guides/28-validate-environment.md} +0 -0
- /package/knowledge/{guides/support/knowledge-generator.md → 03-guides/29-generate-knowledge.md} +0 -0
- /package/knowledge/{guides/support/ai-capability-analyzer.md → 03-guides/30-analyze-ai-capability.md} +0 -0
- /package/knowledge/{guides/support/ai-component-analyzer.md → 03-guides/31-analyze-ai-component.md} +0 -0
- /package/knowledge/{guides/support/ai-agent-analyzer.md → 03-guides/32-analyze-ai-agent.md} +0 -0
- /package/knowledge/{guides/support/ai-rag-analyzer.md → 03-guides/33-analyze-ai-rag.md} +0 -0
- /package/knowledge/{guides/support/ai-task-assessor.md → 03-guides/34-assess-ai-task.md} +0 -0
- /package/knowledge/{guides/support/ai-pipeline-evaluator.md → 03-guides/35-evaluate-ai-pipeline.md} +0 -0
- /package/knowledge/{guides/support/ai-artifact-evaluator.md → 03-guides/36-evaluate-ai-artifact.md} +0 -0
- /package/knowledge/{guides/support/ai-evaluation-planner.md → 03-guides/37-plan-ai-evaluation.md} +0 -0
- /package/knowledge/{guides/support/ai-path-evaluator.md → 03-guides/38-evaluate-ai-path.md} +0 -0
- /package/knowledge/{guides/support/ai-data-validator.md → 03-guides/39-validate-ai-data.md} +0 -0
- /package/knowledge/{guides/support/ai-anomaly-analyzer.md → 03-guides/40-detect-ai-anomaly.md} +0 -0
- /package/knowledge/{guides/support/ai-test-diagnostics.md → 03-guides/41-diagnose-ai-test.md} +0 -0
- /package/knowledge/{guides/support/test-runner.md → 03-guides/45-test-runner.md} +0 -0
- /package/knowledge/{checklists/test.md → 04-checklists/03-test.md} +0 -0
- /package/knowledge/{config/team-stage.yaml → 05-config/01-team-stage.yaml} +0 -0
- /package/knowledge/{config/role-extensions.yaml → 05-config/04-role-extensions.yaml} +0 -0
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* AutoSpec Hook: Environment Autocommit
|
|
5
5
|
*
|
|
6
|
-
* 环境知识自动提交 Hook
|
|
6
|
+
* 环境知识自动提交 Hook(智能决策版)
|
|
7
7
|
* 触发时机:Stop 事件
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
*
|
|
9
|
+
* 智能决策机制:
|
|
10
|
+
* 1. 变更分类评估:纯新增/配置更新/文档更新 → 自动提交;删除/敏感字段 → 需确认
|
|
11
|
+
* 2. 安全检查:文件大小异常/敏感信息泄露/格式验证
|
|
12
|
+
* 3. 版本管理:本地提交自动执行;推送远端默认关闭;冲突检测
|
|
13
|
+
* 4. 决策报告:生成提交/跳过/需确认的决策报告
|
|
12
14
|
*/
|
|
13
15
|
|
|
14
16
|
import fs from 'fs';
|
|
@@ -17,6 +19,32 @@ import { createHookLogger, readStdin, findProjectRootAsync } from './lib/hook-lo
|
|
|
17
19
|
|
|
18
20
|
const logger = createHookLogger('environment-autocommit');
|
|
19
21
|
|
|
22
|
+
// 敏感字段模式(需要确认)
|
|
23
|
+
const SENSITIVE_PATTERNS = [
|
|
24
|
+
/password/i,
|
|
25
|
+
/secret/i,
|
|
26
|
+
/api[_-]?key/i,
|
|
27
|
+
/token/i,
|
|
28
|
+
/private[_-]?key/i,
|
|
29
|
+
/credential/i,
|
|
30
|
+
/auth/i,
|
|
31
|
+
/encrypt/i,
|
|
32
|
+
/salt/i,
|
|
33
|
+
/hash/i
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
// 配置文件模式(高安全度)
|
|
37
|
+
const CONFIG_PATTERNS = [
|
|
38
|
+
/port/i,
|
|
39
|
+
/host/i,
|
|
40
|
+
/endpoint/i,
|
|
41
|
+
/version/i,
|
|
42
|
+
/timeout/i,
|
|
43
|
+
/retry/i,
|
|
44
|
+
/pool/i,
|
|
45
|
+
/connection/i
|
|
46
|
+
];
|
|
47
|
+
|
|
20
48
|
/**
|
|
21
49
|
* 检查是否为 git 仓库
|
|
22
50
|
*/
|
|
@@ -24,6 +52,22 @@ function isGitRepo(dir) {
|
|
|
24
52
|
return fs.existsSync(path.join(dir, '.git'));
|
|
25
53
|
}
|
|
26
54
|
|
|
55
|
+
/**
|
|
56
|
+
* 检测是否有冲突
|
|
57
|
+
*/
|
|
58
|
+
function hasConflicts(repoDir) {
|
|
59
|
+
const { execSync } = require('child_process');
|
|
60
|
+
try {
|
|
61
|
+
const status = execSync('git status --porcelain', {
|
|
62
|
+
cwd: repoDir,
|
|
63
|
+
encoding: 'utf-8'
|
|
64
|
+
});
|
|
65
|
+
return status.split('\n').some(line => line.startsWith('UU') || line.startsWith('AA') || line.startsWith('DD'));
|
|
66
|
+
} catch (e) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
27
71
|
/**
|
|
28
72
|
* 获取 git 状态
|
|
29
73
|
*/
|
|
@@ -41,6 +85,210 @@ function getGitStatus(repoDir) {
|
|
|
41
85
|
}
|
|
42
86
|
}
|
|
43
87
|
|
|
88
|
+
/**
|
|
89
|
+
* 获取文件变更类型和原始路径
|
|
90
|
+
*/
|
|
91
|
+
function parseGitStatusLine(line) {
|
|
92
|
+
const statusCode = line.substring(0, 2);
|
|
93
|
+
const filePath = line.substring(3).trim();
|
|
94
|
+
|
|
95
|
+
// 状态码解析
|
|
96
|
+
const staged = statusCode[0];
|
|
97
|
+
const unstaged = statusCode[1];
|
|
98
|
+
|
|
99
|
+
let changeType = 'unknown';
|
|
100
|
+
if (staged === 'A' || unstaged === 'A') changeType = 'added';
|
|
101
|
+
else if (staged === 'M' || unstaged === 'M') changeType = 'modified';
|
|
102
|
+
else if (staged === 'D' || unstaged === 'D') changeType = 'deleted';
|
|
103
|
+
else if (staged === 'R') changeType = 'renamed';
|
|
104
|
+
else if (staged === 'C') changeType = 'copied';
|
|
105
|
+
else if (staged === '?' || unstaged === '?') changeType = 'untracked';
|
|
106
|
+
|
|
107
|
+
return { changeType, filePath, statusCode };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 获取文件内容
|
|
112
|
+
*/
|
|
113
|
+
function getFileContent(repoDir, filePath) {
|
|
114
|
+
try {
|
|
115
|
+
const fullPath = path.join(repoDir, filePath);
|
|
116
|
+
if (!fs.existsSync(fullPath)) return null;
|
|
117
|
+
return fs.readFileSync(fullPath, 'utf-8');
|
|
118
|
+
} catch (e) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 获取文件大小
|
|
125
|
+
*/
|
|
126
|
+
function getFileSize(repoDir, filePath) {
|
|
127
|
+
try {
|
|
128
|
+
const fullPath = path.join(repoDir, filePath);
|
|
129
|
+
if (!fs.existsSync(fullPath)) return 0;
|
|
130
|
+
const stats = fs.statSync(fullPath);
|
|
131
|
+
return stats.size;
|
|
132
|
+
} catch (e) {
|
|
133
|
+
return 0;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* 获取文件的 git 历史大小(用于比较)
|
|
139
|
+
*/
|
|
140
|
+
function getGitFileSize(repoDir, filePath) {
|
|
141
|
+
const { execSync } = require('child_process');
|
|
142
|
+
try {
|
|
143
|
+
const size = execSync(`git cat-file -s HEAD:"${filePath}" 2>/dev/null || echo 0`, {
|
|
144
|
+
cwd: repoDir,
|
|
145
|
+
encoding: 'utf-8'
|
|
146
|
+
}).trim();
|
|
147
|
+
return parseInt(size, 10) || 0;
|
|
148
|
+
} catch (e) {
|
|
149
|
+
return 0;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* 检查是否包含敏感信息
|
|
155
|
+
*/
|
|
156
|
+
function containsSensitiveInfo(content) {
|
|
157
|
+
if (!content) return false;
|
|
158
|
+
return SENSITIVE_PATTERNS.some(pattern => pattern.test(content));
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* 检查是否为纯配置更新(高安全度)
|
|
163
|
+
*/
|
|
164
|
+
function isConfigUpdate(content) {
|
|
165
|
+
if (!content) return false;
|
|
166
|
+
// 如果内容主要是配置项(包含多个配置模式),则认为是配置更新
|
|
167
|
+
const configMatches = CONFIG_PATTERNS.filter(pattern => pattern.test(content));
|
|
168
|
+
return configMatches.length >= 2;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* 检查 JSON/YAML 格式有效性
|
|
173
|
+
*/
|
|
174
|
+
function validateFormat(filePath, content) {
|
|
175
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
176
|
+
|
|
177
|
+
if (ext === '.json') {
|
|
178
|
+
try {
|
|
179
|
+
JSON.parse(content);
|
|
180
|
+
return { valid: true, error: null };
|
|
181
|
+
} catch (e) {
|
|
182
|
+
return { valid: false, error: `JSON 格式错误: ${e.message}` };
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (ext === '.yaml' || ext === '.yml') {
|
|
187
|
+
// 基础 YAML 检查(缩进、冒号等)
|
|
188
|
+
const lines = content.split('\n');
|
|
189
|
+
for (let i = 0; i < lines.length; i++) {
|
|
190
|
+
const line = lines[i];
|
|
191
|
+
// 检查混合缩进
|
|
192
|
+
if (line.match(/\t/) && line.match(/ /)) {
|
|
193
|
+
return { valid: false, error: `YAML 格式错误: 第 ${i + 1} 行混用空格和制表符` };
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return { valid: true, error: null };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return { valid: true, error: null };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* 评估单个文件的变更风险
|
|
204
|
+
*/
|
|
205
|
+
function assessFileRisk(repoDir, changeInfo) {
|
|
206
|
+
const { changeType, filePath } = changeInfo;
|
|
207
|
+
const content = getFileContent(repoDir, filePath);
|
|
208
|
+
const currentSize = getFileSize(repoDir, filePath);
|
|
209
|
+
const originalSize = getGitFileSize(repoDir, filePath);
|
|
210
|
+
|
|
211
|
+
const assessment = {
|
|
212
|
+
filePath,
|
|
213
|
+
changeType,
|
|
214
|
+
decision: 'pending',
|
|
215
|
+
reason: [],
|
|
216
|
+
riskLevel: 'low'
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
// 1. 变更类型评估
|
|
220
|
+
if (changeType === 'deleted') {
|
|
221
|
+
assessment.decision = 'confirm';
|
|
222
|
+
assessment.reason.push('删除操作需要确认');
|
|
223
|
+
assessment.riskLevel = 'high';
|
|
224
|
+
return assessment;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (changeType === 'added') {
|
|
228
|
+
assessment.decision = 'auto';
|
|
229
|
+
assessment.reason.push('纯新增文件');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// 2. 文件大小异常检查(变化 > 50% 需确认)
|
|
233
|
+
if (originalSize > 0 && currentSize > 0) {
|
|
234
|
+
const sizeChangeRatio = Math.abs(currentSize - originalSize) / originalSize;
|
|
235
|
+
if (sizeChangeRatio > 0.5) {
|
|
236
|
+
assessment.decision = 'confirm';
|
|
237
|
+
assessment.reason.push(`文件大小变化超过 50% (${(sizeChangeRatio * 100).toFixed(1)}%)`);
|
|
238
|
+
assessment.riskLevel = 'medium';
|
|
239
|
+
return assessment;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// 3. 敏感信息泄露扫描
|
|
244
|
+
if (containsSensitiveInfo(content)) {
|
|
245
|
+
assessment.decision = 'confirm';
|
|
246
|
+
assessment.reason.push('包含敏感字段(password/secret/key 等)');
|
|
247
|
+
assessment.riskLevel = 'high';
|
|
248
|
+
return assessment;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// 4. 格式有效性验证
|
|
252
|
+
if (content) {
|
|
253
|
+
const formatCheck = validateFormat(filePath, content);
|
|
254
|
+
if (!formatCheck.valid) {
|
|
255
|
+
assessment.decision = 'skip';
|
|
256
|
+
assessment.reason.push(formatCheck.error);
|
|
257
|
+
assessment.riskLevel = 'high';
|
|
258
|
+
return assessment;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// 5. 配置更新识别(高安全度)
|
|
263
|
+
if (changeType === 'modified' && content && isConfigUpdate(content)) {
|
|
264
|
+
assessment.decision = 'auto';
|
|
265
|
+
assessment.reason.push('配置值更新(端口、版本、超时等)');
|
|
266
|
+
assessment.riskLevel = 'low';
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// 6. 文档内容更新
|
|
270
|
+
if (changeType === 'modified' && filePath.endsWith('.md')) {
|
|
271
|
+
assessment.decision = 'auto';
|
|
272
|
+
assessment.reason.push('文档内容更新');
|
|
273
|
+
assessment.riskLevel = 'low';
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// 默认决策
|
|
277
|
+
if (assessment.decision === 'pending') {
|
|
278
|
+
if (changeType === 'modified') {
|
|
279
|
+
assessment.decision = 'auto';
|
|
280
|
+
assessment.reason.push('常规内容更新');
|
|
281
|
+
assessment.riskLevel = 'low';
|
|
282
|
+
} else {
|
|
283
|
+
assessment.decision = 'confirm';
|
|
284
|
+
assessment.reason.push('未识别的变更类型');
|
|
285
|
+
assessment.riskLevel = 'medium';
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return assessment;
|
|
290
|
+
}
|
|
291
|
+
|
|
44
292
|
/**
|
|
45
293
|
* 获取当前分支名
|
|
46
294
|
*/
|
|
@@ -56,7 +304,7 @@ function getCurrentBranch(repoDir) {
|
|
|
56
304
|
} catch (e) {
|
|
57
305
|
return 'main';
|
|
58
306
|
}
|
|
59
|
-
}
|
|
307
|
+
}
|
|
60
308
|
|
|
61
309
|
/**
|
|
62
310
|
* 执行 git add
|
|
@@ -122,14 +370,26 @@ function loadConfig(projectRoot) {
|
|
|
122
370
|
// 返回默认配置
|
|
123
371
|
return {
|
|
124
372
|
enabled: false,
|
|
125
|
-
autoPush: false,
|
|
373
|
+
autoPush: false, // 默认关闭自动推送
|
|
126
374
|
messageTemplate: 'chore: 更新环境知识 {date}',
|
|
127
|
-
paths: ['.autospec/environment/']
|
|
375
|
+
paths: ['.autospec/environment/'],
|
|
376
|
+
smartCommit: true, // 启用智能决策
|
|
377
|
+
confirmOnDelete: true,
|
|
378
|
+
confirmOnSensitive: true,
|
|
379
|
+
maxAutoSizeChange: 0.5 // 50% 大小变化阈值
|
|
128
380
|
};
|
|
129
381
|
}
|
|
130
382
|
|
|
131
383
|
try {
|
|
132
|
-
|
|
384
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
385
|
+
// 合并默认值
|
|
386
|
+
return {
|
|
387
|
+
smartCommit: true,
|
|
388
|
+
confirmOnDelete: true,
|
|
389
|
+
confirmOnSensitive: true,
|
|
390
|
+
maxAutoSizeChange: 0.5,
|
|
391
|
+
...config
|
|
392
|
+
};
|
|
133
393
|
} catch (e) {
|
|
134
394
|
logger.warn('Failed to load autocommit config', { error: e.message });
|
|
135
395
|
return { enabled: false };
|
|
@@ -139,19 +399,68 @@ function loadConfig(projectRoot) {
|
|
|
139
399
|
/**
|
|
140
400
|
* 生成提交消息
|
|
141
401
|
*/
|
|
142
|
-
function generateCommitMessage(template,
|
|
402
|
+
function generateCommitMessage(template, assessments) {
|
|
143
403
|
const date = new Date().toISOString().split('T')[0];
|
|
144
404
|
let message = template.replace('{date}', date);
|
|
145
405
|
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
406
|
+
// 统计变更类型
|
|
407
|
+
const autoFiles = assessments.filter(a => a.decision === 'auto');
|
|
408
|
+
const confirmFiles = assessments.filter(a => a.decision === 'confirm');
|
|
409
|
+
|
|
410
|
+
if (autoFiles.length > 0) {
|
|
411
|
+
const summary = autoFiles.map(a => path.basename(a.filePath)).join(', ');
|
|
412
|
+
message += `\n\n自动提交 (${autoFiles.length} 个): ${summary}`;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (confirmFiles.length > 0) {
|
|
416
|
+
const summary = confirmFiles.map(a => path.basename(a.filePath)).join(', ');
|
|
417
|
+
message += `\n\n需确认 (${confirmFiles.length} 个): ${summary}`;
|
|
150
418
|
}
|
|
151
419
|
|
|
152
420
|
return message;
|
|
153
421
|
}
|
|
154
422
|
|
|
423
|
+
/**
|
|
424
|
+
* 生成决策报告
|
|
425
|
+
*/
|
|
426
|
+
function generateDecisionReport(assessments) {
|
|
427
|
+
const auto = assessments.filter(a => a.decision === 'auto');
|
|
428
|
+
const confirm = assessments.filter(a => a.decision === 'confirm');
|
|
429
|
+
const skip = assessments.filter(a => a.decision === 'skip');
|
|
430
|
+
|
|
431
|
+
let report = '\n📊 智能提交决策报告\n';
|
|
432
|
+
report += '═'.repeat(50) + '\n';
|
|
433
|
+
|
|
434
|
+
if (auto.length > 0) {
|
|
435
|
+
report += `\n✅ 自动提交 (${auto.length} 个):\n`;
|
|
436
|
+
auto.forEach(a => {
|
|
437
|
+
report += ` • ${path.basename(a.filePath)} - ${a.reason[0]}\n`;
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
if (confirm.length > 0) {
|
|
442
|
+
report += `\n⚠️ 需人工确认 (${confirm.length} 个):\n`;
|
|
443
|
+
confirm.forEach(a => {
|
|
444
|
+
report += ` • ${path.basename(a.filePath)}\n`;
|
|
445
|
+
a.reason.forEach(r => {
|
|
446
|
+
report += ` - ${r}\n`;
|
|
447
|
+
});
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (skip.length > 0) {
|
|
452
|
+
report += `\n❌ 已跳过 (${skip.length} 个):\n`;
|
|
453
|
+
skip.forEach(a => {
|
|
454
|
+
report += ` • ${path.basename(a.filePath)} - ${a.reason[0]}\n`;
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
report += '\n' + '═'.repeat(50) + '\n';
|
|
459
|
+
report += `总计: ${assessments.length} 个文件 | 自动: ${auto.length} | 确认: ${confirm.length} | 跳过: ${skip.length}\n`;
|
|
460
|
+
|
|
461
|
+
return { report, auto, confirm, skip };
|
|
462
|
+
}
|
|
463
|
+
|
|
155
464
|
/**
|
|
156
465
|
* 处理 Stop 事件
|
|
157
466
|
*/
|
|
@@ -162,6 +471,19 @@ async function handleStop(projectRoot) {
|
|
|
162
471
|
process.exit(0);
|
|
163
472
|
}
|
|
164
473
|
|
|
474
|
+
// 检查是否有冲突
|
|
475
|
+
if (hasConflicts(projectRoot)) {
|
|
476
|
+
logger.warn('Git conflicts detected, skipping autocommit');
|
|
477
|
+
const output = {
|
|
478
|
+
hookSpecificOutput: {
|
|
479
|
+
hookEventName: 'Stop',
|
|
480
|
+
additionalContext: '[AutoSpec] 检测到 Git 冲突,跳过自动提交。请手动解决冲突后再提交。',
|
|
481
|
+
},
|
|
482
|
+
};
|
|
483
|
+
process.stdout.write(JSON.stringify(output));
|
|
484
|
+
process.exit(0);
|
|
485
|
+
}
|
|
486
|
+
|
|
165
487
|
// 加载配置
|
|
166
488
|
const config = loadConfig(projectRoot);
|
|
167
489
|
|
|
@@ -183,24 +505,43 @@ async function handleStop(projectRoot) {
|
|
|
183
505
|
const envPaths = config.paths || ['.autospec/environment/'];
|
|
184
506
|
const changedFiles = status.split('\n')
|
|
185
507
|
.filter(line => line.trim())
|
|
186
|
-
.map(line => line
|
|
187
|
-
.filter(
|
|
508
|
+
.map(line => parseGitStatusLine(line))
|
|
509
|
+
.filter(info => envPaths.some(p => info.filePath.startsWith(p)));
|
|
188
510
|
|
|
189
511
|
if (changedFiles.length === 0) {
|
|
190
512
|
logger.debug('No environment knowledge changes');
|
|
191
513
|
process.exit(0);
|
|
192
514
|
}
|
|
193
515
|
|
|
194
|
-
logger.info('Detected environment knowledge changes', { files: changedFiles });
|
|
516
|
+
logger.info('Detected environment knowledge changes', { files: changedFiles.map(f => f.filePath) });
|
|
517
|
+
|
|
518
|
+
// 智能决策评估
|
|
519
|
+
const assessments = changedFiles.map(info => assessFileRisk(projectRoot, info));
|
|
520
|
+
const { report, auto, confirm, skip } = generateDecisionReport(assessments);
|
|
521
|
+
|
|
522
|
+
logger.info(report);
|
|
523
|
+
|
|
524
|
+
// 如果没有可以自动提交的文件,直接退出
|
|
525
|
+
if (auto.length === 0) {
|
|
526
|
+
const output = {
|
|
527
|
+
hookSpecificOutput: {
|
|
528
|
+
hookEventName: 'Stop',
|
|
529
|
+
additionalContext: `[AutoSpec] 环境知识变更需要人工确认。${confirm.length} 个文件待确认,${skip.length} 个文件已跳过。`,
|
|
530
|
+
},
|
|
531
|
+
};
|
|
532
|
+
process.stdout.write(JSON.stringify(output));
|
|
533
|
+
process.exit(0);
|
|
534
|
+
}
|
|
195
535
|
|
|
196
|
-
// 执行 git add
|
|
197
|
-
const
|
|
536
|
+
// 执行 git add(只添加自动提交的文件)
|
|
537
|
+
const autoFilePaths = auto.map(a => a.filePath);
|
|
538
|
+
const addResult = gitAdd(projectRoot, autoFilePaths);
|
|
198
539
|
if (!addResult) {
|
|
199
540
|
process.exit(0);
|
|
200
541
|
}
|
|
201
542
|
|
|
202
543
|
// 生成提交消息
|
|
203
|
-
const message = generateCommitMessage(config.messageTemplate || 'chore: 更新环境知识',
|
|
544
|
+
const message = generateCommitMessage(config.messageTemplate || 'chore: 更新环境知识', assessments);
|
|
204
545
|
|
|
205
546
|
// 执行 git commit
|
|
206
547
|
const commitResult = gitCommit(projectRoot, message);
|
|
@@ -210,9 +551,10 @@ async function handleStop(projectRoot) {
|
|
|
210
551
|
|
|
211
552
|
logger.info('Committed environment knowledge changes', { message });
|
|
212
553
|
|
|
213
|
-
// 如果配置了自动 push
|
|
554
|
+
// 如果配置了自动 push(默认关闭)
|
|
555
|
+
let pushResult = false;
|
|
214
556
|
if (config.autoPush) {
|
|
215
|
-
|
|
557
|
+
pushResult = gitPush(projectRoot);
|
|
216
558
|
if (pushResult) {
|
|
217
559
|
logger.info('Pushed environment knowledge changes');
|
|
218
560
|
}
|
|
@@ -223,7 +565,7 @@ async function handleStop(projectRoot) {
|
|
|
223
565
|
const output = {
|
|
224
566
|
hookSpecificOutput: {
|
|
225
567
|
hookEventName: 'Stop',
|
|
226
|
-
additionalContext: `[AutoSpec]
|
|
568
|
+
additionalContext: `[AutoSpec] 环境知识已智能提交到 ${branch} 分支。自动: ${auto.length} 个${config.autoPush && pushResult ? '并推送' : ''},需确认: ${confirm.length} 个,跳过: ${skip.length} 个`,
|
|
227
569
|
},
|
|
228
570
|
};
|
|
229
571
|
|
|
@@ -261,4 +603,4 @@ async function main() {
|
|
|
261
603
|
}
|
|
262
604
|
}
|
|
263
605
|
|
|
264
|
-
main();
|
|
606
|
+
main();
|
|
@@ -590,12 +590,13 @@ function detectDesignDocChanges(projectRoot) {
|
|
|
590
590
|
}
|
|
591
591
|
|
|
592
592
|
/**
|
|
593
|
-
* 检测业务知识变更 -
|
|
593
|
+
* 检测业务知识变更 - 扫描业务知识目录
|
|
594
594
|
*/
|
|
595
595
|
function detectBusinessKnowledgeChanges(projectRoot) {
|
|
596
596
|
const changes = [];
|
|
597
597
|
const dirsToCheck = [
|
|
598
|
-
'knowledge/
|
|
598
|
+
'knowledge/09-templates/05-business-glossary.md',
|
|
599
|
+
'knowledge/09-templates/06-business-rules.md',
|
|
599
600
|
'docs/business'
|
|
600
601
|
];
|
|
601
602
|
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
import { createHookLogger, safeJsonParse, handleHookError, readStdin, findProjectRootAsync } from './lib/hook-logger.js';
|
|
21
21
|
import { recordHookExecution } from './lib/hook-error-recorder.js';
|
|
22
|
-
import { getState } from './lib/hook-state-manager.js';
|
|
22
|
+
import { getState, getCurrentStageSubsystems, updateState } from './lib/hook-state-manager.js';
|
|
23
23
|
import { generateEventId, getTraceId, appendTraceEvent } from './lib/trace-context.js';
|
|
24
24
|
import fs from 'fs';
|
|
25
25
|
import path from 'path';
|
|
@@ -173,7 +173,7 @@ async function main() {
|
|
|
173
173
|
const toolName = input.tool_name;
|
|
174
174
|
|
|
175
175
|
// Track Write operations for artifact generation
|
|
176
|
-
if (toolName === 'Write') {
|
|
176
|
+
if (toolName === 'Write' || toolName === 'Edit') {
|
|
177
177
|
const filePath = input.tool_input?.file_path || '';
|
|
178
178
|
|
|
179
179
|
// Find project root
|
|
@@ -185,6 +185,60 @@ async function main() {
|
|
|
185
185
|
process.exit(0);
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
// ========== 子系统代码变更追踪 ==========
|
|
189
|
+
const state = getState(projectRoot, true);
|
|
190
|
+
const subsystems = getCurrentStageSubsystems(projectRoot);
|
|
191
|
+
|
|
192
|
+
if (subsystems.length > 0 && filePath && !filePath.includes('.autospec')) {
|
|
193
|
+
// 检测文件变更属于哪个子系统
|
|
194
|
+
const relativePath = filePath.replace(projectRoot + '/', '').replace(projectRoot + '\\\\', '');
|
|
195
|
+
const matchedSubsystem = subsystems.find(sub =>
|
|
196
|
+
relativePath.startsWith(sub.path + '/') ||
|
|
197
|
+
relativePath.startsWith(sub.path + '\\') ||
|
|
198
|
+
relativePath.startsWith(sub.name + '/')
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
if (matchedSubsystem) {
|
|
202
|
+
// 更新子系统的变更计数
|
|
203
|
+
const subsystemKey = `stages.${state.currentStage}.subsystems`;
|
|
204
|
+
const stageData = state.stages[state.currentStage];
|
|
205
|
+
|
|
206
|
+
if (stageData?.subsystems) {
|
|
207
|
+
const subsystem = stageData.subsystems.find(s => s.name === matchedSubsystem.name);
|
|
208
|
+
if (subsystem) {
|
|
209
|
+
// 初始化或更新变更计数
|
|
210
|
+
if (!subsystem.changeCount) {
|
|
211
|
+
subsystem.changeCount = 0;
|
|
212
|
+
}
|
|
213
|
+
subsystem.changeCount++;
|
|
214
|
+
subsystem.lastChangeAt = new Date().toISOString();
|
|
215
|
+
|
|
216
|
+
// 记录变更文件列表
|
|
217
|
+
if (!subsystem.changedFiles) {
|
|
218
|
+
subsystem.changedFiles = [];
|
|
219
|
+
}
|
|
220
|
+
if (!subsystem.changedFiles.includes(relativePath)) {
|
|
221
|
+
subsystem.changedFiles.push(relativePath);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// 标记子系统为进行中(如果还是 pending 状态)
|
|
225
|
+
if (subsystem.status === 'pending') {
|
|
226
|
+
subsystem.status = 'in_progress';
|
|
227
|
+
subsystem.startedAt = subsystem.startedAt || new Date().toISOString();
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
updateState(projectRoot, state);
|
|
231
|
+
logger.debug('Subsystem code change tracked', {
|
|
232
|
+
subsystem: matchedSubsystem.name,
|
|
233
|
+
file: relativePath,
|
|
234
|
+
changeCount: subsystem.changeCount
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// ==========================================
|
|
241
|
+
|
|
188
242
|
// Check if this is a key artifact
|
|
189
243
|
const artifactInfo = detectArtifactType(filePath);
|
|
190
244
|
if (artifactInfo) {
|
|
@@ -222,8 +276,9 @@ async function main() {
|
|
|
222
276
|
const traceEvent = createEvent(projectRoot, 'artifact_created', {
|
|
223
277
|
stage: artifactInfo.stage,
|
|
224
278
|
tool: 'Write',
|
|
225
|
-
action:
|
|
226
|
-
data:
|
|
279
|
+
action: "create_artifact",
|
|
280
|
+
data:
|
|
281
|
+
{
|
|
227
282
|
file: filePath,
|
|
228
283
|
artifactType: artifactInfo.type,
|
|
229
284
|
// 完整内容用于深度评测(仅关键文件)
|
|
@@ -332,6 +387,56 @@ async function main() {
|
|
|
332
387
|
}
|
|
333
388
|
});
|
|
334
389
|
appendTraceEvent(projectRoot, traceEvent);
|
|
390
|
+
|
|
391
|
+
// ========== 自动创建 practice-log 条目 ==========
|
|
392
|
+
// 当阶段完成时,自动记录到 practice-log
|
|
393
|
+
if (state.completedAt && !state.stageLogged) {
|
|
394
|
+
const practiceLogDir = path.join(projectRoot, '.autospec', 'practice-log');
|
|
395
|
+
if (!fs.existsSync(practiceLogDir)) {
|
|
396
|
+
fs.mkdirSync(practiceLogDir, { recursive: true });
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const date = new Date().toISOString().split('T')[0];
|
|
400
|
+
const stageName = state.currentStage.replace('0', '').replace('-', '');
|
|
401
|
+
const logFile = path.join(practiceLogDir, `${date}-${stageName}.md`);
|
|
402
|
+
|
|
403
|
+
// 如果文件已存在,不重复创建
|
|
404
|
+
if (!fs.existsSync(logFile)) {
|
|
405
|
+
const template = `# 实践日志 - ${state.currentStage}
|
|
406
|
+
|
|
407
|
+
日期:${date}
|
|
408
|
+
阶段:${state.currentStage}
|
|
409
|
+
完成时间:${state.completedAt}
|
|
410
|
+
|
|
411
|
+
## 问题描述
|
|
412
|
+
|
|
413
|
+
<!-- 描述遇到的问题 -->
|
|
414
|
+
|
|
415
|
+
## 解决方案
|
|
416
|
+
|
|
417
|
+
<!-- 描述解决方案 -->
|
|
418
|
+
|
|
419
|
+
## 经验总结
|
|
420
|
+
|
|
421
|
+
<!-- 描述可以复用的经验 -->
|
|
422
|
+
|
|
423
|
+
## 相关文件
|
|
424
|
+
|
|
425
|
+
<!-- 列出相关文件 -->
|
|
426
|
+
|
|
427
|
+
## 标签
|
|
428
|
+
|
|
429
|
+
<!-- 添加标签,如:bugfix, optimization, pattern -->
|
|
430
|
+
`;
|
|
431
|
+
fs.writeFileSync(logFile, template, 'utf-8');
|
|
432
|
+
logger.info('Practice-log auto-created', { file: logFile });
|
|
433
|
+
|
|
434
|
+
// 标记已记录,防止重复
|
|
435
|
+
state.stageLogged = true;
|
|
436
|
+
fs.writeFileSync(statePath, JSON.stringify(state, null, 2), 'utf-8');
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
// ==============================================
|
|
335
440
|
}
|
|
336
441
|
} catch {
|
|
337
442
|
// Ignore state.json parsing errors
|