boomtick-cli 0.2.1__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.
- boomtick_cli-0.2.1.dist-info/METADATA +20 -0
- boomtick_cli-0.2.1.dist-info/RECORD +103 -0
- boomtick_cli-0.2.1.dist-info/WHEEL +5 -0
- boomtick_cli-0.2.1.dist-info/entry_points.txt +3 -0
- boomtick_cli-0.2.1.dist-info/top_level.txt +1 -0
- dev_tools/__init__.py +1 -0
- dev_tools/cli-schema.json +2028 -0
- dev_tools/cli.py +1542 -0
- dev_tools/config.py +235 -0
- dev_tools/constants.py +14 -0
- dev_tools/daemon.py +146 -0
- dev_tools/dist/config.js +108 -0
- dev_tools/dist/index.js +10 -0
- dev_tools/dist/lib/error_utils.js +8 -0
- dev_tools/dist/lib/git.js +31 -0
- dev_tools/dist/lib/result.js +21 -0
- dev_tools/dist/lib/shell.js +91 -0
- dev_tools/dist/lib/shell.test.js +10 -0
- dev_tools/dist/lib/td-cli.js +27 -0
- dev_tools/dist/lib/test-utils.js +20 -0
- dev_tools/dist/mcp/definitions.js +242 -0
- dev_tools/dist/mcp/server.js +317 -0
- dev_tools/dist/mcp/tools.js +18 -0
- dev_tools/dist/tools/contract.js +2069 -0
- dev_tools/dist/tools/ddgs.search.js +50 -0
- dev_tools/dist/tools/ddgs.search.test.js +67 -0
- dev_tools/dist/tools/ddgs_search.py +23 -0
- dev_tools/dist/tools/github.checkout_branch.js +20 -0
- dev_tools/dist/tools/github.comment_triage_summary.js +25 -0
- dev_tools/dist/tools/github.create_issue.js +28 -0
- dev_tools/dist/tools/github.create_issue.test.js +54 -0
- dev_tools/dist/tools/github.create_pull_request.js +44 -0
- dev_tools/dist/tools/github.get_merge_conflict_files.js +26 -0
- dev_tools/dist/tools/github.get_pr.js +18 -0
- dev_tools/dist/tools/github.get_pr_diff.js +24 -0
- dev_tools/dist/tools/github.issue_comment.js +24 -0
- dev_tools/dist/tools/github.issue_update.js +29 -0
- dev_tools/dist/tools/github.issue_view.js +28 -0
- dev_tools/dist/tools/github.open_replacement_pr.js +41 -0
- dev_tools/dist/tools/github.search_open_prs.js +31 -0
- dev_tools/dist/tools/github.search_open_prs.test.js +51 -0
- dev_tools/dist/tools/jules/cancel-session.js +20 -0
- dev_tools/dist/tools/jules/create-session.js +20 -0
- dev_tools/dist/tools/jules/create-session.test.js +99 -0
- dev_tools/dist/tools/jules/get-messages.js +19 -0
- dev_tools/dist/tools/jules/get-messages.test.js +45 -0
- dev_tools/dist/tools/jules/get-pr.js +14 -0
- dev_tools/dist/tools/jules/get-pr.test.js +37 -0
- dev_tools/dist/tools/jules/get-session.js +10 -0
- dev_tools/dist/tools/jules/list-sessions.js +43 -0
- dev_tools/dist/tools/jules/send-message.js +22 -0
- dev_tools/dist/tools/jules/send-message.test.js +56 -0
- dev_tools/dist/tools/jules/shared.js +26 -0
- dev_tools/dist/tools/jules/trigger-feedback.js +16 -0
- dev_tools/dist/tools/jules/trigger-feedback.test.js +42 -0
- dev_tools/dist/tools/repo.commit_patch.js +33 -0
- dev_tools/dist/tools/repo.create_branch.js +21 -0
- dev_tools/dist/tools/repo.create_branch.test.js +42 -0
- dev_tools/dist/tools/repo.create_repair_branch.js +38 -0
- dev_tools/dist/tools/repo.get_changed_files.js +21 -0
- dev_tools/dist/tools/repo.get_command_schema.js +27 -0
- dev_tools/dist/tools/repo.get_package_scripts.js +35 -0
- dev_tools/dist/tools/repo.get_package_scripts.test.js +39 -0
- dev_tools/dist/tools/repo.get_route_map.js +37 -0
- dev_tools/dist/tools/repo.logs.js +16 -0
- dev_tools/dist/tools/repo.read_agent_context.js +20 -0
- dev_tools/dist/tools/repo.read_ci_logs.js +18 -0
- dev_tools/dist/tools/repo.run_lighthouse.js +37 -0
- dev_tools/dist/tools/repo.run_playwright.js +29 -0
- dev_tools/dist/tools/repo.run_tests.js +43 -0
- dev_tools/dist/tools/types.js +1 -0
- dev_tools/get_ai_context.py +63 -0
- dev_tools/handlers/__init__.py +1 -0
- dev_tools/handlers/command_handler.py +69 -0
- dev_tools/mcp_server.py +36 -0
- dev_tools/models.py +354 -0
- dev_tools/orchestrator.py +2841 -0
- dev_tools/pr_overlap.py +139 -0
- dev_tools/resources/__init__.py +1 -0
- dev_tools/resources/build-repo-context.py +182 -0
- dev_tools/resources/prompt_constants.json +5 -0
- dev_tools/resources/review_template.md +41 -0
- dev_tools/resources/ux-audit.config.json +15 -0
- dev_tools/resources/visual_guidelines.json +3 -0
- dev_tools/review_read_pass.py +232 -0
- dev_tools/schema_gen.py +55 -0
- dev_tools/schema_utils.py +125 -0
- dev_tools/scope_check.py +85 -0
- dev_tools/services/__init__.py +1 -0
- dev_tools/services/ai_service.py +816 -0
- dev_tools/services/dependency_graph.py +123 -0
- dev_tools/services/github.py +783 -0
- dev_tools/services/jules.py +181 -0
- dev_tools/services/repair_service.py +199 -0
- dev_tools/services/vector_store.py +82 -0
- dev_tools/services/vision_service.py +91 -0
- dev_tools/td_cli.py +28 -0
- dev_tools/utils/__init__.py +1035 -0
- dev_tools/utils/git.py +68 -0
- dev_tools/ux_report.py +213 -0
- dev_tools/verify_infra.py +91 -0
- dev_tools/verify_versions.py +191 -0
- dev_tools/version_utils.py +175 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# pylint: disable=import-outside-toplevel,missing-docstring,too-many-branches,too-many-locals,too-many-return-statements
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import re
|
|
5
|
+
import sys
|
|
6
|
+
from typing import Dict, Optional
|
|
7
|
+
|
|
8
|
+
import requests
|
|
9
|
+
from packaging import version
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def log_warn(msg: str):
|
|
13
|
+
print(f"⚠️ Warning: {msg}", file=sys.stderr)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def log_error(msg: str):
|
|
17
|
+
print(f"ERROR: {msg}", file=sys.stderr)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# Registry Cache
|
|
21
|
+
_NPM_CACHE: Dict[str, str] = {}
|
|
22
|
+
_GITHUB_CACHE: Dict[str, str] = {}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def fetch_latest_npm(package_name: str) -> Optional[str]:
|
|
26
|
+
if package_name in _NPM_CACHE:
|
|
27
|
+
return _NPM_CACHE[package_name]
|
|
28
|
+
try:
|
|
29
|
+
url = f"https://registry.npmjs.org/{package_name}/latest"
|
|
30
|
+
res = requests.get(url, timeout=5)
|
|
31
|
+
if res.status_code == 200:
|
|
32
|
+
ver = res.json().get("version")
|
|
33
|
+
_NPM_CACHE[package_name] = ver
|
|
34
|
+
return ver
|
|
35
|
+
except Exception as e:
|
|
36
|
+
log_warn(f"Failed to fetch latest NPM version for {package_name}: {e}")
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def fetch_latest_node() -> Optional[str]:
|
|
41
|
+
if "node" in _NPM_CACHE:
|
|
42
|
+
return _NPM_CACHE["node"]
|
|
43
|
+
try:
|
|
44
|
+
url = "https://nodejs.org/dist/index.json"
|
|
45
|
+
res = requests.get(url, timeout=5)
|
|
46
|
+
if res.status_code == 200:
|
|
47
|
+
# Latest is the first one
|
|
48
|
+
ver = res.json()[0].get("version").lstrip("v")
|
|
49
|
+
_NPM_CACHE["node"] = ver
|
|
50
|
+
return ver
|
|
51
|
+
except Exception as e:
|
|
52
|
+
log_warn(f"Failed to fetch latest Node.js version: {e}")
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def fetch_latest_gh_action(action_path: str) -> Optional[str]:
|
|
57
|
+
if action_path in _GITHUB_CACHE:
|
|
58
|
+
return _GITHUB_CACHE[action_path]
|
|
59
|
+
try:
|
|
60
|
+
url = f"https://api.github.com/repos/{action_path}/releases/latest"
|
|
61
|
+
headers = {}
|
|
62
|
+
# Try to use token if available
|
|
63
|
+
from dev_tools.utils import get_github_token
|
|
64
|
+
|
|
65
|
+
token = get_github_token()
|
|
66
|
+
if token:
|
|
67
|
+
headers["Authorization"] = f"token {token}"
|
|
68
|
+
|
|
69
|
+
res = requests.get(url, headers=headers, timeout=5)
|
|
70
|
+
if res.status_code == 200:
|
|
71
|
+
tag = res.json().get("tag_name")
|
|
72
|
+
_GITHUB_CACHE[action_path] = tag
|
|
73
|
+
return tag
|
|
74
|
+
except Exception as e:
|
|
75
|
+
log_warn(f"Failed to fetch latest GitHub Action version for {action_path}: {e}")
|
|
76
|
+
return None
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def compare_versions(v1: str, v2: str) -> int:
|
|
80
|
+
"""Returns 1 if v1 > v2, -1 if v1 < v2, 0 if v1 == v2."""
|
|
81
|
+
if v1 == v2:
|
|
82
|
+
return 0
|
|
83
|
+
try:
|
|
84
|
+
v1_clean = v1.lstrip("v")
|
|
85
|
+
v2_clean = v2.lstrip("v")
|
|
86
|
+
|
|
87
|
+
if ".x" in v1_clean:
|
|
88
|
+
v1_clean = v1_clean.replace(".x", ".0")
|
|
89
|
+
if ".x" in v2_clean:
|
|
90
|
+
v2_clean = v2_clean.replace(".x", ".0")
|
|
91
|
+
|
|
92
|
+
pv1 = version.parse(v1_clean)
|
|
93
|
+
pv2 = version.parse(v2_clean)
|
|
94
|
+
if pv1 > pv2:
|
|
95
|
+
return 1
|
|
96
|
+
if pv1 < pv2:
|
|
97
|
+
return -1
|
|
98
|
+
return 0
|
|
99
|
+
except Exception:
|
|
100
|
+
if v1 > v2:
|
|
101
|
+
return 1
|
|
102
|
+
if v1 < v2:
|
|
103
|
+
return -1
|
|
104
|
+
return 0
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def get_stack_versions(fetch_latest: bool = False) -> Dict[str, str]:
|
|
108
|
+
"""Extracts core versions (Node, pnpm, GHA) from the repository."""
|
|
109
|
+
versions = {
|
|
110
|
+
"node": "24.16.0",
|
|
111
|
+
"pnpm": "10.28.2",
|
|
112
|
+
"actions/checkout": "v4",
|
|
113
|
+
"actions/setup-node": "v4",
|
|
114
|
+
"actions/upload-artifact": "v4",
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
try:
|
|
118
|
+
if os.path.exists(".node-version"):
|
|
119
|
+
with open(".node-version", "r", encoding="utf-8") as f:
|
|
120
|
+
v = f.read().strip().lstrip("v")
|
|
121
|
+
if v:
|
|
122
|
+
versions["node"] = v
|
|
123
|
+
elif os.path.exists(".nvmrc"):
|
|
124
|
+
with open(".nvmrc", "r", encoding="utf-8") as f:
|
|
125
|
+
v = f.read().strip().lstrip("v")
|
|
126
|
+
if v:
|
|
127
|
+
versions["node"] = v
|
|
128
|
+
|
|
129
|
+
if os.path.exists("package.json"):
|
|
130
|
+
with open("package.json", "r", encoding="utf-8") as f:
|
|
131
|
+
pkg = json.load(f)
|
|
132
|
+
if "packageManager" in pkg:
|
|
133
|
+
versions["pnpm"] = pkg["packageManager"].replace("pnpm@", "")
|
|
134
|
+
elif "engines" in pkg and "pnpm" in pkg["engines"]:
|
|
135
|
+
versions["pnpm"] = pkg["engines"]["pnpm"]
|
|
136
|
+
|
|
137
|
+
if "engines" in pkg and "node" in pkg["engines"] and not os.path.exists(".node-version"):
|
|
138
|
+
versions["node"] = pkg["engines"]["node"]
|
|
139
|
+
|
|
140
|
+
workflow_dir = ".github/workflows"
|
|
141
|
+
if os.path.exists(workflow_dir):
|
|
142
|
+
for filename in os.listdir(workflow_dir):
|
|
143
|
+
if not (filename.endswith(".yml") or filename.endswith(".yaml")):
|
|
144
|
+
continue
|
|
145
|
+
try:
|
|
146
|
+
with open(os.path.join(workflow_dir, filename), "r", encoding="utf-8") as f:
|
|
147
|
+
content = f.read()
|
|
148
|
+
matches = re.findall(r"uses:\s+([\w\-/]+)@([\w\.]+)", content)
|
|
149
|
+
for action, v_str in matches:
|
|
150
|
+
if not action.startswith("actions/"):
|
|
151
|
+
continue
|
|
152
|
+
current_v = versions.get(action)
|
|
153
|
+
if not current_v or compare_versions(v_str, current_v) > 0:
|
|
154
|
+
versions[action] = v_str
|
|
155
|
+
except Exception as e:
|
|
156
|
+
log_warn(f"Failed to read workflow {filename}: {e}")
|
|
157
|
+
|
|
158
|
+
if fetch_latest:
|
|
159
|
+
latest_node = fetch_latest_node()
|
|
160
|
+
if latest_node:
|
|
161
|
+
versions["latest_node"] = latest_node
|
|
162
|
+
|
|
163
|
+
latest_pnpm = fetch_latest_npm("pnpm")
|
|
164
|
+
if latest_pnpm:
|
|
165
|
+
versions["latest_pnpm"] = latest_pnpm
|
|
166
|
+
|
|
167
|
+
for action in ["actions/checkout", "actions/setup-node"]:
|
|
168
|
+
latest_a = fetch_latest_gh_action(action)
|
|
169
|
+
if latest_a:
|
|
170
|
+
versions[f"latest_{action}"] = latest_a
|
|
171
|
+
|
|
172
|
+
except Exception as e:
|
|
173
|
+
log_error(f"Unexpected error in get_stack_versions: {e}")
|
|
174
|
+
|
|
175
|
+
return versions
|