source-kb 0.2.2__py3-none-any.whl
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.
- cli/__init__.py +50 -0
- cli/__main__.py +5 -0
- cli/commands/__init__.py +1 -0
- cli/commands/anchor_fix.py +47 -0
- cli/commands/diff_doc.py +52 -0
- cli/commands/dispatch.py +77 -0
- cli/commands/extract.py +72 -0
- cli/commands/file_list.py +74 -0
- cli/commands/index.py +84 -0
- cli/commands/lock.py +89 -0
- cli/commands/merge.py +60 -0
- cli/commands/merge_delta.py +19 -0
- cli/commands/metadata.py +24 -0
- cli/commands/pipeline.py +45 -0
- cli/commands/post_merge.py +43 -0
- cli/commands/query.py +52 -0
- cli/commands/render.py +101 -0
- cli/commands/scan_repos.py +46 -0
- cli/commands/setup.py +94 -0
- cli/commands/split.py +196 -0
- cli/commands/stale_files.py +98 -0
- cli/commands/validate.py +191 -0
- core/__init__.py +32 -0
- core/config.py +261 -0
- core/docs/__init__.py +7 -0
- core/docs/section_updater.py +286 -0
- core/docs/shared.py +149 -0
- core/git.py +294 -0
- core/interfaces.py +249 -0
- core/monitor/__init__.py +5 -0
- core/monitor/progress.py +83 -0
- core/monitor/prompt_store.py +49 -0
- core/paths.py +141 -0
- core/preset.py +237 -0
- core/preset_accessors.py +202 -0
- core/preset_classify.py +132 -0
- core/preset_hooks.py +129 -0
- core/preset_profile.py +89 -0
- core/prompt/__init__.py +7 -0
- core/prompt/__main__.py +147 -0
- core/prompt/content.py +320 -0
- core/prompt/context_manager.py +164 -0
- core/prompt/renderer.py +236 -0
- core/prompt/response_parser.py +274 -0
- core/prompt/templates.py +357 -0
- core/prompt/validate_parity.py +162 -0
- core/prompt/variables.py +339 -0
- core/rag/__init__.py +22 -0
- core/rag/__main__.py +136 -0
- core/rag/bm25_index.py +268 -0
- core/rag/chunker.py +273 -0
- core/rag/embedder.py +151 -0
- core/rag/indexer.py +292 -0
- core/rag/loader.py +89 -0
- core/rag/retriever.py +82 -0
- core/skeleton/__init__.py +11 -0
- core/skeleton/__main__.py +934 -0
- core/skeleton/anchor_fix.py +250 -0
- core/skeleton/classify.py +331 -0
- core/skeleton/cmd_anchor_fix.py +43 -0
- core/skeleton/cmd_diff_doc.py +44 -0
- core/skeleton/cmd_lock.py +87 -0
- core/skeleton/cmd_merge_delta.py +41 -0
- core/skeleton/community.py +233 -0
- core/skeleton/dependency_graph.py +306 -0
- core/skeleton/diff_doc.py +248 -0
- core/skeleton/dispatch.py +273 -0
- core/skeleton/dispatch_render.py +319 -0
- core/skeleton/dispatch_source.py +111 -0
- core/skeleton/extract.py +218 -0
- core/skeleton/extract_methods.py +298 -0
- core/skeleton/file_list.py +239 -0
- core/skeleton/impact.py +278 -0
- core/skeleton/jar_download.py +177 -0
- core/skeleton/jar_resolver.py +186 -0
- core/skeleton/loader.py +162 -0
- core/skeleton/merge.py +278 -0
- core/skeleton/merge_delta.py +229 -0
- core/skeleton/metadata.py +96 -0
- core/skeleton/metadata_builders.py +264 -0
- core/skeleton/module_dag.py +330 -0
- core/skeleton/parsers/__init__.py +71 -0
- core/skeleton/parsers/jqassistant.py +300 -0
- core/skeleton/parsers/jqassistant_cypher.py +225 -0
- core/skeleton/parsers/regex.py +171 -0
- core/skeleton/parsers/treesitter.py +324 -0
- core/skeleton/parsers/treesitter_java.py +284 -0
- core/skeleton/parsers/treesitter_multi.py +289 -0
- core/skeleton/pom_parser.py +299 -0
- core/skeleton/post_merge.py +295 -0
- core/skeleton/post_merge_llm.py +82 -0
- core/skeleton/query.py +195 -0
- core/skeleton/shard_context.py +177 -0
- core/skeleton/split.py +180 -0
- core/skeleton/split_cache.py +107 -0
- core/skeleton/split_feedback.py +174 -0
- core/skeleton/split_plan.py +219 -0
- core/skeleton/split_plan_helpers.py +305 -0
- core/skeleton/split_plan_llm.py +274 -0
- core/utils.py +135 -0
- core/validators/__init__.py +65 -0
- core/validators/__main__.py +215 -0
- core/validators/consistency.py +203 -0
- core/validators/coverage.py +171 -0
- core/validators/duplicates.py +76 -0
- core/validators/engine.py +224 -0
- core/validators/links.py +76 -0
- core/validators/sampling.py +169 -0
- core/validators/structure.py +144 -0
- engine/__init__.py +7 -0
- engine/assembler.py +231 -0
- engine/confirm.py +65 -0
- engine/dedup.py +106 -0
- engine/main.py +211 -0
- engine/pipeline/__init__.py +163 -0
- engine/pipeline/recovery.py +250 -0
- engine/pipeline/steps/__init__.py +23 -0
- engine/pipeline/steps/audit.py +220 -0
- engine/pipeline/steps/audit_apply.py +195 -0
- engine/pipeline/steps/audit_helpers.py +155 -0
- engine/pipeline/steps/classify_llm.py +236 -0
- engine/pipeline/steps/classify_prompt.py +223 -0
- engine/pipeline/steps/finalize.py +160 -0
- engine/pipeline/steps/generate.py +169 -0
- engine/pipeline/steps/generate_batch.py +197 -0
- engine/pipeline/steps/generate_recovery.py +170 -0
- engine/pipeline/steps/llm_plan_split.py +253 -0
- engine/pipeline/steps/lock.py +64 -0
- engine/pipeline/steps/preflight.py +237 -0
- engine/pipeline/steps/preflight_adjust.py +147 -0
- engine/pipeline/steps/pregenerate.py +130 -0
- engine/pipeline/steps/quality.py +81 -0
- engine/pipeline/steps/skeleton.py +149 -0
- engine/pipeline/steps/source.py +163 -0
- engine/pipeline/steps/sync.py +117 -0
- engine/pipeline/steps/sync_finalize.py +237 -0
- engine/pipeline/steps/sync_update.py +341 -0
- engine/pipelines.py +91 -0
- engine/runner.py +335 -0
- engine/strategies/__init__.py +86 -0
- engine/strategies/api.py +128 -0
- engine/strategies/delegated.py +50 -0
- engine/strategies/dryrun.py +25 -0
- engine/two_phase.py +143 -0
- mcp_server/__init__.py +73 -0
- mcp_server/__main__.py +5 -0
- mcp_server/tools/__init__.py +1 -0
- mcp_server/tools/config.py +63 -0
- mcp_server/tools/discovery.py +276 -0
- mcp_server/tools/generation.py +184 -0
- mcp_server/tools/planning.py +144 -0
- mcp_server/tools/source.py +175 -0
- mcp_server/tools/validation.py +140 -0
- mcp_server/tools/workflow.py +166 -0
- mcp_server/workflow_loader.py +204 -0
- presets/generic/audit_dimensions.md +132 -0
- presets/generic/doc_types.yaml +152 -0
- presets/generic/preset.yaml +115 -0
- presets/java-spring/audit_dimensions.md +228 -0
- presets/java-spring/audit_dimensions.yaml +203 -0
- presets/java-spring/doc_types.yaml +269 -0
- presets/java-spring/hooks.py +122 -0
- presets/java-spring/preset.yaml +341 -0
- presets/java-spring/templates/README.md +34 -0
- presets/java-spring/templates/audit-system.md +15 -0
- presets/java-spring/templates/subagent-aop.md +105 -0
- presets/java-spring/templates/subagent-api.md +63 -0
- presets/java-spring/templates/subagent-architecture.md +111 -0
- presets/java-spring/templates/subagent-async-events.md +107 -0
- presets/java-spring/templates/subagent-audit-api-contracts.md +40 -0
- presets/java-spring/templates/subagent-audit-architecture.md +38 -0
- presets/java-spring/templates/subagent-audit-business.md +40 -0
- presets/java-spring/templates/subagent-audit-data-models.md +40 -0
- presets/java-spring/templates/subagent-business.md +129 -0
- presets/java-spring/templates/subagent-caching.md +75 -0
- presets/java-spring/templates/subagent-database-access.md +114 -0
- presets/java-spring/templates/subagent-enum.md +75 -0
- presets/java-spring/templates/subagent-error-handling.md +91 -0
- presets/java-spring/templates/subagent-external-integrations.md +80 -0
- presets/java-spring/templates/subagent-index.md +122 -0
- presets/java-spring/templates/subagent-messaging.md +97 -0
- presets/java-spring/templates/subagent-model.md +88 -0
- presets/java-spring/templates/subagent-observability.md +91 -0
- presets/java-spring/templates/subagent-scheduled.md +81 -0
- presets/java-spring/templates/subagent-security.md +102 -0
- presets/java-spring/templates/subagent-structure.md +101 -0
- presets/java-spring/templates/subagent-sync-section.md +34 -0
- presets/java-spring/templates/subagent-utils.md +73 -0
- presets/java-spring/templates/sync-system.md +8 -0
- presets/java-spring/workflow-extensions.md +112 -0
- skills/__init__.py +1 -0
- skills/_shared/README.md +30 -0
- skills/_shared/doc-coverage-shared.md +134 -0
- skills/_shared/doc-quality-standard.md +1058 -0
- skills/_shared/doc-subagent-rules.md +762 -0
- skills/_shared/windows-compat.md +89 -0
- skills/kb-audit/SKILL.md +52 -0
- skills/kb-audit/rules.md +88 -0
- skills/kb-audit/steps/step-01-prepare.md +75 -0
- skills/kb-audit/steps/step-02-audit.md +96 -0
- skills/kb-audit/steps/step-03-verify.md +65 -0
- skills/kb-audit/steps/step-04-report.md +64 -0
- skills/kb-init/SKILL.md +146 -0
- skills/kb-init/rules.md +187 -0
- skills/kb-init/steps/step-01-scope.md +62 -0
- skills/kb-init/steps/step-02-source.md +410 -0
- skills/kb-init/steps/step-03-generate.md +307 -0
- skills/kb-init/steps/step-04-quality.md +92 -0
- skills/kb-init/steps/step-05-finalize.md +132 -0
- skills/kb-init/templates/core/execution-modes.md +29 -0
- skills/kb-init/templates/core/output-only.md +4 -0
- skills/kb-init/templates/core/readwrite.md +33 -0
- skills/kb-search/SKILL.md +138 -0
- skills/kb-search/rules.md +64 -0
- skills/kb-sync/SKILL.md +43 -0
- skills/kb-sync/rules.md +70 -0
- skills/kb-sync/scripts/rebuild_module.py +91 -0
- skills/kb-sync/scripts/scan_repos.py +687 -0
- skills/kb-sync/steps/step-01-detect.md +72 -0
- skills/kb-sync/steps/step-02-update.md +71 -0
- skills/kb-sync/steps/step-03-verify.md +47 -0
- skills/kb-sync/steps/step-04-finalize.md +52 -0
- source_kb-0.2.2.dist-info/METADATA +194 -0
- source_kb-0.2.2.dist-info/RECORD +228 -0
- source_kb-0.2.2.dist-info/WHEEL +5 -0
- source_kb-0.2.2.dist-info/entry_points.txt +3 -0
- source_kb-0.2.2.dist-info/licenses/LICENSE +21 -0
- source_kb-0.2.2.dist-info/top_level.txt +6 -0
core/prompt/templates.py
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
"""Prompt template dataclass and registry.
|
|
2
|
+
|
|
3
|
+
Provides parameterized prompt templates for LLM steps (sync section-update,
|
|
4
|
+
audit doc-type checks, etc.). Templates are registered by name and looked up
|
|
5
|
+
at runtime.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
from core.prompt.templates import PromptTemplate, register, get, list_templates
|
|
9
|
+
|
|
10
|
+
template = get("sync:section-update")
|
|
11
|
+
system, user = template.render(doc_type="business-logic", ...)
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class PromptTemplate:
|
|
21
|
+
"""A parameterized prompt template with system and user parts."""
|
|
22
|
+
|
|
23
|
+
name: str
|
|
24
|
+
system_template: str
|
|
25
|
+
user_template: str
|
|
26
|
+
|
|
27
|
+
def render(self, **kwargs: str) -> tuple[str, str]:
|
|
28
|
+
"""Render both templates with provided variables.
|
|
29
|
+
|
|
30
|
+
Missing keys render as empty string (safe fallback).
|
|
31
|
+
Returns (system_prompt, user_prompt).
|
|
32
|
+
"""
|
|
33
|
+
safe = _SafeDict(kwargs)
|
|
34
|
+
return (
|
|
35
|
+
self.system_template.format_map(safe),
|
|
36
|
+
self.user_template.format_map(safe),
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class _SafeDict(dict):
|
|
41
|
+
"""format_map fallback — missing keys render as empty string."""
|
|
42
|
+
def __missing__(self, key: str) -> str:
|
|
43
|
+
return ""
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# ---------------------------------------------------------------------------
|
|
47
|
+
# Registry
|
|
48
|
+
# ---------------------------------------------------------------------------
|
|
49
|
+
|
|
50
|
+
_REGISTRY: dict[str, PromptTemplate] = {}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def register(template: PromptTemplate) -> PromptTemplate:
|
|
54
|
+
"""Register a template by name. Returns the template for decorator use."""
|
|
55
|
+
_REGISTRY[template.name] = template
|
|
56
|
+
return template
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get(name: str) -> PromptTemplate:
|
|
60
|
+
"""Look up a registered template by name. Raises KeyError if not found."""
|
|
61
|
+
if name not in _REGISTRY:
|
|
62
|
+
available = ", ".join(sorted(_REGISTRY.keys()))
|
|
63
|
+
raise KeyError(f"Template '{name}' not found. Available: {available}")
|
|
64
|
+
return _REGISTRY[name]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def list_templates() -> list[str]:
|
|
68
|
+
"""Return sorted list of all registered template names."""
|
|
69
|
+
return sorted(_REGISTRY.keys())
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# ---------------------------------------------------------------------------
|
|
73
|
+
# Built-in templates: Audit
|
|
74
|
+
# ---------------------------------------------------------------------------
|
|
75
|
+
|
|
76
|
+
_AUDIT_SYSTEM_COMMON = (
|
|
77
|
+
"You are a knowledge base auditor. Compare the document against source code "
|
|
78
|
+
"and report findings.\n"
|
|
79
|
+
'Return ONLY a JSON object: {{"findings": [{{"dimension": "...", '
|
|
80
|
+
'"status": "pass|fail", "detail": "...", "fix": "..."}}]}}\n'
|
|
81
|
+
'- "pass": document matches source code for this dimension\n'
|
|
82
|
+
'- "fail": inconsistency found — "detail" explains what\'s wrong, '
|
|
83
|
+
'"fix" gives the corrected content\n'
|
|
84
|
+
"- Be precise: cite specific class/method/field names\n"
|
|
85
|
+
"- Output in Chinese"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
register(PromptTemplate(
|
|
89
|
+
name="audit:source-tree",
|
|
90
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: source-tree-analysis.md\n"
|
|
91
|
+
"Dimensions: 1.file completeness 2.directory structure 3.file responsibility "
|
|
92
|
+
"4.file count 5.new/deleted files",
|
|
93
|
+
user_template=(
|
|
94
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
95
|
+
"Source skeleton:\n{skeleton}\n\nActual file list:\n{file_list}\n\n"
|
|
96
|
+
"Audit source-tree-analysis.md against source code."
|
|
97
|
+
),
|
|
98
|
+
))
|
|
99
|
+
|
|
100
|
+
register(PromptTemplate(
|
|
101
|
+
name="audit:data-models",
|
|
102
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: data-models.md\n"
|
|
103
|
+
"Dimensions: 1.entity completeness 2.field consistency 3.annotation accuracy "
|
|
104
|
+
"4.table name mapping 5.DTO/VO coverage 6.enum values 7.inheritance",
|
|
105
|
+
user_template=(
|
|
106
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
107
|
+
"Entity/DTO/VO skeleton:\n{skeleton}\n\nSource snippets:\n{source_snippets}\n\n"
|
|
108
|
+
"Audit data-models.md against source code."
|
|
109
|
+
),
|
|
110
|
+
))
|
|
111
|
+
|
|
112
|
+
register(PromptTemplate(
|
|
113
|
+
name="audit:api-contracts",
|
|
114
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: api-contracts.md\n"
|
|
115
|
+
"Dimensions: 1.interface completeness 2.URL path 3.HTTP method 4.request params "
|
|
116
|
+
"5.response type 6.error codes 7.Feign fallback 8.permission annotations",
|
|
117
|
+
user_template=(
|
|
118
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
119
|
+
"Controller/API skeleton:\n{skeleton}\n\n"
|
|
120
|
+
"Audit api-contracts.md against source code."
|
|
121
|
+
),
|
|
122
|
+
))
|
|
123
|
+
|
|
124
|
+
register(PromptTemplate(
|
|
125
|
+
name="audit:architecture",
|
|
126
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: architecture.md\n"
|
|
127
|
+
"Dimensions: 1.tech stack versions 2.dependency list 3.layer structure "
|
|
128
|
+
"4.middleware config 5.component relationships 6.config items",
|
|
129
|
+
user_template=(
|
|
130
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
131
|
+
"pom.xml:\n{pom_xml}\n\nConfig (yml):\n{yml_config}\n\n"
|
|
132
|
+
"Config class skeleton:\n{skeleton}\n\n"
|
|
133
|
+
"Audit architecture.md against source code."
|
|
134
|
+
),
|
|
135
|
+
))
|
|
136
|
+
|
|
137
|
+
register(PromptTemplate(
|
|
138
|
+
name="audit:business-logic",
|
|
139
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: business-logic.md\n"
|
|
140
|
+
"Dimensions (10 method-level): 1.method purpose 2.parameter semantics "
|
|
141
|
+
"3.return value meaning 4.core logic flow 5.branch condition rationale "
|
|
142
|
+
"6.exception handling 7.external dependency 8.state mutation "
|
|
143
|
+
"9.performance/concurrency 10.edge case coverage "
|
|
144
|
+
"Plus: 11.reference integrity 12.dedup compliance",
|
|
145
|
+
user_template=(
|
|
146
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
147
|
+
"Service skeleton:\n{skeleton}\n\nSource code (high-complexity methods):\n"
|
|
148
|
+
"{source_code}\n\nNeutral doc headings:\n{neutral_doc_headings}\n\n"
|
|
149
|
+
"Audit business-logic.md against source code."
|
|
150
|
+
),
|
|
151
|
+
))
|
|
152
|
+
|
|
153
|
+
register(PromptTemplate(
|
|
154
|
+
name="audit:messaging",
|
|
155
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: messaging.md\n"
|
|
156
|
+
"Dimensions: 1.topic completeness 2.message body structure "
|
|
157
|
+
"3.consumer groupId 4.producer/consumer relationships",
|
|
158
|
+
user_template=(
|
|
159
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
160
|
+
"Messaging skeleton:\n{skeleton}\n\n"
|
|
161
|
+
"Audit messaging.md against source code."
|
|
162
|
+
),
|
|
163
|
+
))
|
|
164
|
+
|
|
165
|
+
register(PromptTemplate(
|
|
166
|
+
name="audit:caching",
|
|
167
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: caching.md\n"
|
|
168
|
+
"Dimensions: 1.key completeness 2.TTL accuracy 3.data type correctness",
|
|
169
|
+
user_template=(
|
|
170
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
171
|
+
"Caching skeleton:\n{skeleton}\n\nKey constants:\n{key_constants}\n\n"
|
|
172
|
+
"Audit caching.md against source code."
|
|
173
|
+
),
|
|
174
|
+
))
|
|
175
|
+
|
|
176
|
+
register(PromptTemplate(
|
|
177
|
+
name="audit:enums",
|
|
178
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: enums-and-constants.md\n"
|
|
179
|
+
"Dimensions: 1.enum completeness 2.enum value accuracy "
|
|
180
|
+
"3.constant value correctness 4.usage context",
|
|
181
|
+
user_template=(
|
|
182
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
183
|
+
"Enum/constant skeleton:\n{skeleton}\n\n"
|
|
184
|
+
"Audit enums-and-constants.md against source code."
|
|
185
|
+
),
|
|
186
|
+
))
|
|
187
|
+
|
|
188
|
+
register(PromptTemplate(
|
|
189
|
+
name="audit:utils",
|
|
190
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: utils.md\n"
|
|
191
|
+
"Dimensions: 1.utility class completeness 2.method signature accuracy "
|
|
192
|
+
"3.usage context",
|
|
193
|
+
user_template=(
|
|
194
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
195
|
+
"Utility skeleton:\n{skeleton}\n\n"
|
|
196
|
+
"Audit utils.md against source code."
|
|
197
|
+
),
|
|
198
|
+
))
|
|
199
|
+
|
|
200
|
+
register(PromptTemplate(
|
|
201
|
+
name="audit:external",
|
|
202
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: external-integrations.md\n"
|
|
203
|
+
"Dimensions: 1.integration completeness 2.endpoint/URL accuracy "
|
|
204
|
+
"3.request/response format 4.error handling",
|
|
205
|
+
user_template=(
|
|
206
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
207
|
+
"Integration skeleton:\n{skeleton}\n\n"
|
|
208
|
+
"Audit external-integrations.md against source code."
|
|
209
|
+
),
|
|
210
|
+
))
|
|
211
|
+
|
|
212
|
+
register(PromptTemplate(
|
|
213
|
+
name="audit:database",
|
|
214
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: database-access.md\n"
|
|
215
|
+
"Dimensions: 1.mapper completeness 2.SQL semantics accuracy "
|
|
216
|
+
"3.transaction boundaries 4.pagination params 5.batch operations 6.table mapping",
|
|
217
|
+
user_template=(
|
|
218
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
219
|
+
"DAO/Mapper skeleton:\n{skeleton}\n\nSource snippets:\n{source_snippets}\n\n"
|
|
220
|
+
"Audit database-access.md against source code."
|
|
221
|
+
),
|
|
222
|
+
))
|
|
223
|
+
|
|
224
|
+
register(PromptTemplate(
|
|
225
|
+
name="audit:scheduled",
|
|
226
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: scheduled-tasks.md\n"
|
|
227
|
+
"Dimensions: 1.task completeness 2.cron expression accuracy "
|
|
228
|
+
"3.execution frequency 4.idempotency 5.error handling 6.sharding strategy",
|
|
229
|
+
user_template=(
|
|
230
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
231
|
+
"Scheduled task skeleton:\n{skeleton}\n\n"
|
|
232
|
+
"Audit scheduled-tasks.md against source code."
|
|
233
|
+
),
|
|
234
|
+
))
|
|
235
|
+
|
|
236
|
+
register(PromptTemplate(
|
|
237
|
+
name="audit:error",
|
|
238
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: error-handling.md\n"
|
|
239
|
+
"Dimensions: 1.exception class completeness 2.hierarchy structure "
|
|
240
|
+
"3.error code mapping 4.global handler logic 5.user-facing messages",
|
|
241
|
+
user_template=(
|
|
242
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
243
|
+
"Exception skeleton:\n{skeleton}\n\n"
|
|
244
|
+
"Audit error-handling.md against source code."
|
|
245
|
+
),
|
|
246
|
+
))
|
|
247
|
+
|
|
248
|
+
register(PromptTemplate(
|
|
249
|
+
name="audit:security",
|
|
250
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: security.md\n"
|
|
251
|
+
"Dimensions: 1.auth flow completeness 2.token mechanism "
|
|
252
|
+
"3.permission model 4.filter chain order 5.permission identifiers",
|
|
253
|
+
user_template=(
|
|
254
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
255
|
+
"Security skeleton:\n{skeleton}\n\n"
|
|
256
|
+
"Audit security.md against source code."
|
|
257
|
+
),
|
|
258
|
+
))
|
|
259
|
+
|
|
260
|
+
register(PromptTemplate(
|
|
261
|
+
name="audit:aop",
|
|
262
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: aop-and-interceptors.md\n"
|
|
263
|
+
"Dimensions: 1.aspect completeness 2.pointcut expression accuracy "
|
|
264
|
+
"3.execution order 4.interceptor chain 5.advice type logic",
|
|
265
|
+
user_template=(
|
|
266
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
267
|
+
"AOP/Interceptor skeleton:\n{skeleton}\n\n"
|
|
268
|
+
"Audit aop-and-interceptors.md against source code."
|
|
269
|
+
),
|
|
270
|
+
))
|
|
271
|
+
|
|
272
|
+
register(PromptTemplate(
|
|
273
|
+
name="audit:observability",
|
|
274
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: observability.md\n"
|
|
275
|
+
"Dimensions: 1.metric completeness 2.metric name accuracy "
|
|
276
|
+
"3.alert thresholds 4.logging config 5.health checks",
|
|
277
|
+
user_template=(
|
|
278
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
279
|
+
"Observability skeleton:\n{skeleton}\n\n"
|
|
280
|
+
"Audit observability.md against source code."
|
|
281
|
+
),
|
|
282
|
+
))
|
|
283
|
+
|
|
284
|
+
register(PromptTemplate(
|
|
285
|
+
name="audit:async",
|
|
286
|
+
system_template=_AUDIT_SYSTEM_COMMON + "\nTarget: async-and-events.md\n"
|
|
287
|
+
"Dimensions: 1.thread pool config 2.async method completeness "
|
|
288
|
+
"3.event pub/sub relationships 4.failure handling 5.event timing",
|
|
289
|
+
user_template=(
|
|
290
|
+
"Module: {module_name}\nCurrent document:\n{doc_content}\n\n"
|
|
291
|
+
"Async/Event skeleton:\n{skeleton}\n\n"
|
|
292
|
+
"Audit async-and-events.md against source code."
|
|
293
|
+
),
|
|
294
|
+
))
|
|
295
|
+
|
|
296
|
+
# ---------------------------------------------------------------------------
|
|
297
|
+
# Built-in templates: Sync (incremental update)
|
|
298
|
+
# ---------------------------------------------------------------------------
|
|
299
|
+
|
|
300
|
+
register(PromptTemplate(
|
|
301
|
+
name="sync:section-update",
|
|
302
|
+
system_template=(
|
|
303
|
+
"You are a knowledge base maintainer. Update a specific document section "
|
|
304
|
+
"based on source code changes.\nRules:\n"
|
|
305
|
+
"- Only rewrite the affected section, preserve the rest\n"
|
|
306
|
+
"- Maintain existing document structure and style\n"
|
|
307
|
+
"- Write from business perspective, not code translation\n"
|
|
308
|
+
"- Output the complete updated section content in Chinese\n"
|
|
309
|
+
"- Do NOT output anything outside the section content"
|
|
310
|
+
),
|
|
311
|
+
user_template=(
|
|
312
|
+
"Document type: {doc_type}\nSection heading: {section_heading}\n\n"
|
|
313
|
+
"Current section content:\n{old_content}\n\n"
|
|
314
|
+
"Changed source files:\n{changed_files}\n\n"
|
|
315
|
+
"Skeleton delta:\n{skeleton_delta}\n\n"
|
|
316
|
+
"Rewrite this section to reflect the source code changes."
|
|
317
|
+
),
|
|
318
|
+
))
|
|
319
|
+
|
|
320
|
+
# ---------------------------------------------------------------------------
|
|
321
|
+
# Audit doc_type → template name mapping
|
|
322
|
+
# ---------------------------------------------------------------------------
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def get_audit_doc_type_map(preset: dict | None = None) -> dict[str, str]:
|
|
326
|
+
"""Generate audit template mapping from preset doc_types dynamically."""
|
|
327
|
+
if preset:
|
|
328
|
+
doc_types = preset.get("doc_types", {})
|
|
329
|
+
if doc_types:
|
|
330
|
+
result: dict[str, str] = {}
|
|
331
|
+
for dt_key in doc_types:
|
|
332
|
+
short = dt_key.split("-")[0] if "-" in dt_key else dt_key
|
|
333
|
+
result[dt_key] = f"audit:{short}"
|
|
334
|
+
return result
|
|
335
|
+
# Fallback for backward compat
|
|
336
|
+
return AUDIT_DOC_TYPE_MAP
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
AUDIT_DOC_TYPE_MAP: dict[str, str] = {
|
|
340
|
+
"source-tree-analysis": "audit:source-tree",
|
|
341
|
+
"data-models": "audit:data-models",
|
|
342
|
+
"api-contracts": "audit:api-contracts",
|
|
343
|
+
"architecture": "audit:architecture",
|
|
344
|
+
"business-logic": "audit:business-logic",
|
|
345
|
+
"messaging": "audit:messaging",
|
|
346
|
+
"caching": "audit:caching",
|
|
347
|
+
"enums-and-constants": "audit:enums",
|
|
348
|
+
"utils": "audit:utils",
|
|
349
|
+
"external-integrations": "audit:external",
|
|
350
|
+
"database-access": "audit:database",
|
|
351
|
+
"scheduled-tasks": "audit:scheduled",
|
|
352
|
+
"error-handling": "audit:error",
|
|
353
|
+
"security": "audit:security",
|
|
354
|
+
"aop-and-interceptors": "audit:aop",
|
|
355
|
+
"observability": "audit:observability",
|
|
356
|
+
"async-and-events": "audit:async",
|
|
357
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""Template parity validation — ensures CLI and Agent templates stay in sync.
|
|
2
|
+
|
|
3
|
+
Validates that:
|
|
4
|
+
1. Every CLI_Template (audit:*, sync:*) has a corresponding Agent_Template .md file
|
|
5
|
+
2. Variable placeholders match between CLI and Agent versions
|
|
6
|
+
3. No orphaned Agent templates without CLI registration
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
python -m core.prompt validate-parity --preset java-spring
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import re
|
|
15
|
+
import sys
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class ParityViolation:
|
|
22
|
+
"""A single parity violation."""
|
|
23
|
+
|
|
24
|
+
template_name: str
|
|
25
|
+
violation_type: str # "missing_agent", "missing_cli", "variable_mismatch"
|
|
26
|
+
detail: str
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def validate_parity(preset_name: str) -> list[ParityViolation]:
|
|
30
|
+
"""Compare CLI templates against Agent template files.
|
|
31
|
+
|
|
32
|
+
Returns list of violations (empty = all good).
|
|
33
|
+
"""
|
|
34
|
+
from core.prompt.templates import _REGISTRY as REGISTRY
|
|
35
|
+
from core.preset import PRESETS_DIR
|
|
36
|
+
|
|
37
|
+
violations: list[ParityViolation] = []
|
|
38
|
+
templates_dir = PRESETS_DIR / preset_name / "templates"
|
|
39
|
+
|
|
40
|
+
if not templates_dir.is_dir():
|
|
41
|
+
violations.append(ParityViolation(
|
|
42
|
+
template_name="*",
|
|
43
|
+
violation_type="missing_agent",
|
|
44
|
+
detail=f"Templates directory not found: {templates_dir}",
|
|
45
|
+
))
|
|
46
|
+
return violations
|
|
47
|
+
|
|
48
|
+
# Check CLI → Agent direction
|
|
49
|
+
for name, template in REGISTRY.items():
|
|
50
|
+
if not (name.startswith("audit:") or name.startswith("sync:")):
|
|
51
|
+
continue
|
|
52
|
+
|
|
53
|
+
# Expected agent template filename: "audit:business-logic" → "subagent-audit-business-logic.md"
|
|
54
|
+
agent_filename = "subagent-" + name.replace(":", "-") + ".md"
|
|
55
|
+
agent_path = templates_dir / agent_filename
|
|
56
|
+
|
|
57
|
+
if not agent_path.exists():
|
|
58
|
+
violations.append(ParityViolation(
|
|
59
|
+
template_name=name,
|
|
60
|
+
violation_type="missing_agent",
|
|
61
|
+
detail=f"Agent template not found: {agent_filename}",
|
|
62
|
+
))
|
|
63
|
+
continue
|
|
64
|
+
|
|
65
|
+
# Compare variables
|
|
66
|
+
cli_vars = _extract_cli_variables(template)
|
|
67
|
+
agent_vars = _extract_agent_variables(agent_path)
|
|
68
|
+
|
|
69
|
+
missing_in_agent = cli_vars - agent_vars
|
|
70
|
+
missing_in_cli = agent_vars - cli_vars
|
|
71
|
+
|
|
72
|
+
if missing_in_agent:
|
|
73
|
+
violations.append(ParityViolation(
|
|
74
|
+
template_name=name,
|
|
75
|
+
violation_type="variable_mismatch",
|
|
76
|
+
detail=f"Variables in CLI but not Agent: {sorted(missing_in_agent)}",
|
|
77
|
+
))
|
|
78
|
+
if missing_in_cli:
|
|
79
|
+
violations.append(ParityViolation(
|
|
80
|
+
template_name=name,
|
|
81
|
+
violation_type="variable_mismatch",
|
|
82
|
+
detail=f"Variables in Agent but not CLI: {sorted(missing_in_cli)}",
|
|
83
|
+
))
|
|
84
|
+
|
|
85
|
+
# Check Agent → CLI direction (orphaned agent templates)
|
|
86
|
+
for md_file in sorted(templates_dir.glob("subagent-audit-*.md")):
|
|
87
|
+
# "subagent-audit-business.md" → "audit:business"
|
|
88
|
+
stem = md_file.stem # "subagent-audit-business"
|
|
89
|
+
parts = stem.split("-", 1) # ["subagent", "audit-business"]
|
|
90
|
+
if len(parts) < 2:
|
|
91
|
+
continue
|
|
92
|
+
cli_name = parts[1].replace("-", ":", 1) # "audit:business"
|
|
93
|
+
if cli_name not in REGISTRY:
|
|
94
|
+
# Not a violation if CLI templates haven't been registered yet
|
|
95
|
+
# (Agent templates can exist ahead of CLI registration)
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
for md_file in sorted(templates_dir.glob("subagent-sync-*.md")):
|
|
99
|
+
stem = md_file.stem
|
|
100
|
+
parts = stem.split("-", 1)
|
|
101
|
+
if len(parts) < 2:
|
|
102
|
+
continue
|
|
103
|
+
cli_name = parts[1].replace("-", ":", 1)
|
|
104
|
+
if cli_name not in REGISTRY:
|
|
105
|
+
pass
|
|
106
|
+
|
|
107
|
+
return violations
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _extract_cli_variables(template) -> set[str]:
|
|
111
|
+
"""Extract variable placeholders from a CLI PromptTemplate."""
|
|
112
|
+
variables: set[str] = set()
|
|
113
|
+
# PromptTemplate uses {variable_name} syntax
|
|
114
|
+
text = template.system + "\n" + template.user
|
|
115
|
+
for match in re.finditer(r'\{(\w+)\}', text):
|
|
116
|
+
variables.add(match.group(1))
|
|
117
|
+
return variables
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _extract_agent_variables(agent_path: Path) -> set[str]:
|
|
121
|
+
"""Extract variable placeholders from an Agent template .md file."""
|
|
122
|
+
variables: set[str] = set()
|
|
123
|
+
try:
|
|
124
|
+
content = agent_path.read_text(encoding="utf-8")
|
|
125
|
+
except OSError:
|
|
126
|
+
return variables
|
|
127
|
+
|
|
128
|
+
# Agent templates use {variable_name} syntax
|
|
129
|
+
for match in re.finditer(r'\{(\w+)\}', content):
|
|
130
|
+
var = match.group(1)
|
|
131
|
+
# Filter out common false positives (JSON examples, etc.)
|
|
132
|
+
if var not in ("json", "else", "if", "endif", "status", "dimension", "detail", "fix"):
|
|
133
|
+
variables.add(var)
|
|
134
|
+
|
|
135
|
+
return variables
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def main() -> None:
|
|
139
|
+
"""CLI entry point for parity validation."""
|
|
140
|
+
import argparse
|
|
141
|
+
|
|
142
|
+
parser = argparse.ArgumentParser(
|
|
143
|
+
prog="python -m core.prompt validate-parity",
|
|
144
|
+
description="Validate CLI/Agent template parity",
|
|
145
|
+
)
|
|
146
|
+
parser.add_argument("--preset", required=True, help="Preset name")
|
|
147
|
+
args = parser.parse_args()
|
|
148
|
+
|
|
149
|
+
violations = validate_parity(args.preset)
|
|
150
|
+
|
|
151
|
+
if violations:
|
|
152
|
+
print(f"❌ {len(violations)} parity violation(s) found:\n")
|
|
153
|
+
for v in violations:
|
|
154
|
+
print(f" [{v.violation_type}] {v.template_name}: {v.detail}")
|
|
155
|
+
sys.exit(1)
|
|
156
|
+
else:
|
|
157
|
+
print(f"✅ All templates in sync for preset '{args.preset}'")
|
|
158
|
+
sys.exit(0)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
if __name__ == "__main__":
|
|
162
|
+
main()
|