soloforge 1.0.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 +21 -0
- package/README.md +203 -0
- package/dist/adapters/claude_code/claude_md.d.ts +3 -0
- package/dist/adapters/claude_code/claude_md.d.ts.map +1 -0
- package/dist/adapters/claude_code/claude_md.js +79 -0
- package/dist/adapters/claude_code/claude_md.js.map +1 -0
- package/dist/adapters/claude_code/hooks.d.ts +3 -0
- package/dist/adapters/claude_code/hooks.d.ts.map +1 -0
- package/dist/adapters/claude_code/hooks.js +30 -0
- package/dist/adapters/claude_code/hooks.js.map +1 -0
- package/dist/adapters/claude_code/server.d.ts +10 -0
- package/dist/adapters/claude_code/server.d.ts.map +1 -0
- package/dist/adapters/claude_code/server.js +75 -0
- package/dist/adapters/claude_code/server.js.map +1 -0
- package/dist/adapters/claude_code/tools.d.ts +15 -0
- package/dist/adapters/claude_code/tools.d.ts.map +1 -0
- package/dist/adapters/claude_code/tools.js +758 -0
- package/dist/adapters/claude_code/tools.js.map +1 -0
- package/dist/adapters/trae/trae_config.d.ts +2 -0
- package/dist/adapters/trae/trae_config.d.ts.map +1 -0
- package/dist/adapters/trae/trae_config.js +22 -0
- package/dist/adapters/trae/trae_config.js.map +1 -0
- package/dist/adapters/trae/trae_rules.d.ts +3 -0
- package/dist/adapters/trae/trae_rules.d.ts.map +1 -0
- package/dist/adapters/trae/trae_rules.js +85 -0
- package/dist/adapters/trae/trae_rules.js.map +1 -0
- package/dist/bin/soloforge.d.ts +3 -0
- package/dist/bin/soloforge.d.ts.map +1 -0
- package/dist/bin/soloforge.js +353 -0
- package/dist/bin/soloforge.js.map +1 -0
- package/dist/engine/adr_recorder.d.ts +13 -0
- package/dist/engine/adr_recorder.d.ts.map +1 -0
- package/dist/engine/adr_recorder.js +132 -0
- package/dist/engine/adr_recorder.js.map +1 -0
- package/dist/engine/change_coordinator.d.ts +17 -0
- package/dist/engine/change_coordinator.d.ts.map +1 -0
- package/dist/engine/change_coordinator.js +138 -0
- package/dist/engine/change_coordinator.js.map +1 -0
- package/dist/engine/classifier.d.ts +7 -0
- package/dist/engine/classifier.d.ts.map +1 -0
- package/dist/engine/classifier.js +135 -0
- package/dist/engine/classifier.js.map +1 -0
- package/dist/engine/code_reviewer.d.ts +15 -0
- package/dist/engine/code_reviewer.d.ts.map +1 -0
- package/dist/engine/code_reviewer.js +371 -0
- package/dist/engine/code_reviewer.js.map +1 -0
- package/dist/engine/confidence_scorer.d.ts +11 -0
- package/dist/engine/confidence_scorer.d.ts.map +1 -0
- package/dist/engine/confidence_scorer.js +30 -0
- package/dist/engine/confidence_scorer.js.map +1 -0
- package/dist/engine/contract_guard.d.ts +10 -0
- package/dist/engine/contract_guard.d.ts.map +1 -0
- package/dist/engine/contract_guard.js +471 -0
- package/dist/engine/contract_guard.js.map +1 -0
- package/dist/engine/convention_detector.d.ts +7 -0
- package/dist/engine/convention_detector.d.ts.map +1 -0
- package/dist/engine/convention_detector.js +93 -0
- package/dist/engine/convention_detector.js.map +1 -0
- package/dist/engine/debt_reporter.d.ts +4 -0
- package/dist/engine/debt_reporter.d.ts.map +1 -0
- package/dist/engine/debt_reporter.js +67 -0
- package/dist/engine/debt_reporter.js.map +1 -0
- package/dist/engine/debt_tracker.d.ts +20 -0
- package/dist/engine/debt_tracker.d.ts.map +1 -0
- package/dist/engine/debt_tracker.js +152 -0
- package/dist/engine/debt_tracker.js.map +1 -0
- package/dist/engine/debugger.d.ts +3 -0
- package/dist/engine/debugger.d.ts.map +1 -0
- package/dist/engine/debugger.js +291 -0
- package/dist/engine/debugger.js.map +1 -0
- package/dist/engine/delivery.d.ts +15 -0
- package/dist/engine/delivery.d.ts.map +1 -0
- package/dist/engine/delivery.js +182 -0
- package/dist/engine/delivery.js.map +1 -0
- package/dist/engine/dependency_scanner.d.ts +13 -0
- package/dist/engine/dependency_scanner.d.ts.map +1 -0
- package/dist/engine/dependency_scanner.js +275 -0
- package/dist/engine/dependency_scanner.js.map +1 -0
- package/dist/engine/evolver.d.ts +15 -0
- package/dist/engine/evolver.d.ts.map +1 -0
- package/dist/engine/evolver.js +167 -0
- package/dist/engine/evolver.js.map +1 -0
- package/dist/engine/failure_classifier.d.ts +11 -0
- package/dist/engine/failure_classifier.d.ts.map +1 -0
- package/dist/engine/failure_classifier.js +120 -0
- package/dist/engine/failure_classifier.js.map +1 -0
- package/dist/engine/feasibility_checker.d.ts +6 -0
- package/dist/engine/feasibility_checker.d.ts.map +1 -0
- package/dist/engine/feasibility_checker.js +88 -0
- package/dist/engine/feasibility_checker.js.map +1 -0
- package/dist/engine/git_deps.d.ts +37 -0
- package/dist/engine/git_deps.d.ts.map +1 -0
- package/dist/engine/git_deps.js +3 -0
- package/dist/engine/git_deps.js.map +1 -0
- package/dist/engine/impact_analyzer.d.ts +10 -0
- package/dist/engine/impact_analyzer.d.ts.map +1 -0
- package/dist/engine/impact_analyzer.js +171 -0
- package/dist/engine/impact_analyzer.js.map +1 -0
- package/dist/engine/intent_expander.d.ts +17 -0
- package/dist/engine/intent_expander.d.ts.map +1 -0
- package/dist/engine/intent_expander.js +447 -0
- package/dist/engine/intent_expander.js.map +1 -0
- package/dist/engine/knowledge_manager.d.ts +76 -0
- package/dist/engine/knowledge_manager.d.ts.map +1 -0
- package/dist/engine/knowledge_manager.js +781 -0
- package/dist/engine/knowledge_manager.js.map +1 -0
- package/dist/engine/migration_guard.d.ts +3 -0
- package/dist/engine/migration_guard.d.ts.map +1 -0
- package/dist/engine/migration_guard.js +235 -0
- package/dist/engine/migration_guard.js.map +1 -0
- package/dist/engine/observability.d.ts +33 -0
- package/dist/engine/observability.d.ts.map +1 -0
- package/dist/engine/observability.js +312 -0
- package/dist/engine/observability.js.map +1 -0
- package/dist/engine/onboarding.d.ts +27 -0
- package/dist/engine/onboarding.d.ts.map +1 -0
- package/dist/engine/onboarding.js +362 -0
- package/dist/engine/onboarding.js.map +1 -0
- package/dist/engine/prompt_experiment.d.ts +18 -0
- package/dist/engine/prompt_experiment.d.ts.map +1 -0
- package/dist/engine/prompt_experiment.js +127 -0
- package/dist/engine/prompt_experiment.js.map +1 -0
- package/dist/engine/resilience.d.ts +20 -0
- package/dist/engine/resilience.d.ts.map +1 -0
- package/dist/engine/resilience.js +210 -0
- package/dist/engine/resilience.js.map +1 -0
- package/dist/engine/scaffolder.d.ts +9 -0
- package/dist/engine/scaffolder.d.ts.map +1 -0
- package/dist/engine/scaffolder.js +222 -0
- package/dist/engine/scaffolder.js.map +1 -0
- package/dist/engine/scope_controller.d.ts +3 -0
- package/dist/engine/scope_controller.d.ts.map +1 -0
- package/dist/engine/scope_controller.js +121 -0
- package/dist/engine/scope_controller.js.map +1 -0
- package/dist/engine/task_context.d.ts +34 -0
- package/dist/engine/task_context.d.ts.map +1 -0
- package/dist/engine/task_context.js +321 -0
- package/dist/engine/task_context.js.map +1 -0
- package/dist/engine/task_planner.d.ts +11 -0
- package/dist/engine/task_planner.d.ts.map +1 -0
- package/dist/engine/task_planner.js +267 -0
- package/dist/engine/task_planner.js.map +1 -0
- package/dist/engine/team_awareness.d.ts +12 -0
- package/dist/engine/team_awareness.d.ts.map +1 -0
- package/dist/engine/team_awareness.js +121 -0
- package/dist/engine/team_awareness.js.map +1 -0
- package/dist/engine/test_generator.d.ts +9 -0
- package/dist/engine/test_generator.d.ts.map +1 -0
- package/dist/engine/test_generator.js +241 -0
- package/dist/engine/test_generator.js.map +1 -0
- package/dist/engine/test_quality.d.ts +9 -0
- package/dist/engine/test_quality.d.ts.map +1 -0
- package/dist/engine/test_quality.js +256 -0
- package/dist/engine/test_quality.js.map +1 -0
- package/dist/engine/traceability.d.ts +3 -0
- package/dist/engine/traceability.d.ts.map +1 -0
- package/dist/engine/traceability.js +137 -0
- package/dist/engine/traceability.js.map +1 -0
- package/dist/engine/verifier.d.ts +3 -0
- package/dist/engine/verifier.d.ts.map +1 -0
- package/dist/engine/verifier.js +202 -0
- package/dist/engine/verifier.js.map +1 -0
- package/dist/engine/workspace_manager.d.ts +29 -0
- package/dist/engine/workspace_manager.d.ts.map +1 -0
- package/dist/engine/workspace_manager.js +77 -0
- package/dist/engine/workspace_manager.js.map +1 -0
- package/dist/git/operations.d.ts +57 -0
- package/dist/git/operations.d.ts.map +1 -0
- package/dist/git/operations.js +215 -0
- package/dist/git/operations.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge/conflict_detector.d.ts +6 -0
- package/dist/knowledge/conflict_detector.d.ts.map +1 -0
- package/dist/knowledge/conflict_detector.js +19 -0
- package/dist/knowledge/conflict_detector.js.map +1 -0
- package/dist/knowledge/health_checker.d.ts +10 -0
- package/dist/knowledge/health_checker.d.ts.map +1 -0
- package/dist/knowledge/health_checker.js +61 -0
- package/dist/knowledge/health_checker.js.map +1 -0
- package/dist/knowledge/index_manager.d.ts +35 -0
- package/dist/knowledge/index_manager.d.ts.map +1 -0
- package/dist/knowledge/index_manager.js +209 -0
- package/dist/knowledge/index_manager.js.map +1 -0
- package/dist/knowledge/loader.d.ts +13 -0
- package/dist/knowledge/loader.d.ts.map +1 -0
- package/dist/knowledge/loader.js +161 -0
- package/dist/knowledge/loader.js.map +1 -0
- package/dist/knowledge/writer.d.ts +15 -0
- package/dist/knowledge/writer.d.ts.map +1 -0
- package/dist/knowledge/writer.js +98 -0
- package/dist/knowledge/writer.js.map +1 -0
- package/dist/types.d.ts +724 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
- package/templates/config.yaml +53 -0
- package/templates/knowledge/acceptance_templates/Bug/345/210/206/346/236/220/346/250/241/347/211/210.md +45 -0
- package/templates/knowledge/acceptance_templates/POC/347/273/223/350/256/272/346/250/241/347/211/210.md +39 -0
- package/templates/knowledge/acceptance_templates//345/211/215/347/253/257/351/241/265/351/235/242/351/252/214/346/224/266/346/270/205/345/215/225.md +27 -0
- package/templates/knowledge/acceptance_templates//345/216/237/345/236/213/350/257/264/346/230/216/346/250/241/347/211/210.md +180 -0
- package/templates/knowledge/acceptance_templates//345/220/216/347/253/257API/351/252/214/346/224/266/346/270/205/345/215/225.md +26 -0
- package/templates/knowledge/acceptance_templates//345/256/211/345/205/250/345/256/241/350/256/241/346/250/241/347/211/210.md +51 -0
- package/templates/knowledge/acceptance_templates//346/200/247/350/203/275/345/210/206/346/236/220/346/250/241/347/211/210.md +45 -0
- package/templates/knowledge/acceptance_templates//346/216/245/345/217/243/345/257/271/346/216/245/346/226/271/346/241/210/346/250/241/347/211/210.md +45 -0
- package/templates/knowledge/acceptance_templates//346/216/245/345/217/243/350/256/276/350/256/241/346/250/241/347/211/210.md +58 -0
- package/templates/knowledge/acceptance_templates//346/225/205/351/232/234/345/244/215/347/233/230/346/250/241/347/211/210.md +53 -0
- package/templates/knowledge/acceptance_templates//346/225/260/346/215/256/345/272/223/345/217/230/346/233/264/346/226/271/346/241/210/346/250/241/347/211/210.md +45 -0
- package/templates/knowledge/acceptance_templates//346/225/260/346/215/256/345/272/223/345/217/230/346/233/264/351/252/214/346/224/266/346/270/205/345/215/225.md +24 -0
- package/templates/knowledge/acceptance_templates//346/236/266/346/236/204/350/256/276/350/256/241/346/250/241/347/211/210.md +42 -0
- package/templates/knowledge/acceptance_templates//346/265/213/350/257/225/350/256/241/345/210/222/346/250/241/347/211/210.md +39 -0
- package/templates/knowledge/acceptance_templates//350/257/246/347/273/206/350/256/276/350/256/241/346/250/241/347/211/210.md +40 -0
- package/templates/knowledge/acceptance_templates//350/277/201/347/247/273/350/257/204/344/274/260/346/250/241/347/211/210.md +42 -0
- package/templates/knowledge/acceptance_templates//351/200/232/347/224/250/350/264/250/351/207/217/351/252/214/346/224/266/346/270/205/345/215/225.md +26 -0
- package/templates/knowledge/acceptance_templates//351/207/215/346/236/204/346/226/271/346/241/210/346/250/241/347/211/210.md +47 -0
- package/templates/knowledge/acceptance_templates//351/234/200/346/261/202/345/210/206/346/236/220/346/250/241/347/211/210.md +44 -0
- package/templates/knowledge/domain//345/244/232/347/247/237/346/210/267.md +35 -0
- package/templates/knowledge/domain//345/256/241/350/256/241/346/227/245/345/277/227.md +34 -0
- package/templates/knowledge/domain//345/257/274/345/205/245/345/257/274/345/207/272/350/247/204/345/210/231.md +37 -0
- package/templates/knowledge/domain//345/267/245/344/275/234/346/265/201/345/274/225/346/223/216.md +37 -0
- package/templates/knowledge/domain//346/212/245/350/241/250/347/273/237/350/256/241.md +36 -0
- package/templates/knowledge/domain//346/224/257/344/273/230/350/247/204/345/210/231.md +38 -0
- package/templates/knowledge/domain//346/225/260/346/215/256/346/235/203/351/231/220.md +34 -0
- package/templates/knowledge/domain//351/200/232/347/224/250/346/234/272/346/242/260/346/235/241/346/254/276.md +24 -0
- package/templates/knowledge/domain//351/200/232/347/237/245/350/247/204/345/210/231.md +36 -0
- package/templates/knowledge/procedures/Figma/344/272/244/344/273/230/346/265/201/347/250/213.md +35 -0
- package/templates/knowledge/procedures/Schema/345/217/230/346/233/264/346/265/201/346/260/264/347/272/277.md +28 -0
- package/templates/knowledge/procedures//344/273/243/347/240/201/351/227/250/347/246/201/346/265/201/347/250/213.md +33 -0
- package/templates/knowledge/procedures//344/273/273/345/212/241/346/213/206/350/247/243/346/265/201/347/250/213.md +31 -0
- package/templates/knowledge/procedures//345/212/237/350/203/275/345/274/200/345/217/221/346/265/201/347/250/213.md +37 -0
- package/templates/knowledge/procedures//345/256/211/345/205/250/345/212/240/345/233/272/346/265/201/346/260/264/347/272/277.md +43 -0
- package/templates/knowledge/procedures//346/200/247/350/203/275/346/265/201/346/260/264/347/272/277.md +27 -0
- package/templates/knowledge/procedures//346/216/245/345/217/243/351/233/206/346/210/220/346/265/201/346/260/264/347/272/277.md +46 -0
- package/templates/knowledge/procedures//346/225/260/346/215/256/345/272/223/350/277/201/347/247/273/346/265/201/347/250/213.md +38 -0
- package/templates/knowledge/procedures//346/236/266/346/236/204/350/256/276/350/256/241/346/265/201/347/250/213.md +30 -0
- package/templates/knowledge/procedures//346/246/202/345/277/265/351/252/214/350/257/201/346/265/201/346/260/264/347/272/277.md +24 -0
- package/templates/knowledge/procedures//347/237/245/350/257/206/347/273/264/346/212/244/346/265/201/346/260/264/347/272/277.md +40 -0
- package/templates/knowledge/procedures//347/264/247/346/200/245/344/277/256/345/244/215/346/265/201/346/260/264/347/272/277.md +45 -0
- package/templates/knowledge/procedures//347/264/247/346/200/245/344/277/256/345/244/215/346/265/201/347/250/213.md +33 -0
- package/templates/knowledge/procedures//347/274/272/351/231/267/344/277/256/345/244/215/346/265/201/346/260/264/347/272/277.md +28 -0
- package/templates/knowledge/procedures//350/257/246/347/273/206/350/256/276/350/256/241/346/265/201/347/250/213.md +29 -0
- package/templates/knowledge/procedures//350/260/203/350/257/225/346/216/222/346/237/245/346/265/201/347/250/213.md +43 -0
- package/templates/knowledge/procedures//350/277/201/347/247/273/346/265/201/346/260/264/347/272/277.md +27 -0
- package/templates/knowledge/procedures//351/203/250/347/275/262/345/217/221/345/270/203/346/265/201/347/250/213.md +45 -0
- package/templates/knowledge/procedures//351/207/215/346/236/204/346/265/201/346/260/264/347/272/277.md +27 -0
- package/templates/knowledge/procedures//351/233/206/346/210/220/351/252/214/350/257/201/346/265/201/347/250/213.md +36 -0
- package/templates/knowledge/procedures//351/234/200/346/261/202/346/276/204/346/270/205/346/265/201/347/250/213.md +32 -0
- package/templates/knowledge/procedures//351/252/214/346/224/266/346/265/213/350/257/225/350/247/204/345/210/222.md +40 -0
- package/templates/knowledge/procedures//351/252/214/350/257/201/350/256/241/345/210/222/346/265/201/347/250/213.md +32 -0
- package/templates/knowledge/product_profiles/b2b-internal.yaml +35 -0
- package/templates/knowledge/product_profiles/b2c.yaml +37 -0
- package/templates/knowledge/product_profiles/saas.yaml +35 -0
- package/templates/knowledge/review_rules//345/256/211/345/205/250/345/256/241/346/237/245/350/247/204/345/210/231.md +79 -0
- package/templates/knowledge/review_rules//345/271/266/345/217/221/345/256/241/346/237/245/350/247/204/345/210/231.md +67 -0
- package/templates/knowledge/review_rules//346/200/247/350/203/275/345/256/241/346/237/245/350/247/204/345/210/231.md +61 -0
- package/templates/knowledge/review_rules//346/216/245/345/217/243/345/245/221/347/272/246/345/256/241/346/237/245/350/247/204/345/210/231.md +67 -0
- package/templates/knowledge/review_rules//346/236/266/346/236/204/345/256/241/346/237/245/350/247/204/345/210/231.md +62 -0
- package/templates/knowledge/review_rules//350/264/250/351/207/217/345/256/241/346/237/245/350/247/204/345/210/231.md +80 -0
- package/templates/patterns/API/350/256/276/350/256/241/350/247/204/350/214/203.md +31 -0
- package/templates/patterns/Docker/351/203/250/347/275/262/350/247/204/350/214/203.md +31 -0
- package/templates/patterns/Git/346/223/215/344/275/234/350/247/204/350/214/203.md +31 -0
- package/templates/patterns/N/345/212/2401/346/237/245/350/257/242/350/247/204/350/214/203.md +32 -0
- package/templates/patterns/React/345/210/227/350/241/250/350/241/250/346/240/274/350/247/204/350/214/203.md +29 -0
- package/templates/patterns/React/346/216/245/345/217/243/351/233/206/346/210/220/350/247/204/350/214/203.md +28 -0
- package/templates/patterns/React/347/212/266/346/200/201/347/256/241/347/220/206/350/247/204/350/214/203.md +28 -0
- package/templates/patterns/React/347/273/204/344/273/266/350/247/204/350/214/203.md +28 -0
- package/templates/patterns/React/350/241/250/345/215/225/350/247/204/350/214/203.md +29 -0
- package/templates/patterns/React/350/267/257/347/224/261/350/247/204/350/214/203.md +29 -0
- package/templates/patterns/Schema/345/205/274/345/256/271/350/247/204/350/214/203.md +28 -0
- package/templates/patterns/Vue/347/212/266/346/200/201/347/256/241/347/220/206/350/247/204/350/214/203.md +28 -0
- package/templates/patterns/Vue/347/273/204/344/273/266/350/247/204/350/214/203.md +28 -0
- package/templates/patterns/Vue/350/267/257/347/224/261/350/247/204/350/214/203.md +29 -0
- package/templates/patterns//344/272/213/344/273/266/351/251/261/345/212/250/350/247/204/350/214/203.md +32 -0
- package/templates/patterns//344/272/213/345/212/241/346/250/241/345/274/217/350/247/204/350/214/203.md +28 -0
- package/templates/patterns//344/274/230/351/233/205/345/201/234/346/234/272/350/247/204/350/214/203.md +30 -0
- package/templates/patterns//345/205/250/346/240/210/346/265/201/347/250/213/344/277/256/345/244/215.md +31 -0
- package/templates/patterns//345/210/206/351/241/265/346/237/245/350/257/242/350/247/204/350/214/203.md +27 -0
- package/templates/patterns//345/211/215/347/253/257/346/200/247/350/203/275/350/247/204/350/214/203.md +33 -0
- package/templates/patterns//345/221/275/345/220/215/350/247/204/350/214/203.md +32 -0
- package/templates/patterns//345/233/275/351/231/205/345/214/226/350/247/204/350/214/203.md +31 -0
- package/templates/patterns//345/242/236/345/210/240/346/224/271/346/237/245/350/247/204/350/214/203.md +31 -0
- package/templates/patterns//345/244/226/351/203/250/344/276/235/350/265/226/350/247/204/350/214/203.md +29 -0
- package/templates/patterns//345/245/221/347/272/246/345/205/274/345/256/271/350/247/204/350/214/203.md +28 -0
- package/templates/patterns//345/256/232/346/227/266/344/273/273/345/212/241/350/247/204/350/214/203.md +25 -0
- package/templates/patterns//345/256/236/346/227/266/346/216/250/351/200/201/350/247/204/350/214/203.md +33 -0
- package/templates/patterns//345/267/245/347/250/213/347/272/252/345/276/213.md +39 -0
- package/templates/patterns//345/271/266/345/217/221/346/216/247/345/210/266/350/247/204/350/214/203.md +34 -0
- package/templates/patterns//345/274/202/346/255/245/345/257/274/345/207/272/350/247/204/350/214/203.md +27 -0
- package/templates/patterns//346/216/245/345/217/243/345/245/221/347/272/246/350/247/204/350/214/203.md +30 -0
- package/templates/patterns//346/220/234/347/264/242/346/250/241/345/274/217/350/247/204/350/214/203.md +32 -0
- package/templates/patterns//346/225/260/346/215/256/351/232/220/347/247/201/350/247/204/350/214/203.md +31 -0
- package/templates/patterns//346/226/207/344/273/266/344/270/212/344/274/240/350/247/204/350/214/203.md +31 -0
- package/templates/patterns//346/227/240/351/232/234/347/242/215/350/247/204/350/214/203.md +33 -0
- package/templates/patterns//346/227/245/345/277/227/350/247/204/350/214/203.md +31 -0
- package/templates/patterns//346/235/203/351/231/220/350/256/244/350/257/201/350/247/204/350/214/203.md +35 -0
- package/templates/patterns//346/236/266/346/236/204/347/272/242/347/272/277.md +30 -0
- package/templates/patterns//346/265/213/350/257/225/350/264/250/351/207/217/350/247/204/350/214/203.md +30 -0
- package/templates/patterns//347/206/224/346/226/255/351/231/215/347/272/247/350/247/204/350/214/203.md +33 -0
- package/templates/patterns//347/212/266/346/200/201/346/265/201/350/275/254/350/247/204/350/214/203.md +29 -0
- package/templates/patterns//347/272/246/346/235/237/345/256/236/347/216/260/350/247/204/350/214/203.md +32 -0
- package/templates/patterns//347/274/223/345/255/230/347/255/226/347/225/245/350/247/204/350/214/203.md +31 -0
- package/templates/patterns//347/274/226/347/240/201/350/264/250/351/207/217/350/247/204/350/214/203.md +31 -0
- package/templates/patterns//347/274/272/351/231/267/347/256/241/347/220/206/350/247/204/350/214/203.md +30 -0
- package/templates/patterns//350/260/203/350/257/225/346/226/271/346/263/225/350/256/272.md +28 -0
- package/templates/patterns//350/276/223/345/205/245/346/240/241/351/252/214/350/247/204/350/214/203.md +30 -0
- package/templates/patterns//351/224/231/350/257/257/345/244/204/347/220/206/350/247/204/350/214/203.md +32 -0
- package/templates/patterns//351/224/231/350/257/257/350/276/271/347/225/214/350/247/204/350/214/203.md +24 -0
- package/templates/patterns//351/242/206/345/237/237/351/251/261/345/212/250/350/256/276/350/256/241/350/247/204/350/214/203.md +29 -0
- package/templates/scaffolds/react/Form.tsx.hbs +16 -0
- package/templates/scaffolds/react/List.tsx.hbs +28 -0
- package/templates/scaffolds/react/Page.test.tsx.hbs +10 -0
- package/templates/scaffolds/react/Page.tsx.hbs +14 -0
- package/templates/scaffolds/react/README.md.hbs +44 -0
- package/templates/scaffolds/react/service.ts.hbs +37 -0
- package/templates/scaffolds/react/types.ts.hbs +6 -0
- package/templates/scaffolds/react/use{{ModuleName}}.ts.hbs +88 -0
- package/templates/scaffolds/spring-boot/ApiContract.md.hbs +110 -0
- package/templates/scaffolds/spring-boot/Controller.java.hbs +43 -0
- package/templates/scaffolds/spring-boot/DTO.java.hbs +9 -0
- package/templates/scaffolds/spring-boot/Entity.java.hbs +12 -0
- package/templates/scaffolds/spring-boot/ErrorCode.java.hbs +28 -0
- package/templates/scaffolds/spring-boot/Mapper.java.hbs +9 -0
- package/templates/scaffolds/spring-boot/PageResponse.java.hbs +29 -0
- package/templates/scaffolds/spring-boot/Service.java.hbs +12 -0
- package/templates/scaffolds/spring-boot/ServiceImpl.java.hbs +48 -0
- package/templates/scaffolds/spring-boot/ServiceTest.java.hbs +22 -0
|
@@ -0,0 +1,781 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import fss from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import matter from "gray-matter";
|
|
5
|
+
export async function auditKnowledge(knowledgeIndex, config) {
|
|
6
|
+
const { global: globalEntries, project: projectEntries } = knowledgeIndex.getAllEntries();
|
|
7
|
+
const all = [...globalEntries, ...projectEntries];
|
|
8
|
+
const findings = [];
|
|
9
|
+
const now = Date.now();
|
|
10
|
+
let findingId = 0;
|
|
11
|
+
// 1. Stale entries: last_used_at > 90 days or usage_count === 0
|
|
12
|
+
for (const entry of all) {
|
|
13
|
+
if (entry.status === "deprecated")
|
|
14
|
+
continue;
|
|
15
|
+
if (entry.usage_count === 0) {
|
|
16
|
+
findings.push({
|
|
17
|
+
id: `AUD-${String(++findingId).padStart(3, "0")}`,
|
|
18
|
+
severity: "info",
|
|
19
|
+
category: "stale",
|
|
20
|
+
entry_name: entry.name,
|
|
21
|
+
message: `从未被匹配使用: ${entry.name}`,
|
|
22
|
+
suggestion: "检查 when 触发词是否覆盖实际场景,或标记为 deprecated",
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
else if (entry.last_used_at) {
|
|
26
|
+
const daysSinceUse = (now - new Date(entry.last_used_at).getTime()) / (1000 * 60 * 60 * 24);
|
|
27
|
+
if (daysSinceUse > 90) {
|
|
28
|
+
findings.push({
|
|
29
|
+
id: `AUD-${String(++findingId).padStart(3, "0")}`,
|
|
30
|
+
severity: "warning",
|
|
31
|
+
category: "stale",
|
|
32
|
+
entry_name: entry.name,
|
|
33
|
+
message: `超过 ${Math.floor(daysSinceUse)} 天未被使用: ${entry.name}`,
|
|
34
|
+
suggestion: "评估是否仍需要,考虑更新触发词或标记为 deprecated",
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// 2. Duplicate: similar when triggers
|
|
40
|
+
for (let i = 0; i < all.length; i++) {
|
|
41
|
+
for (let j = i + 1; j < all.length; j++) {
|
|
42
|
+
if (all[i].type !== all[j].type)
|
|
43
|
+
continue;
|
|
44
|
+
const overlap = keywordOverlap(all[i].when, all[j].when);
|
|
45
|
+
if (overlap >= 0.6) {
|
|
46
|
+
findings.push({
|
|
47
|
+
id: `AUD-${String(++findingId).padStart(3, "0")}`,
|
|
48
|
+
severity: "info",
|
|
49
|
+
category: "duplicate",
|
|
50
|
+
entry_name: `${all[i].name} / ${all[j].name}`,
|
|
51
|
+
message: `触发词高度重叠 (${Math.round(overlap * 100)}%): "${all[i].name}" 和 "${all[j].name}"`,
|
|
52
|
+
suggestion: "考虑合并或区分触发词",
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// 3. Format: missing required frontmatter fields + schema validation
|
|
58
|
+
for (const entry of all) {
|
|
59
|
+
if (entry.status === "deprecated")
|
|
60
|
+
continue;
|
|
61
|
+
const issues = [];
|
|
62
|
+
if (!entry.when || entry.when.trim().length === 0)
|
|
63
|
+
issues.push("when");
|
|
64
|
+
if (!entry.scope || entry.scope.length === 0)
|
|
65
|
+
issues.push("scope");
|
|
66
|
+
if (!entry.products || entry.products.length === 0)
|
|
67
|
+
issues.push("products");
|
|
68
|
+
if (issues.length > 0) {
|
|
69
|
+
findings.push({
|
|
70
|
+
id: `AUD-${String(++findingId).padStart(3, "0")}`,
|
|
71
|
+
severity: "warning",
|
|
72
|
+
category: "format",
|
|
73
|
+
entry_name: entry.name,
|
|
74
|
+
message: `缺少必需字段: ${issues.join(", ")}`,
|
|
75
|
+
suggestion: `补充 ${issues.join("、")} 字段`,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
// 3b. Schema validation: read raw file for deeper checks
|
|
79
|
+
const schemaIssues = await validateFormatSchema(entry);
|
|
80
|
+
for (const issue of schemaIssues) {
|
|
81
|
+
findings.push({
|
|
82
|
+
id: `AUD-${String(++findingId).padStart(3, "0")}`,
|
|
83
|
+
severity: "info",
|
|
84
|
+
category: "format",
|
|
85
|
+
entry_name: entry.name,
|
|
86
|
+
message: issue.message,
|
|
87
|
+
suggestion: issue.suggestion,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// 4. Coverage: check knowledge types have entries
|
|
92
|
+
const requiredTypes = ["pattern", "procedure", "domain", "review_rule"];
|
|
93
|
+
for (const type of requiredTypes) {
|
|
94
|
+
const count = all.filter((e) => e.type === type && e.status !== "deprecated").length;
|
|
95
|
+
if (count === 0) {
|
|
96
|
+
findings.push({
|
|
97
|
+
id: `AUD-${String(++findingId).padStart(3, "0")}`,
|
|
98
|
+
severity: "warning",
|
|
99
|
+
category: "coverage",
|
|
100
|
+
entry_name: `type=${type}`,
|
|
101
|
+
message: `缺少 ${type} 类型的知识条目`,
|
|
102
|
+
suggestion: `新增至少一个 ${type} 条目`,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// 5. Completeness: check rule/AC counts against type thresholds
|
|
107
|
+
for (const entry of all) {
|
|
108
|
+
if (entry.status === "deprecated")
|
|
109
|
+
continue;
|
|
110
|
+
if (!entry.file_path || !fss.existsSync(entry.file_path))
|
|
111
|
+
continue;
|
|
112
|
+
const thresholds = COMPLETENESS_THRESHOLDS[entry.type];
|
|
113
|
+
if (!thresholds)
|
|
114
|
+
continue;
|
|
115
|
+
let raw;
|
|
116
|
+
try {
|
|
117
|
+
raw = await fs.readFile(entry.file_path, "utf-8");
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const { content: body } = matter(raw);
|
|
123
|
+
for (const check of thresholds) {
|
|
124
|
+
const count = countPattern(body, check.pattern);
|
|
125
|
+
if (count < check.minimum) {
|
|
126
|
+
findings.push({
|
|
127
|
+
id: `AUD-${String(++findingId).padStart(3, "0")}`,
|
|
128
|
+
severity: "info",
|
|
129
|
+
category: "completeness",
|
|
130
|
+
entry_name: entry.name,
|
|
131
|
+
message: `${entry.type} 条目"${entry.name}"的 ${check.field} 不足:实际 ${count} 条,要求 ≥ ${check.minimum} 条`,
|
|
132
|
+
suggestion: `运行 sf_knowledge_update 补充 ${check.field},或调用 sf_knowledge_add 的 auto_enrich 机制自动探索行业最佳实践`,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const summary = {
|
|
138
|
+
stale: findings.filter((f) => f.category === "stale").length,
|
|
139
|
+
duplicate: findings.filter((f) => f.category === "duplicate").length,
|
|
140
|
+
format: findings.filter((f) => f.category === "format").length,
|
|
141
|
+
coverage: findings.filter((f) => f.category === "coverage").length,
|
|
142
|
+
completeness: findings.filter((f) => f.category === "completeness").length,
|
|
143
|
+
design_drift: 0,
|
|
144
|
+
};
|
|
145
|
+
return {
|
|
146
|
+
total_entries: all.filter((e) => e.status !== "deprecated").length,
|
|
147
|
+
findings,
|
|
148
|
+
summary,
|
|
149
|
+
audited_at: new Date().toISOString(),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
export async function addKnowledge(input, config) {
|
|
153
|
+
const knowledgeDir = getProjectKnowledgeDir(config);
|
|
154
|
+
const fileName = `${input.title}.md`;
|
|
155
|
+
// Determine save location
|
|
156
|
+
const typeDir = getTypeDirectory(input.type);
|
|
157
|
+
const draftsDir = path.join(knowledgeDir, "drafts");
|
|
158
|
+
const targetDir = input.save_to_drafts !== false
|
|
159
|
+
? draftsDir
|
|
160
|
+
: path.join(knowledgeDir, typeDir);
|
|
161
|
+
// Ensure directory exists
|
|
162
|
+
await fs.mkdir(targetDir, { recursive: true });
|
|
163
|
+
const filePath = path.join(targetDir, fileName);
|
|
164
|
+
// Check if file already exists
|
|
165
|
+
if (fss.existsSync(filePath)) {
|
|
166
|
+
return {
|
|
167
|
+
success: false,
|
|
168
|
+
file_path: filePath,
|
|
169
|
+
is_draft: input.save_to_drafts !== false,
|
|
170
|
+
message: `文件已存在: ${filePath},请使用 sf_knowledge_update 更新`,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
// Generate content
|
|
174
|
+
const content = generateKnowledgeContent(input);
|
|
175
|
+
await fs.writeFile(filePath, content, "utf-8");
|
|
176
|
+
const enrichment_guide = input.auto_enrich !== false
|
|
177
|
+
? buildEnrichmentGuide(input)
|
|
178
|
+
: undefined;
|
|
179
|
+
return {
|
|
180
|
+
success: true,
|
|
181
|
+
file_path: filePath,
|
|
182
|
+
is_draft: input.save_to_drafts !== false,
|
|
183
|
+
message: input.save_to_drafts !== false
|
|
184
|
+
? `知识条目草稿已保存到: ${filePath}\n人工 review 后可移至正式目录: ${path.join(knowledgeDir, typeDir, fileName)}`
|
|
185
|
+
: `知识条目已保存到: ${filePath}`,
|
|
186
|
+
enrichment_guide,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
export async function updateKnowledge(input, knowledgeIndex, config) {
|
|
190
|
+
const entry = knowledgeIndex.getEntry(input.entry_name)
|
|
191
|
+
?? knowledgeIndex.getAllEntries().global.find((e) => e.name === input.entry_name)
|
|
192
|
+
?? knowledgeIndex.getAllEntries().project.find((e) => e.name === input.entry_name);
|
|
193
|
+
if (!entry) {
|
|
194
|
+
return {
|
|
195
|
+
success: false,
|
|
196
|
+
file_path: "",
|
|
197
|
+
backup_path: "",
|
|
198
|
+
message: `未找到知识条目: ${input.entry_name}`,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const filePath = entry.file_path;
|
|
202
|
+
if (!fss.existsSync(filePath)) {
|
|
203
|
+
return {
|
|
204
|
+
success: false,
|
|
205
|
+
file_path: filePath,
|
|
206
|
+
backup_path: "",
|
|
207
|
+
message: `文件不存在: ${filePath}`,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
// Read and parse
|
|
211
|
+
const raw = await fs.readFile(filePath, "utf-8");
|
|
212
|
+
const { data: frontmatter, content: body } = matter(raw);
|
|
213
|
+
// Create backup
|
|
214
|
+
const backupDir = path.join(path.dirname(filePath), ".backups");
|
|
215
|
+
await fs.mkdir(backupDir, { recursive: true });
|
|
216
|
+
const backupPath = path.join(backupDir, `${entry.name}-${Date.now()}.md`);
|
|
217
|
+
await fs.writeFile(backupPath, raw, "utf-8");
|
|
218
|
+
// Apply updates
|
|
219
|
+
let updated = false;
|
|
220
|
+
if (input.updates.when_triggers) {
|
|
221
|
+
frontmatter.when = input.updates.when_triggers;
|
|
222
|
+
updated = true;
|
|
223
|
+
}
|
|
224
|
+
if (input.updates.status) {
|
|
225
|
+
frontmatter.status = input.updates.status;
|
|
226
|
+
updated = true;
|
|
227
|
+
}
|
|
228
|
+
let newBody = body;
|
|
229
|
+
if (input.updates.add_decision_rules?.length) {
|
|
230
|
+
const rulesSection = input.updates.add_decision_rules
|
|
231
|
+
.map((r) => `- ${r}`)
|
|
232
|
+
.join("\n");
|
|
233
|
+
if (newBody.includes("## 决策规则")) {
|
|
234
|
+
newBody = newBody.replace(/## 决策规则\n/, `## 决策规则\n${rulesSection}\n`);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
newBody += `\n\n## 决策规则\n${rulesSection}\n`;
|
|
238
|
+
}
|
|
239
|
+
updated = true;
|
|
240
|
+
}
|
|
241
|
+
if (input.updates.add_acceptance_criteria?.length) {
|
|
242
|
+
const acSection = input.updates.add_acceptance_criteria
|
|
243
|
+
.map((ac, i) => `- [AC-${String(i + 1).padStart(2, "0")}] ${ac}`)
|
|
244
|
+
.join("\n");
|
|
245
|
+
if (newBody.includes("## 验收项")) {
|
|
246
|
+
newBody = newBody.replace(/## 验收项\n/, `## 验收项\n${acSection}\n`);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
newBody += `\n\n## 验收项\n${acSection}\n`;
|
|
250
|
+
}
|
|
251
|
+
updated = true;
|
|
252
|
+
}
|
|
253
|
+
if (!updated) {
|
|
254
|
+
return {
|
|
255
|
+
success: false,
|
|
256
|
+
file_path: filePath,
|
|
257
|
+
backup_path: backupPath,
|
|
258
|
+
message: "未提供任何更新内容",
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
// Write updated file
|
|
262
|
+
const output = matter.stringify(newBody, frontmatter);
|
|
263
|
+
await fs.writeFile(filePath, output, "utf-8");
|
|
264
|
+
return {
|
|
265
|
+
success: true,
|
|
266
|
+
file_path: filePath,
|
|
267
|
+
backup_path: backupPath,
|
|
268
|
+
message: `知识条目已更新: ${filePath}\n备份: ${backupPath}`,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
// ── Format Schema ──
|
|
272
|
+
const CANONICAL_FM_ORDER = ["name", "type", "when", "scope", "products"];
|
|
273
|
+
const FORMAT_SCHEMA = {
|
|
274
|
+
pattern: {
|
|
275
|
+
required_headings: ["## 决策规则", "## 验收项"],
|
|
276
|
+
},
|
|
277
|
+
domain: {
|
|
278
|
+
required_headings: ["## 业务规则", "## 约束条件", "## 例外情况", "## 关联模式"],
|
|
279
|
+
},
|
|
280
|
+
procedure: {
|
|
281
|
+
required_headings: ["## 适用场景", "## 步骤", "## 检查点", "## 注意事项"],
|
|
282
|
+
},
|
|
283
|
+
pipeline_procedure: {
|
|
284
|
+
required_headings: [],
|
|
285
|
+
partial_match_headings: ["### 第"],
|
|
286
|
+
},
|
|
287
|
+
review_rule: {
|
|
288
|
+
required_headings: [],
|
|
289
|
+
partial_match_headings: ["pattern:", "severity:", "description:"],
|
|
290
|
+
},
|
|
291
|
+
acceptance_template: {
|
|
292
|
+
required_headings: [],
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
const COMPLETENESS_THRESHOLDS = {
|
|
296
|
+
pattern: [
|
|
297
|
+
{ field: "决策规则", pattern: /^- /gm, minimum: 5 },
|
|
298
|
+
{ field: "验收项", pattern: /^- \[AC-/gm, minimum: 3 },
|
|
299
|
+
],
|
|
300
|
+
domain: [
|
|
301
|
+
{ field: "业务规则", pattern: /^(?:- |\d+\.)/gm, minimum: 6 },
|
|
302
|
+
],
|
|
303
|
+
procedure: [
|
|
304
|
+
{ field: "步骤", pattern: /^\d+\.\s/gm, minimum: 5 },
|
|
305
|
+
{ field: "检查点", pattern: /^- \[ \]/gm, minimum: 3 },
|
|
306
|
+
],
|
|
307
|
+
pipeline_procedure: [
|
|
308
|
+
{ field: "阶段", pattern: /^### 第\d+步/gm, minimum: 3 },
|
|
309
|
+
],
|
|
310
|
+
review_rule: [
|
|
311
|
+
{ field: "规则", pattern: /^## [A-Z]+-\d+/gm, minimum: 5 },
|
|
312
|
+
],
|
|
313
|
+
};
|
|
314
|
+
function countPattern(body, pattern) {
|
|
315
|
+
return (body.match(pattern) ?? []).length;
|
|
316
|
+
}
|
|
317
|
+
async function validateFormatSchema(entry) {
|
|
318
|
+
const results = [];
|
|
319
|
+
if (!entry.file_path || !fss.existsSync(entry.file_path))
|
|
320
|
+
return results;
|
|
321
|
+
let raw;
|
|
322
|
+
try {
|
|
323
|
+
raw = await fs.readFile(entry.file_path, "utf-8");
|
|
324
|
+
}
|
|
325
|
+
catch {
|
|
326
|
+
return results;
|
|
327
|
+
}
|
|
328
|
+
const { data: fm, content: body } = matter(raw);
|
|
329
|
+
// Check frontmatter field order
|
|
330
|
+
const fmKeys = Object.keys(fm);
|
|
331
|
+
const orderIssues = [];
|
|
332
|
+
for (let i = 0; i < CANONICAL_FM_ORDER.length; i++) {
|
|
333
|
+
const expected = CANONICAL_FM_ORDER[i];
|
|
334
|
+
if (i < fmKeys.length && fmKeys[i] !== expected) {
|
|
335
|
+
orderIssues.push(`期望第 ${i + 1} 个字段为 ${expected},实际为 ${fmKeys[i]}`);
|
|
336
|
+
break;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (orderIssues.length > 0) {
|
|
340
|
+
results.push({
|
|
341
|
+
message: `frontmatter 字段顺序不规范: ${orderIssues[0]}`,
|
|
342
|
+
suggestion: `标准顺序: ${CANONICAL_FM_ORDER.join(" → ")}`,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
// Check when style: first comma-separated segment should be ≤ 10 Chinese chars
|
|
346
|
+
const whenStr = fm.when ?? "";
|
|
347
|
+
const firstSegment = whenStr.split(/[,\s,]/)[0] ?? "";
|
|
348
|
+
const chineseCharCount = (firstSegment.match(/[一-鿿]/g) ?? []).length;
|
|
349
|
+
if (chineseCharCount > 10 && firstSegment.length > 12) {
|
|
350
|
+
results.push({
|
|
351
|
+
message: `when 字段首个触发词过长(${chineseCharCount} 个中文字符),疑似描述性短语: "${firstSegment}"`,
|
|
352
|
+
suggestion: "when 应为纯关键词逗号分隔,如: 数据导出, CSV, Excel, 批量导出",
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
// Check body headings
|
|
356
|
+
const schema = FORMAT_SCHEMA[entry.type];
|
|
357
|
+
if (schema) {
|
|
358
|
+
for (const heading of schema.required_headings) {
|
|
359
|
+
if (!body.includes(heading)) {
|
|
360
|
+
results.push({
|
|
361
|
+
message: `body 缺少必需标题: ${heading}(type=${entry.type})`,
|
|
362
|
+
suggestion: `按格式规约补充 ${heading} 部分`,
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
if (schema.partial_match_headings) {
|
|
367
|
+
for (const partial of schema.partial_match_headings) {
|
|
368
|
+
if (!body.includes(partial)) {
|
|
369
|
+
results.push({
|
|
370
|
+
message: `body 缺少必需内容: "${partial}"(type=${entry.type})`,
|
|
371
|
+
suggestion: `按格式规约补充包含 "${partial}" 的内容`,
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return results;
|
|
378
|
+
}
|
|
379
|
+
// ── Helpers ──
|
|
380
|
+
function keywordOverlap(a, b) {
|
|
381
|
+
const wordsA = new Set(a.toLowerCase().split(/[,\s,]+/).filter(Boolean));
|
|
382
|
+
const wordsB = new Set(b.toLowerCase().split(/[,\s,]+/).filter(Boolean));
|
|
383
|
+
if (wordsA.size === 0 || wordsB.size === 0)
|
|
384
|
+
return 0;
|
|
385
|
+
let overlap = 0;
|
|
386
|
+
for (const w of wordsA) {
|
|
387
|
+
if (wordsB.has(w))
|
|
388
|
+
overlap++;
|
|
389
|
+
}
|
|
390
|
+
return overlap / Math.min(wordsA.size, wordsB.size);
|
|
391
|
+
}
|
|
392
|
+
function getTypeDirectory(type) {
|
|
393
|
+
const map = {
|
|
394
|
+
pattern: "patterns",
|
|
395
|
+
procedure: "procedures",
|
|
396
|
+
pipeline_procedure: "procedures",
|
|
397
|
+
domain: "domain",
|
|
398
|
+
acceptance_template: "acceptance_templates",
|
|
399
|
+
review_rule: "review_rules",
|
|
400
|
+
};
|
|
401
|
+
return map[type] ?? "procedures";
|
|
402
|
+
}
|
|
403
|
+
function generateFrontmatter(input) {
|
|
404
|
+
return `---
|
|
405
|
+
name: ${input.title}
|
|
406
|
+
type: ${input.type}
|
|
407
|
+
when: "${input.when_triggers}"
|
|
408
|
+
scope: [${input.scope.join(", ")}]
|
|
409
|
+
products: ["*"]
|
|
410
|
+
---`;
|
|
411
|
+
}
|
|
412
|
+
function generateKnowledgeContent(input) {
|
|
413
|
+
const fm = generateFrontmatter(input);
|
|
414
|
+
const generators = {
|
|
415
|
+
pattern: () => generatePatternBody(input),
|
|
416
|
+
domain: () => generateDomainBody(input),
|
|
417
|
+
procedure: () => generateProcedureBody(input),
|
|
418
|
+
pipeline_procedure: () => generatePipelineBody(input),
|
|
419
|
+
review_rule: () => generateReviewRuleBody(input),
|
|
420
|
+
acceptance_template: () => generateAcceptanceBody(input),
|
|
421
|
+
};
|
|
422
|
+
const gen = generators[input.type] ?? generators.pattern;
|
|
423
|
+
return `${fm}\n\n${gen()}\n`;
|
|
424
|
+
}
|
|
425
|
+
function generatePatternBody(input) {
|
|
426
|
+
const rules = input.decision_rules
|
|
427
|
+
? input.decision_rules.split("\n").filter(Boolean).map((r) => `- ${r}`).join("\n")
|
|
428
|
+
: "- (待补充决策规则)";
|
|
429
|
+
return `## 决策规则
|
|
430
|
+
${rules}
|
|
431
|
+
|
|
432
|
+
## 验收项
|
|
433
|
+
- [AC-01] (待补充验收标准)`;
|
|
434
|
+
}
|
|
435
|
+
function generateDomainBody(input) {
|
|
436
|
+
const rules = input.decision_rules
|
|
437
|
+
? input.decision_rules.split("\n").filter(Boolean).map((r) => `${r}`).join("\n\n")
|
|
438
|
+
: "(待补充业务规则)";
|
|
439
|
+
return `## 业务规则
|
|
440
|
+
${rules}
|
|
441
|
+
|
|
442
|
+
## 约束条件
|
|
443
|
+
- (待补充约束条件)
|
|
444
|
+
|
|
445
|
+
## 例外情况
|
|
446
|
+
- (待补充例外情况)
|
|
447
|
+
|
|
448
|
+
## 关联模式
|
|
449
|
+
- (待补充关联模式)`;
|
|
450
|
+
}
|
|
451
|
+
function generateProcedureBody(input) {
|
|
452
|
+
return `## 适用场景
|
|
453
|
+
(待补充适用场景描述)
|
|
454
|
+
|
|
455
|
+
## 步骤
|
|
456
|
+
1. (待补充步骤)
|
|
457
|
+
|
|
458
|
+
## 检查点
|
|
459
|
+
- [ ] (待补充检查点)
|
|
460
|
+
|
|
461
|
+
## 注意事项
|
|
462
|
+
- (待补充注意事项)`;
|
|
463
|
+
}
|
|
464
|
+
function generatePipelineBody(input) {
|
|
465
|
+
return `# ${input.title}
|
|
466
|
+
|
|
467
|
+
### 第1步:定义阶段
|
|
468
|
+
(待补充阶段描述)
|
|
469
|
+
产出保存到:.soloforge/output/01-产出.md
|
|
470
|
+
工具:sf_classify, sf_expand
|
|
471
|
+
|
|
472
|
+
### 第2步:执行阶段
|
|
473
|
+
(待补充阶段描述)
|
|
474
|
+
工具:sf_verify`;
|
|
475
|
+
}
|
|
476
|
+
function generateReviewRuleBody(input) {
|
|
477
|
+
const code = input.title.toUpperCase().replace(/-/g, "").slice(0, 3);
|
|
478
|
+
return `## ${code}-01: (待补充规则标题)
|
|
479
|
+
pattern: /(待补充正则)/
|
|
480
|
+
severity: warning
|
|
481
|
+
scope: ${input.scope.join(", ")}
|
|
482
|
+
description: (待补充规则描述)`;
|
|
483
|
+
}
|
|
484
|
+
function generateAcceptanceBody(input) {
|
|
485
|
+
return `# ${input.title}
|
|
486
|
+
|
|
487
|
+
## 1. (待补充章节标题)
|
|
488
|
+
(待补充内容)
|
|
489
|
+
|
|
490
|
+
## 2. (待补充章节标题)
|
|
491
|
+
(待补充内容)`;
|
|
492
|
+
}
|
|
493
|
+
// ── Enrichment Guide ──
|
|
494
|
+
function extractTopicFromTitle(title) {
|
|
495
|
+
return title.split(/[-_]/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
496
|
+
}
|
|
497
|
+
function buildEnrichmentGuide(input) {
|
|
498
|
+
const builders = {
|
|
499
|
+
pattern: () => buildPatternGuide(input),
|
|
500
|
+
domain: () => buildDomainGuide(input),
|
|
501
|
+
procedure: () => buildProcedureGuide(input),
|
|
502
|
+
pipeline_procedure: () => buildPipelineGuide(input),
|
|
503
|
+
review_rule: () => buildReviewRuleGuide(input),
|
|
504
|
+
acceptance_template: () => buildAcceptanceGuide(input),
|
|
505
|
+
};
|
|
506
|
+
return builders[input.type]();
|
|
507
|
+
}
|
|
508
|
+
function buildPatternGuide(input) {
|
|
509
|
+
const topic = extractTopicFromTitle(input.title);
|
|
510
|
+
return {
|
|
511
|
+
entry_name: input.title,
|
|
512
|
+
type: "pattern",
|
|
513
|
+
overview: `从行业最佳实践中提取"${topic}"领域的决策规则和验收标准。规则应具体、可操作、可验证,覆盖安全、性能、可维护性等维度。`,
|
|
514
|
+
steps: [
|
|
515
|
+
{
|
|
516
|
+
step_number: 1,
|
|
517
|
+
action: `搜索"${topic}"的最佳实践、常见陷阱和反模式`,
|
|
518
|
+
search_queries: [`${topic} best practices software development`, `${topic} common mistakes anti-patterns`, `${topic} production checklist enterprise`],
|
|
519
|
+
focus_areas: ["常见错误", "性能陷阱", "安全风险", "可维护性"],
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
step_number: 2,
|
|
523
|
+
action: `从搜索结果中提取至少 5 条决策规则`,
|
|
524
|
+
search_queries: [`${topic} coding guidelines ${input.scope.join(" ")}`, `${topic} design patterns enterprise java`],
|
|
525
|
+
focus_areas: ["规则具体性", "可操作性", "互斥性"],
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
step_number: 3,
|
|
529
|
+
action: "为每条规则设计可验证的验收标准(AC)",
|
|
530
|
+
focus_areas: ["可自动化检查", "明确的通过/失败标准"],
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
step_number: 4,
|
|
534
|
+
action: `调用 sf_knowledge_update 将探索到的规则和验收项写入文件`,
|
|
535
|
+
focus_areas: ["使用 add_decision_rules 和 add_acceptance_criteria 参数"],
|
|
536
|
+
},
|
|
537
|
+
],
|
|
538
|
+
authoritative_sources: [
|
|
539
|
+
"OWASP Cheat Sheet Series — 安全相关模式",
|
|
540
|
+
"Google Engineering Practices (google.github.io/eng-practices) — 代码评审实践",
|
|
541
|
+
"Alibaba Java Development Manual — Java 开发最佳实践",
|
|
542
|
+
"Martin Fowler's Patterns Catalog — 设计模式",
|
|
543
|
+
"Microsoft API Guidelines — API 设计模式",
|
|
544
|
+
],
|
|
545
|
+
completeness_thresholds: [
|
|
546
|
+
{ field: "decision_rules", minimum: 5 },
|
|
547
|
+
{ field: "acceptance_criteria", minimum: 3 },
|
|
548
|
+
],
|
|
549
|
+
update_call_template: `sf_knowledge_update(entry_name="${input.title}", add_decision_rules=[规则1, 规则2, ...], add_acceptance_criteria=[标准1, 标准2, ...])`,
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
function buildDomainGuide(input) {
|
|
553
|
+
const topic = extractTopicFromTitle(input.title);
|
|
554
|
+
return {
|
|
555
|
+
entry_name: input.title,
|
|
556
|
+
type: "domain",
|
|
557
|
+
overview: `研究"${topic}"领域的行业标准和监管要求,提取业务规则、约束条件、例外情况和关联模式。`,
|
|
558
|
+
steps: [
|
|
559
|
+
{
|
|
560
|
+
step_number: 1,
|
|
561
|
+
action: `搜索"${topic}"领域的行业标准和法规要求`,
|
|
562
|
+
search_queries: [`${topic} business rules industry standard`, `${topic} compliance regulatory requirements`, `${topic} domain driven design`],
|
|
563
|
+
focus_areas: ["行业法规", "合规要求", "业务约束"],
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
step_number: 2,
|
|
567
|
+
action: "提取核心业务规则(什么必须为真、什么不能发生)",
|
|
568
|
+
focus_areas: ["业务规则", "状态约束", "数据完整性"],
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
step_number: 3,
|
|
572
|
+
action: "识别技术约束和操作约束",
|
|
573
|
+
focus_areas: ["性能约束", "安全约束", "容量约束"],
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
step_number: 4,
|
|
577
|
+
action: "列举例外场景和边界条件",
|
|
578
|
+
focus_areas: ["边缘场景", "特殊条件", "豁免情况"],
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
step_number: 5,
|
|
582
|
+
action: `调用 sf_knowledge_update 将探索到的内容写入文件`,
|
|
583
|
+
focus_areas: ["使用 add_decision_rules 写入业务规则"],
|
|
584
|
+
},
|
|
585
|
+
],
|
|
586
|
+
authoritative_sources: [
|
|
587
|
+
"OWASP — 安全相关领域",
|
|
588
|
+
"PCI-DSS — 支付相关领域",
|
|
589
|
+
"GDPR / 个人信息保护法 — 数据隐私领域",
|
|
590
|
+
"Domain-Driven Design (Eric Evans) — 领域建模",
|
|
591
|
+
"行业特定标准(HIPAA/SOX/ISO 27001)",
|
|
592
|
+
],
|
|
593
|
+
completeness_thresholds: [
|
|
594
|
+
{ field: "business_rules", minimum: 6 },
|
|
595
|
+
{ field: "constraints", minimum: 4 },
|
|
596
|
+
{ field: "exceptions", minimum: 2 },
|
|
597
|
+
{ field: "related_patterns", minimum: 1 },
|
|
598
|
+
],
|
|
599
|
+
update_call_template: `sf_knowledge_update(entry_name="${input.title}", add_decision_rules=[业务规则1, 业务规则2, ...])`,
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
function buildProcedureGuide(input) {
|
|
603
|
+
const topic = extractTopicFromTitle(input.title);
|
|
604
|
+
return {
|
|
605
|
+
entry_name: input.title,
|
|
606
|
+
type: "procedure",
|
|
607
|
+
overview: `研究"${topic}"的标准操作流程,拆分为有序步骤、检查点和注意事项。`,
|
|
608
|
+
steps: [
|
|
609
|
+
{
|
|
610
|
+
step_number: 1,
|
|
611
|
+
action: `搜索"${topic}"的标准流程和行业实践`,
|
|
612
|
+
search_queries: [`${topic} standard procedure workflow`, `${topic} step by step guide`, `${topic} operational best practices`],
|
|
613
|
+
focus_areas: ["标准流程", "关键步骤", "验证节点"],
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
step_number: 2,
|
|
617
|
+
action: "将流程拆分为有序的原子步骤",
|
|
618
|
+
focus_areas: ["步骤顺序", "步骤原子性", "输入输出明确"],
|
|
619
|
+
},
|
|
620
|
+
{
|
|
621
|
+
step_number: 3,
|
|
622
|
+
action: "在关键节点设计检查点(验证门禁)",
|
|
623
|
+
focus_areas: ["质量门禁", "可验证条件"],
|
|
624
|
+
},
|
|
625
|
+
{
|
|
626
|
+
step_number: 4,
|
|
627
|
+
action: "识别常见陷阱和注意事项",
|
|
628
|
+
focus_areas: ["常见错误", "风险点", "最佳实践"],
|
|
629
|
+
},
|
|
630
|
+
{
|
|
631
|
+
step_number: 5,
|
|
632
|
+
action: `调用 sf_knowledge_update 将步骤内容写入文件`,
|
|
633
|
+
focus_areas: ["使用 add_decision_rules 写入步骤和注意事项"],
|
|
634
|
+
},
|
|
635
|
+
],
|
|
636
|
+
authoritative_sources: [
|
|
637
|
+
"Google SRE Book — 运维流程实践",
|
|
638
|
+
"CI/CD Pipeline Best Practices — 部署发布流程",
|
|
639
|
+
"Git Workflow Guides — 代码管理流程",
|
|
640
|
+
"OWASP Secure Development Lifecycle — 安全开发流程",
|
|
641
|
+
],
|
|
642
|
+
completeness_thresholds: [
|
|
643
|
+
{ field: "steps", minimum: 5 },
|
|
644
|
+
{ field: "checkpoints", minimum: 3 },
|
|
645
|
+
{ field: "notes", minimum: 3 },
|
|
646
|
+
],
|
|
647
|
+
update_call_template: `sf_knowledge_update(entry_name="${input.title}", add_decision_rules=[步骤内容, 注意事项, ...])`,
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
function buildPipelineGuide(input) {
|
|
651
|
+
const topic = extractTopicFromTitle(input.title);
|
|
652
|
+
return {
|
|
653
|
+
entry_name: input.title,
|
|
654
|
+
type: "pipeline_procedure",
|
|
655
|
+
overview: `设计"${topic}"的多阶段流水线,明确每个阶段的工具、产出和检查点。`,
|
|
656
|
+
steps: [
|
|
657
|
+
{
|
|
658
|
+
step_number: 1,
|
|
659
|
+
action: `搜索"${topic}"相关的流水线或工作流设计`,
|
|
660
|
+
search_queries: [`${topic} pipeline workflow design`, `${topic} multi-phase process`],
|
|
661
|
+
focus_areas: ["阶段划分", "阶段边界", "入口/出口条件"],
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
step_number: 2,
|
|
665
|
+
action: "为每个阶段映射具体的 SoloForge 工具(sf_classify, sf_expand, sf_verify 等)",
|
|
666
|
+
focus_areas: ["工具选择", "工具参数"],
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
step_number: 3,
|
|
670
|
+
action: "定义每个阶段的产出物和保存路径",
|
|
671
|
+
focus_areas: ["产出格式", "路径规范"],
|
|
672
|
+
},
|
|
673
|
+
{
|
|
674
|
+
step_number: 4,
|
|
675
|
+
action: `调用 sf_knowledge_update 将阶段内容写入文件`,
|
|
676
|
+
focus_areas: ["使用 add_decision_rules 写入阶段定义"],
|
|
677
|
+
},
|
|
678
|
+
],
|
|
679
|
+
authoritative_sources: [
|
|
680
|
+
"CI/CD Pipeline Best Practices",
|
|
681
|
+
"Google SRE Release Engineering",
|
|
682
|
+
"GitHub Actions Workflow Patterns",
|
|
683
|
+
],
|
|
684
|
+
completeness_thresholds: [
|
|
685
|
+
{ field: "phases", minimum: 3 },
|
|
686
|
+
{ field: "tools_per_phase", minimum: 1 },
|
|
687
|
+
],
|
|
688
|
+
update_call_template: `sf_knowledge_update(entry_name="${input.title}", add_decision_rules=[阶段定义1, 阶段定义2, ...])`,
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
function buildReviewRuleGuide(input) {
|
|
692
|
+
const topic = extractTopicFromTitle(input.title);
|
|
693
|
+
return {
|
|
694
|
+
entry_name: input.title,
|
|
695
|
+
type: "review_rule",
|
|
696
|
+
overview: `研究"${topic}"相关的代码质量问题,定义正则匹配规则、严重级别和描述。规则需覆盖安全、性能、质量维度。`,
|
|
697
|
+
steps: [
|
|
698
|
+
{
|
|
699
|
+
step_number: 1,
|
|
700
|
+
action: `搜索"${topic}"相关的常见代码质量问题和安全漏洞`,
|
|
701
|
+
search_queries: [`${topic} code review checklist`, `${topic} static analysis rules`, `${topic} common vulnerabilities patterns`],
|
|
702
|
+
focus_areas: ["代码异味", "安全漏洞模式", "性能反模式"],
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
step_number: 2,
|
|
706
|
+
action: "为每个问题定义可匹配的正则表达式(pattern)",
|
|
707
|
+
focus_areas: ["正则精确性", "误报率控制", "覆盖变体"],
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
step_number: 3,
|
|
711
|
+
action: "分配严重级别(critical/warning/info)并编写描述",
|
|
712
|
+
focus_areas: ["严重度合理性", "描述清晰性", "修复建议"],
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
step_number: 4,
|
|
716
|
+
action: `调用 sf_knowledge_update 将规则写入文件`,
|
|
717
|
+
focus_areas: ["使用 add_decision_rules 写入规则定义"],
|
|
718
|
+
},
|
|
719
|
+
],
|
|
720
|
+
authoritative_sources: [
|
|
721
|
+
"OWASP Code Review Guide — 安全审查规则",
|
|
722
|
+
"ESLint / PMD / Checkstyle Rule Catalogs — 静态分析规则",
|
|
723
|
+
"Google Style Guides — 代码风格规则",
|
|
724
|
+
"Alibaba Java Development Manual — Java 规则",
|
|
725
|
+
"SonarQube Rule Definitions — 质量规则",
|
|
726
|
+
],
|
|
727
|
+
completeness_thresholds: [
|
|
728
|
+
{ field: "rules", minimum: 5 },
|
|
729
|
+
{ field: "critical_rules", minimum: 1 },
|
|
730
|
+
],
|
|
731
|
+
update_call_template: `sf_knowledge_update(entry_name="${input.title}", add_decision_rules=[规则定义1, 规则定义2, ...])`,
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
function buildAcceptanceGuide(input) {
|
|
735
|
+
const topic = extractTopicFromTitle(input.title);
|
|
736
|
+
return {
|
|
737
|
+
entry_name: input.title,
|
|
738
|
+
type: "acceptance_template",
|
|
739
|
+
overview: `研究"${topic}"的行业标准验收门禁,设计覆盖安全、性能、质量维度的验收清单,每个验收项需包含可执行的检查命令。`,
|
|
740
|
+
steps: [
|
|
741
|
+
{
|
|
742
|
+
step_number: 1,
|
|
743
|
+
action: `搜索"${topic}"的质量门禁和验收标准`,
|
|
744
|
+
search_queries: [`${topic} acceptance criteria checklist`, `${topic} quality gate verification`, `${topic} production readiness review`],
|
|
745
|
+
focus_areas: ["安全验收", "性能验收", "功能验收", "合规验收"],
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
step_number: 2,
|
|
749
|
+
action: "为每个验收项设计可执行的检查命令(grep/find/test 命令)",
|
|
750
|
+
focus_areas: ["命令可执行性", "结果可判定性"],
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
step_number: 3,
|
|
754
|
+
action: "确保验收项覆盖安全(≥2项)和质量(≥2项)维度",
|
|
755
|
+
focus_areas: ["安全覆盖", "质量覆盖", "独立性"],
|
|
756
|
+
},
|
|
757
|
+
{
|
|
758
|
+
step_number: 4,
|
|
759
|
+
action: `调用 sf_knowledge_update 将验收项写入文件`,
|
|
760
|
+
focus_areas: ["使用 add_acceptance_criteria 写入验收项"],
|
|
761
|
+
},
|
|
762
|
+
],
|
|
763
|
+
authoritative_sources: [
|
|
764
|
+
"OWASP ASVS (Application Security Verification Standard) — 安全验收",
|
|
765
|
+
"Microsoft Security Development Lifecycle — 安全开发验收",
|
|
766
|
+
"Google Engineering Practices — 代码质量验收",
|
|
767
|
+
"IEEE Software Quality Standards — 软件质量标准",
|
|
768
|
+
],
|
|
769
|
+
completeness_thresholds: [
|
|
770
|
+
{ field: "acceptance_criteria", minimum: 10 },
|
|
771
|
+
{ field: "security_acs", minimum: 2 },
|
|
772
|
+
{ field: "check_commands", minimum: 10 },
|
|
773
|
+
],
|
|
774
|
+
update_call_template: `sf_knowledge_update(entry_name="${input.title}", add_acceptance_criteria=[验收项1, 验收项2, ...])`,
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
function getProjectKnowledgeDir(config) {
|
|
778
|
+
const projectDir = config._projectPath ?? process.cwd();
|
|
779
|
+
return path.join(projectDir, ".soloforge", "knowledge");
|
|
780
|
+
}
|
|
781
|
+
//# sourceMappingURL=knowledge_manager.js.map
|