Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
8cd3fe1
feat(lang_parser): add multi-language parser module (standalone)
HuYaSen Jun 1, 2026
6804d5b
feat(encoder): wire lang_parser into RPG / dep-graph / encoder pipeline
HuYaSen Jun 1, 2026
0aa2287
fix(encoder): plug 3 lang_parser integration holes found in review
HuYaSen Jun 1, 2026
d8f19c5
fix(encoder): normalize non-Python class-like unit kinds to 'class' i…
HuYaSen Jun 2, 2026
12cfcee
feat(encoder): propagate language metadata through refactor_tree Node…
HuYaSen Jun 2, 2026
7b5f480
docs(encoder): scrub Python-only wording from semantic-extraction pro…
HuYaSen Jun 2, 2026
4664517
fix(encoder): dispatch add_file and _rerun_semantic_passes on language
HuYaSen Jun 2, 2026
5f9ddf6
fix(encoder): detect dominant language so rpg.json meta.language refl…
HuYaSen Jun 4, 2026
3720feb
fix(encoder): also propagate dominant_language through incremental re…
HuYaSen Jun 4, 2026
d830b9c
feat(decoder): multi-language abstraction layer (Phases 0-5)
HuYaSen Jun 5, 2026
ac853f7
fix(encoder): atomic write for rpg.json + dep_graph.json (no more hal…
HuYaSen Jun 5, 2026
21b2d86
fix(encoder): atomic write for 4 remaining JSON write sites
HuYaSen Jun 5, 2026
a0c3a10
refactor(rpg): dep_graph rides inside rpg.json (single source of truth)
HuYaSen Jun 5, 2026
60bf013
docs: Scrub migration-phase comments from Python sources
HuYaSen Jun 6, 2026
1ec55dc
feat(decoder): Add Go backend structure support
HuYaSen Jun 7, 2026
a4191ee
fix(feature): Handle dict leaves in path expansion
HuYaSen Jun 7, 2026
d5d215b
fix(encoder): Align checks with current graph storage
HuYaSen Jun 7, 2026
758ac74
docs(decoder): Update Go backend package description
HuYaSen Jun 7, 2026
8bd30cc
fix(decoder): Preserve target languages through planning
HuYaSen Jun 8, 2026
1aa3151
feat(decoder): Use meta language fields across planning
HuYaSen Jun 8, 2026
3ea0f61
feat(decoder): Add Rust and TypeScript planning backends
HuYaSen Jun 8, 2026
f4a72be
fix(decoder): Fail incomplete interface planning
HuYaSen Jun 8, 2026
cf2058d
fix(decoder): Resume completed interface subtrees
HuYaSen Jun 8, 2026
5fe3b2f
chore(decoder): Print interface generation progress
HuYaSen Jun 9, 2026
0662232
fix(decoder): Use language-neutral interface prompts
HuYaSen Jun 9, 2026
1713731
fix(decoder): Cap interface subtree retries
HuYaSen Jun 9, 2026
5632740
fix(decoder): Recognize TypeScript declaration stubs
HuYaSen Jun 9, 2026
a723373
fix(decoder): Preserve Python interface review pass
HuYaSen Jun 9, 2026
e5f2648
fix(decoder): Strip fenced interface snippets
HuYaSen Jun 9, 2026
0866e84
fix(decoder): Ignore TypeScript comments during validation
HuYaSen Jun 9, 2026
4a0d9cd
feat(decoder): Add C and C++ pipeline support
HuYaSen Jun 9, 2026
4e22643
feat(codegen): Route execution through language backends
HuYaSen Jun 9, 2026
34248dd
fix(plan): Complete C-family interface coverage
HuYaSen Jun 10, 2026
cac4bf0
feat(codegen): Add bounded loop and project-aware C++ syntax fallback
HuYaSen Jun 10, 2026
f61d3bf
fix(parser): Stop false "unterminated string" on comments and lifetimes
HuYaSen Jun 10, 2026
8470aa5
fix(init): Append .venv_dev ignore to pre-existing gitignore
HuYaSen Jun 10, 2026
7ad05b7
feat(decoder): Add JavaScript code-generation backend
HuYaSen Jun 10, 2026
5acf538
fix(codegen): Stop non-Python projects from emitting Python files
HuYaSen Jun 11, 2026
bd79bce
fix(codegen): Keep dep graph and API summary language-aware across ba…
HuYaSen Jun 11, 2026
85f06a7
fix(plan): Order non-Python files by real imports, not Python AST
HuYaSen Jun 11, 2026
d9f5d16
fix(codegen): Run review-stage tests with the native test command, no…
HuYaSen Jun 11, 2026
5c6cf8f
fix(plan): Parse interface code with the target-language backend
HuYaSen Jun 11, 2026
1b99bcf
fix(dep-graph): Resolve C/C++ calls to the definition, not the header…
HuYaSen Jun 11, 2026
d460d33
fix(codegen): Summarize base classes with the target-language backend
HuYaSen Jun 11, 2026
46a4385
fix(codegen): Skip Python venv/pip setup for non-Python review stages
HuYaSen Jun 11, 2026
80afdc3
feat(decoder): Add list_inheritance to the language backend API
HuYaSen Jun 11, 2026
4d5e00d
fix(plan): Resolve interface inheritance for all languages
HuYaSen Jun 11, 2026
23b0452
refactor(plan): Make the Python-only interface review gate explicit
HuYaSen Jun 11, 2026
15c05e9
feat(plan): Run the global interface review for every language
HuYaSen Jun 11, 2026
05ed594
docs(plan): Align interface-review wording with multilingual review
HuYaSen Jun 11, 2026
77135b3
perf(rpg): centralize scan exclusions and drop per-commit LLM exclude
HuYaSen Jun 12, 2026
cf55b92
fix(plan,codegen): refine interface-review gating and parse noise
HuYaSen Jun 12, 2026
88ae9f8
feat(decoder): add unit-kind and entrypoint backend APIs
HuYaSen Jun 13, 2026
49e63ab
fix(plan): exclude type-like units from orphan checks
HuYaSen Jun 13, 2026
d21cab2
fix(plan): reconcile entrypoints and harden multilang checks
HuYaSen Jun 13, 2026
47dd00f
chore(prompts): scrub Python-isms from codegen prompts
HuYaSen Jun 13, 2026
d0cdf13
fix(codegen): sanitize git branch names across stages
HuYaSen Jun 13, 2026
adfd91c
feat(codegen): add bounded repair loop to final test
HuYaSen Jun 13, 2026
5a7c0d1
fix(verify): resolve language from on-disk sources
HuYaSen Jun 14, 2026
f456e2e
fix(verify): reject zero-test runs as a no-op pass
HuYaSen Jun 14, 2026
6877ee1
fix(go): run go test with -v so passed counts are parsed
HuYaSen Jun 14, 2026
897c571
fix(plan): exclude test and build units from orphan detection
HuYaSen Jun 14, 2026
1e4173e
fix(plan): reconcile program entry path for all languages
HuYaSen Jun 14, 2026
a05e103
fix(plan): unify orphan detection across connectivity and coverage gates
HuYaSen Jun 15, 2026
5e02cfc
test: Move newly added tests to follow-up branch
HuYaSen Jun 15, 2026
53e1d46
fix(verify): use backend test command in repair prompts
HuYaSen Jun 15, 2026
03bf1fa
fix(verify): close multi-language verification gaps from review
HuYaSen Jun 15, 2026
b8b9bef
fix(spec): tighten Go inference and correct doc/prompt examples
HuYaSen Jun 15, 2026
3bffe56
fix(encoder): keep PARSE_CLASS example language-neutral
HuYaSen Jun 15, 2026
22e0e18
[codermind] Clean non-header imports.
QingtaoLi1 Jun 23, 2026
5f1f478
[cmind] Update cmind init hint expression.
QingtaoLi1 Jun 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CoderMind/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Reverse Direction: Code → RPG │
│ │ │ (full) │ │ (manual │ │
└──────────────────┘ └────┬─────┘ │ fallback)│ │
rpg.json └──────────┘ │
dep_graph.json rpg.json / dep_graph.json
(includes dep_graph) rpg.json
│ │
└──────────────────────────────────────────┘
Expand Down
10 changes: 10 additions & 0 deletions CoderMind/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ dependencies = [
"pytest",
"tree-sitter",
"tree-sitter-json",
# Tree-sitter grammars for the lang_parser module (Go / TS / JS / C / C++ /
# Rust). Installed by default so every language works out of the box; each
# is lazy-loaded in lang_parser/tree_sitter_backend.py, so if one grammar
# fails to import on a given platform only that language degrades.
"tree-sitter-go>=0.23.4",
"tree-sitter-typescript>=0.23.2",
"tree-sitter-javascript>=0.23.1",
"tree-sitter-c>=0.24.2",
"tree-sitter-cpp>=0.23.4",
"tree-sitter-rust>=0.24.2",
"networkx",
"rank_bm25",
"rapidfuzz",
Expand Down
6 changes: 5 additions & 1 deletion CoderMind/scripts/build_data_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
# Import centralized paths
from common.paths import SKELETON_FILE, DATA_FLOW_FILE, REPO_RPG_FILE
from common import get_project_background_context
from common.language_meta import extract_language_metadata, metadata_with_languages


# ============================================================================
Expand Down Expand Up @@ -139,6 +140,7 @@ def build(self, skeleton: Dict[str, Any]) -> Dict[str, Any]:
"""
# Get repository info
repo_name, repo_info = get_repo_info_from_files()
primary_language, _ = extract_language_metadata(skeleton)

# Enrich repo_info with project background / technology context
project_background = get_project_background_context()
Expand Down Expand Up @@ -185,7 +187,8 @@ def build(self, skeleton: Dict[str, Any]) -> Dict[str, Any]:
max_iterations=self.max_iterations,
logger=self.logger,
trajectory=self.trajectory,
step_id=self._current_step_id
step_id=self._current_step_id,
target_language=primary_language,
)

result = agent.build_data_flow(
Expand All @@ -198,6 +201,7 @@ def build(self, skeleton: Dict[str, Any]) -> Dict[str, Any]:

# Add components to result
result["components"] = functional_areas
result["meta"] = metadata_with_languages(skeleton)

# Update trajectory
if self.trajectory and self._current_step_id:
Expand Down
20 changes: 18 additions & 2 deletions CoderMind/scripts/build_skeleton.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
REPO_RPG_FILE,
)
from common import print_unicode_table
from common.language_meta import extract_language_metadata, metadata_with_languages
from pathlib import Path as PPath
from rpg import NodeMetaData
from skeleton.skeleton_prompts import extract_features_from_subtree
Expand Down Expand Up @@ -74,6 +75,12 @@ def convert_node(node):
output = {
"repository_name": rpg.repo_name,
"repository_purpose": rpg.repo_info,
"meta": metadata_with_languages({
"meta": {
"primary_language": getattr(rpg.repo_node.meta, "language", None)
if rpg.repo_node and rpg.repo_node.meta else None
}
}),
"root": convert_node(skeleton.root),
"statistics": {
"total_components": len([n for n in rpg.nodes.values() if n.level == 1]),
Expand All @@ -100,6 +107,7 @@ def __init__(self, max_iterations: int = 10, trajectory: Trajectory = None):

# Build state
self.repo_name = ""
self.target_language = None
self.repo_data = {}
self.rpg = None
self.skeleton = None
Expand All @@ -121,6 +129,7 @@ def build(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
"""Execute complete skeleton building workflow."""
self.repo_data = input_data
self.repo_name = input_data.get("repository_name", "project")
self.target_language = extract_language_metadata(input_data)[0]
components = input_data.get("components", [])

if not components:
Expand Down Expand Up @@ -242,7 +251,8 @@ def _step2_file_design(self) -> bool:
rpg=self.rpg,
max_iterations=self.max_iterations,
trajectory=self.trajectory,
step_id=self._current_step_id
step_id=self._current_step_id,
target_language=self.target_language,
)

# Run file design process
Expand Down Expand Up @@ -281,6 +291,12 @@ def _build_result(self) -> Dict[str, Any]:
"""Build the final result dictionary in CoderMind format."""
# Convert to CoderMind compatible format
result = convert_skeleton_to_cmind_format(self.skeleton, self.rpg)
result["meta"] = metadata_with_languages({
"meta": {
"primary_language": self.target_language,
"target_languages": [self.target_language] if self.target_language else [],
}
})

# Add statistics
result["statistics"].update({
Expand Down Expand Up @@ -553,7 +569,7 @@ def patch_missing(input_data: Dict[str, Any]) -> Dict[str, Any]:
json.dump(result, f, indent=2, ensure_ascii=False)
rpg.save_json(str(REPO_RPG_FILE), indent=2)

print(f"\n[OK] Patch complete:")
print("\n[OK] Patch complete:")
print(f" - Missing features patched: {total_missing}")
print(f" - New files created: {new_file_count}")
print(f" - Features merged into existing files: {merged_count}")
Expand Down
28 changes: 16 additions & 12 deletions CoderMind/scripts/check_base_classes.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#!/usr/bin/env python3
"""Check Base Classes Script.

Function: Validate base_classes.json state and validate Python syntax
Function: Validate base_classes.json state and target-language syntax
- Checks if base_classes.json exists (init state)
- Validates JSON structure (error state if invalid)
- Validates Python code syntax (error state if syntax errors)
- Validates source syntax (error state if syntax errors)
- Returns update state if valid

Input: .cmind/base_classes.json
Expand All @@ -15,8 +15,9 @@
from pathlib import Path
from typing import Dict, Any, List, Tuple

# Import from common utils
from common import validate_python_syntax, extract_class_names
from common.language_meta import extract_language_metadata
from decoder_lang import get_backend
from func_design.base_class_agent import extract_declaration_names

# Import centralized paths
from common.paths import BASE_CLASSES_FILE
Expand All @@ -34,6 +35,7 @@ def load_json(file_path: Path) -> Dict[str, Any]:
def validate_base_classes_structure(data: Dict[str, Any]) -> Tuple[bool, List[str]]:
"""Validate base classes structure."""
errors = []
backend = get_backend(extract_language_metadata(data)[0])

base_classes = data.get("base_classes", [])

Expand All @@ -53,16 +55,15 @@ def validate_base_classes_structure(data: Dict[str, Any]) -> Tuple[bool, List[st
elif not bc[field]:
errors.append(f"Base class {i}: field '{field}' is empty")

# Validate Python syntax
code = bc.get("code", "")
if code:
is_valid, error = validate_python_syntax(code)
is_valid, error = backend.syntax_check(code, bc.get("file_path", ""))
if not is_valid:
# Try to get name from bc or extract from code
name = bc.get("name", "")
if not name:
class_names = extract_class_names(code)
name = class_names[0] if class_names else "unknown"
declarations = extract_declaration_names(code, backend)
name = declarations[0] if declarations else "unknown"
errors.append(f"Base class {i} ({name}): syntax error - {error}")

# Also validate data_structures if present
Expand Down Expand Up @@ -94,11 +95,13 @@ def validate_base_classes_structure(data: Dict[str, Any]) -> Tuple[bool, List[st

code = ds.get("code", "")
if code:
is_valid, error = validate_python_syntax(code)
is_valid, error = backend.syntax_check(
code,
ds.get("file_path", f"data_structure{backend.file_extension}"),
)
if not is_valid:
name = ""
class_names = extract_class_names(code)
name = class_names[0] if class_names else "unknown"
declarations = extract_declaration_names(code, backend)
name = declarations[0] if declarations else "unknown"
errors.append(f"Data structure {i} ({name}): syntax error - {error}")

return len(errors) == 0, errors
Expand Down Expand Up @@ -172,6 +175,7 @@ def inspect_state(base_classes_path: Path) -> Dict[str, Any]:
"data_structure_names": ds_class_names,
"data_structure_subtrees": ds_subtrees,
"data_structure_file_paths": ds_file_paths,
"language": extract_language_metadata(data)[0],
}
}

Expand Down
53 changes: 45 additions & 8 deletions CoderMind/scripts/check_code_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,16 +362,53 @@ def determine_state(
# actually generating the expected files.
missing_artifacts = []
repo_root = REPO_DIR

# Check for main_entry task artifact

# Resolve the target language so entry-point / dependency artifact
# checks are not hard-coded to Python's ``main.py`` /
# ``requirements.txt``. Routes through the canonical repo resolver so
# the language is inferred from the real on-disk sources when the rpg
# metadata is missing, rather than silently assuming Python. Falls
# back to Python on any failure so the check degrades to its previous
# behaviour rather than crashing.
backend = None
try:
from common.paths import REPO_RPG_FILE
from decoder_lang import resolve_repo_backend
rpg_obj = None
if Path(REPO_RPG_FILE).is_file():
rpg_obj = json.loads(Path(REPO_RPG_FILE).read_text(encoding="utf-8"))
backend = resolve_repo_backend(repo_root, rpg_obj=rpg_obj)
except Exception: # noqa: BLE001 — degraded mode: assume Python
backend = None

# Check for main_entry task artifact (language-aware entry path).
main_entry_ids = [tid for tid in completed_ids if tid.startswith("<MAIN_ENTRY>")]
if main_entry_ids and not (repo_root / "main.py").exists():
missing_artifacts.append("main.py (from <MAIN_ENTRY> task)")

# Check for requirements task artifact
if main_entry_ids:
if backend is not None:
# Accept any of the backend's entry-point shapes. A single
# canonical path is too strict when the skeleton placed the
# entry off-canonical (e.g. C++ ``src/cli/main.cpp``) or the
# language uses a glob convention (Go ``cmd/*/main.go``).
candidates = backend.entry_point_candidates()
entry_exists = any(
(any(repo_root.glob(c)) if "*" in c else (repo_root / c).exists())
for c in candidates
)
if not entry_exists:
missing_artifacts.append(
f"{candidates[0]} (from <MAIN_ENTRY> task)"
)
elif not (repo_root / "main.py").exists():
missing_artifacts.append("main.py (from <MAIN_ENTRY> task)")

# Check for requirements task artifact. The dependency-manifest
# filename is language-specific; only Python's is asserted here
# (other languages manage deps via go.mod / Cargo.toml / package.json
# which the dependency task and build steps validate separately).
req_ids = [tid for tid in completed_ids if tid.startswith("<REQUIREMENTS>")]
if req_ids and not (repo_root / "requirements.txt").exists():
missing_artifacts.append("requirements.txt (from <REQUIREMENTS> task)")
if req_ids and (backend is None or backend.name == "python"):
if not (repo_root / "requirements.txt").exists():
missing_artifacts.append("requirements.txt (from <REQUIREMENTS> task)")

if missing_artifacts:
result["type"] = "incomplete"
Expand Down
Loading
Loading