@xenonbyte/req-2-plan 0.2.3
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 +172 -0
- package/README.zh-CN.md +158 -0
- package/bin/r2p.js +38 -0
- package/docs/req-to-plan-design.md +277 -0
- package/package.json +47 -0
- package/requirements.txt +1 -0
- package/tools/r2p +10 -0
- package/tools/r2p-continue +10 -0
- package/tools/r2p-gap-open +10 -0
- package/tools/r2p-gap-resolve +10 -0
- package/tools/r2p-reopen +10 -0
- package/tools/r2p-start +10 -0
- package/tools/r2p-status +10 -0
- package/tools/r2p-switch +10 -0
- package/tools/r2p-tier-lock +10 -0
- package/tools/workflow_cli/__init__.py +0 -0
- package/tools/workflow_cli/__main__.py +5 -0
- package/tools/workflow_cli/agent_shortcuts.py +778 -0
- package/tools/workflow_cli/agent_templates/claude/SKILL.md +34 -0
- package/tools/workflow_cli/agent_templates/claude/commands/r2p-continue.md +16 -0
- package/tools/workflow_cli/agent_templates/claude/commands/r2p-gap-open.md +8 -0
- package/tools/workflow_cli/agent_templates/claude/commands/r2p-gap-resolve.md +8 -0
- package/tools/workflow_cli/agent_templates/claude/commands/r2p-reopen.md +8 -0
- package/tools/workflow_cli/agent_templates/claude/commands/r2p-start.md +10 -0
- package/tools/workflow_cli/agent_templates/claude/commands/r2p-status.md +8 -0
- package/tools/workflow_cli/agent_templates/claude/commands/r2p-switch.md +8 -0
- package/tools/workflow_cli/agent_templates/claude/commands/r2p-tier-lock.md +8 -0
- package/tools/workflow_cli/agent_templates/codex/skills/r2p-continue/SKILL.md +12 -0
- package/tools/workflow_cli/agent_templates/codex/skills/r2p-gap-open/SKILL.md +12 -0
- package/tools/workflow_cli/agent_templates/codex/skills/r2p-gap-resolve/SKILL.md +12 -0
- package/tools/workflow_cli/agent_templates/codex/skills/r2p-reopen/SKILL.md +12 -0
- package/tools/workflow_cli/agent_templates/codex/skills/r2p-start/SKILL.md +14 -0
- package/tools/workflow_cli/agent_templates/codex/skills/r2p-status/SKILL.md +12 -0
- package/tools/workflow_cli/agent_templates/codex/skills/r2p-switch/SKILL.md +12 -0
- package/tools/workflow_cli/agent_templates/codex/skills/r2p-tier-lock/SKILL.md +12 -0
- package/tools/workflow_cli/agent_templates/gemini/commands/r2p-continue.toml +4 -0
- package/tools/workflow_cli/agent_templates/gemini/commands/r2p-gap-open.toml +4 -0
- package/tools/workflow_cli/agent_templates/gemini/commands/r2p-gap-resolve.toml +4 -0
- package/tools/workflow_cli/agent_templates/gemini/commands/r2p-reopen.toml +4 -0
- package/tools/workflow_cli/agent_templates/gemini/commands/r2p-start.toml +4 -0
- package/tools/workflow_cli/agent_templates/gemini/commands/r2p-status.toml +4 -0
- package/tools/workflow_cli/agent_templates/gemini/commands/r2p-switch.toml +4 -0
- package/tools/workflow_cli/agent_templates/gemini/commands/r2p-tier-lock.toml +4 -0
- package/tools/workflow_cli/artifact.py +228 -0
- package/tools/workflow_cli/cli.py +1779 -0
- package/tools/workflow_cli/gates.py +471 -0
- package/tools/workflow_cli/install.py +900 -0
- package/tools/workflow_cli/install_cli.py +158 -0
- package/tools/workflow_cli/link_expander.py +102 -0
- package/tools/workflow_cli/models.py +504 -0
- package/tools/workflow_cli/output.py +91 -0
- package/tools/workflow_cli/repo_baseline.py +137 -0
- package/tools/workflow_cli/state.py +621 -0
- package/tools/workflow_cli/tier.py +201 -0
- package/tools/workflow_cli/tier_keywords.yaml +45 -0
- package/tools/workflow_cli/version.py +1 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"""Scan repo baseline metrics: LOC, language breakdown, monorepo detection, submodules."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class RepoBaseline:
|
|
12
|
+
"""Repository baseline metrics."""
|
|
13
|
+
loc: int = 0
|
|
14
|
+
module_count: int = 0
|
|
15
|
+
is_monorepo: bool = False
|
|
16
|
+
language_breakdown: dict[str, int] = field(default_factory=dict)
|
|
17
|
+
submodule_count: int = 0
|
|
18
|
+
cross_language_refs: list[str] = field(default_factory=list)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
EXTENSION_TO_LANGUAGE = {
|
|
22
|
+
".py": "Python",
|
|
23
|
+
".ts": "TypeScript",
|
|
24
|
+
".tsx": "TypeScript",
|
|
25
|
+
".js": "JavaScript",
|
|
26
|
+
".jsx": "JavaScript",
|
|
27
|
+
".go": "Go",
|
|
28
|
+
".rs": "Rust",
|
|
29
|
+
".java": "Java",
|
|
30
|
+
".kt": "Kotlin",
|
|
31
|
+
".swift": "Swift",
|
|
32
|
+
".rb": "Ruby",
|
|
33
|
+
".php": "PHP",
|
|
34
|
+
".cs": "C#",
|
|
35
|
+
".cpp": "C++",
|
|
36
|
+
".cc": "C++",
|
|
37
|
+
".c": "C",
|
|
38
|
+
".h": "C",
|
|
39
|
+
".scala": "Scala",
|
|
40
|
+
".ex": "Elixir",
|
|
41
|
+
".exs": "Elixir",
|
|
42
|
+
".zig": "Zig",
|
|
43
|
+
".dart": "Dart",
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
MONOREPO_SIGNALS = {
|
|
47
|
+
"package.json",
|
|
48
|
+
"setup.py",
|
|
49
|
+
"Cargo.toml",
|
|
50
|
+
"go.mod",
|
|
51
|
+
"build.gradle",
|
|
52
|
+
"pom.xml",
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
SKIP_DIRS = {
|
|
56
|
+
".git",
|
|
57
|
+
".worktrees",
|
|
58
|
+
"node_modules",
|
|
59
|
+
"__pycache__",
|
|
60
|
+
".venv",
|
|
61
|
+
"venv",
|
|
62
|
+
"dist",
|
|
63
|
+
"build",
|
|
64
|
+
"target",
|
|
65
|
+
".pytest_cache",
|
|
66
|
+
".mypy_cache",
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _count_loc(path: Path) -> int:
|
|
71
|
+
"""Count non-blank lines of code in a file."""
|
|
72
|
+
try:
|
|
73
|
+
text = path.read_text(encoding="utf-8", errors="ignore")
|
|
74
|
+
return sum(1 for line in text.splitlines() if line.strip())
|
|
75
|
+
except (PermissionError, OSError):
|
|
76
|
+
return 0
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def scan_repo_baseline(repo_path: Path) -> RepoBaseline:
|
|
80
|
+
"""Scan repo directory and return baseline metrics.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
repo_path: Path to the repository root.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
RepoBaseline with collected metrics.
|
|
87
|
+
"""
|
|
88
|
+
total_loc = 0
|
|
89
|
+
language_breakdown: dict[str, int] = {}
|
|
90
|
+
monorepo_signal_files: dict[str, list[Path]] = {}
|
|
91
|
+
module_dirs: set[Path] = set()
|
|
92
|
+
submodule_count = 0
|
|
93
|
+
|
|
94
|
+
for root, dirs, files in os.walk(repo_path):
|
|
95
|
+
root_path = Path(root)
|
|
96
|
+
# Skip excluded directories
|
|
97
|
+
dirs[:] = [d for d in dirs if d not in SKIP_DIRS and not d.startswith(".")]
|
|
98
|
+
|
|
99
|
+
for fname in files:
|
|
100
|
+
fpath = root_path / fname
|
|
101
|
+
ext = fpath.suffix.lower()
|
|
102
|
+
|
|
103
|
+
# Count lines of code for recognized languages
|
|
104
|
+
if ext in EXTENSION_TO_LANGUAGE:
|
|
105
|
+
lang = EXTENSION_TO_LANGUAGE[ext]
|
|
106
|
+
loc = _count_loc(fpath)
|
|
107
|
+
total_loc += loc
|
|
108
|
+
language_breakdown[lang] = language_breakdown.get(lang, 0) + loc
|
|
109
|
+
module_dirs.add(root_path)
|
|
110
|
+
|
|
111
|
+
# Track monorepo signal files
|
|
112
|
+
if fname in MONOREPO_SIGNALS:
|
|
113
|
+
monorepo_signal_files.setdefault(fname, []).append(fpath)
|
|
114
|
+
|
|
115
|
+
# Count git submodules
|
|
116
|
+
if fname == ".gitmodules":
|
|
117
|
+
try:
|
|
118
|
+
content = fpath.read_text(encoding="utf-8", errors="ignore")
|
|
119
|
+
submodule_count = content.count("[submodule ")
|
|
120
|
+
except (PermissionError, OSError):
|
|
121
|
+
pass
|
|
122
|
+
|
|
123
|
+
# Detect monorepo: 2+ of same signal file type (e.g., 2+ package.json)
|
|
124
|
+
is_monorepo = any(len(paths) >= 2 for paths in monorepo_signal_files.values())
|
|
125
|
+
|
|
126
|
+
# Cross-language refs: list of languages if 2+
|
|
127
|
+
languages = sorted(language_breakdown.keys())
|
|
128
|
+
cross_language_refs = languages if len(languages) >= 2 else []
|
|
129
|
+
|
|
130
|
+
return RepoBaseline(
|
|
131
|
+
loc=total_loc,
|
|
132
|
+
module_count=len(module_dirs),
|
|
133
|
+
is_monorepo=is_monorepo,
|
|
134
|
+
language_breakdown=language_breakdown,
|
|
135
|
+
submodule_count=submodule_count,
|
|
136
|
+
cross_language_refs=cross_language_refs,
|
|
137
|
+
)
|