agentic-devtools 0.2.596__py3-none-any.whl → 0.2.597__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.
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.2.596'
22
- __version_tuple__ = version_tuple = (0, 2, 596)
21
+ __version__ = version = '0.2.597'
22
+ __version_tuple__ = version_tuple = (0, 2, 597)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -5,13 +5,19 @@ Checks all external CLI tools that ``agentic-devtools`` depends on and
5
5
  reports their availability, version, and install path in a formatted table.
6
6
  """
7
7
 
8
+ import json
9
+ import os
8
10
  import re
11
+ import shlex
9
12
  import shutil
10
13
  import subprocess
11
14
  import sys
12
15
  from dataclasses import dataclass, field
16
+ from importlib.metadata import PackageNotFoundError, distribution
13
17
  from pathlib import Path
14
18
  from typing import Any
19
+ from urllib.parse import urlsplit
20
+ from urllib.request import url2pathname
15
21
 
16
22
  from ..subprocess_utils import run_safe
17
23
  from .git_hooks_policy import is_git_hooks_management_enabled
@@ -128,23 +134,11 @@ def _find_binary(name: str) -> str | None:
128
134
  return shutil.which(name)
129
135
 
130
136
 
131
- def _check_dependency(
132
- name: str,
133
- *,
134
- required: bool,
135
- install_hint: str,
136
- category: str,
137
- ) -> DependencyStatus:
137
+ def _check_dependency(name: str, *, required: bool, install_hint: str, category: str) -> DependencyStatus:
138
138
  """Check a single dependency and return its :class:`DependencyStatus`."""
139
139
  path = _find_binary(name)
140
140
  if not path:
141
- return DependencyStatus(
142
- name=name,
143
- found=False,
144
- required=required,
145
- install_hint=install_hint,
146
- category=category,
147
- )
141
+ return DependencyStatus(name=name, found=False, required=required, install_hint=install_hint, category=category)
148
142
  version = _get_version(name, path)
149
143
  return DependencyStatus(
150
144
  name=name,
@@ -162,6 +156,50 @@ def _check_dependency(
162
156
  # ---------------------------------------------------------------------------
163
157
 
164
158
 
159
+ def _check_editable_install() -> DependencyStatus:
160
+ """Report stale editable sources for this interpreter without repairing them."""
161
+ status = DependencyStatus(name="editable-install", found=True, category="Warning")
162
+ status.install_hint = "pip install -e <current-worktree-root>"
163
+ try:
164
+ cwd = Path.cwd().resolve()
165
+ root = next((p for p in (cwd, *cwd.parents) if (p / "pyproject.toml").is_file()), None)
166
+ root_path = ("<current-worktree-root>", str(root))[root is not None]
167
+ powershell_path = "'" + root_path.replace("'", "''") + "'"
168
+ quote = (shlex.quote(root_path), powershell_path)[sys.platform == "win32"]
169
+ status.install_hint = (f"pip install -e {root_path}", f"pip install -e {quote}")[root is not None]
170
+ raw = (installed_distribution := distribution("agentic-devtools")).read_text("direct_url.json")
171
+ if raw is None: # PathDistribution.read_text suppresses PermissionError by returning None.
172
+ try:
173
+ raw = getattr(installed_distribution, "_path").joinpath("direct_url.json").read_text(encoding="utf-8")
174
+ except AttributeError, FileNotFoundError, KeyError, NotADirectoryError:
175
+ return status
176
+ data = json.loads(raw)
177
+ if not isinstance(data, dict):
178
+ raise ValueError("Invalid direct_url.json object")
179
+ info = data.get("dir_info", {})
180
+ if not isinstance(info, dict) or not isinstance(info.get("editable", False), bool):
181
+ raise ValueError("Invalid editable metadata")
182
+ if not info.get("editable", False):
183
+ return status
184
+ url = data.get("url")
185
+ if not isinstance(url, str):
186
+ raise ValueError("Missing editable source URL")
187
+ parsed = urlsplit(url)
188
+ source = Path(url2pathname(url, require_scheme=True))
189
+ if parsed.query or parsed.fragment or not source.is_absolute():
190
+ raise ValueError("Invalid editable source URL")
191
+ source = source.resolve()
192
+ status.path = str(source)
193
+ status.found = source.is_dir() and (
194
+ root is None or os.path.normcase(str(source)) == os.path.normcase(str(root))
195
+ )
196
+ except PackageNotFoundError:
197
+ return status
198
+ except OSError, TypeError, ValueError, UnicodeError, RuntimeError:
199
+ status.found = False
200
+ return status
201
+
202
+
165
203
  def _check_path_profile() -> DependencyStatus:
166
204
  """Check whether ``~/.agdt/bin`` is present as a PATH component.
167
205
 
@@ -281,12 +319,7 @@ def _check_git_hooks_config() -> DependencyStatus:
281
319
  category=_GIT_HOOKS_OPTIONAL_CATEGORY,
282
320
  )
283
321
  except subprocess.TimeoutExpired:
284
- return DependencyStatus(
285
- name="git-hooks",
286
- found=False,
287
- required=False,
288
- category=_GIT_HOOKS_OPTIONAL_CATEGORY,
289
- )
322
+ return DependencyStatus(name="git-hooks", found=False, required=False, category=_GIT_HOOKS_OPTIONAL_CATEGORY)
290
323
 
291
324
  if in_repo.returncode != 0:
292
325
  # Not in a git repo — non-blocking
@@ -308,22 +341,12 @@ def _check_git_hooks_config() -> DependencyStatus:
308
341
  )
309
342
  except FileNotFoundError, subprocess.TimeoutExpired:
310
343
  # git disappeared or timed out — treat as non-blocking (same as git-missing)
311
- return DependencyStatus(
312
- name="git-hooks",
313
- found=False,
314
- required=False,
315
- category=_GIT_HOOKS_OPTIONAL_CATEGORY,
316
- )
344
+ return DependencyStatus(name="git-hooks", found=False, required=False, category=_GIT_HOOKS_OPTIONAL_CATEGORY)
317
345
 
318
346
  if toplevel.returncode != 0:
319
347
  # show-toplevel failed (e.g. detached HEAD, bare repo, or unexpected error)
320
348
  # — cannot validate .githooks dir; treat as non-blocking
321
- return DependencyStatus(
322
- name="git-hooks",
323
- found=False,
324
- required=False,
325
- category=_GIT_HOOKS_OPTIONAL_CATEGORY,
326
- )
349
+ return DependencyStatus(name="git-hooks", found=False, required=False, category=_GIT_HOOKS_OPTIONAL_CATEGORY)
327
350
 
328
351
  repo_root = Path(toplevel.stdout.strip())
329
352
 
@@ -337,12 +360,7 @@ def _check_git_hooks_config() -> DependencyStatus:
337
360
  )
338
361
  except FileNotFoundError, subprocess.TimeoutExpired:
339
362
  # git disappeared or timed out — treat as non-blocking
340
- return DependencyStatus(
341
- name="git-hooks",
342
- found=False,
343
- required=False,
344
- category=_GIT_HOOKS_OPTIONAL_CATEGORY,
345
- )
363
+ return DependencyStatus(name="git-hooks", found=False, required=False, category=_GIT_HOOKS_OPTIONAL_CATEGORY)
346
364
 
347
365
  hooks_path_set = config_result.returncode == 0
348
366
  current = config_result.stdout.strip() if hooks_path_set else ""
@@ -395,40 +413,21 @@ def check_all_dependencies() -> list[DependencyStatus]:
395
413
  A list of :class:`DependencyStatus` objects, one per tool.
396
414
  """
397
415
  results = [
398
- _check_dependency(
399
- "copilot",
400
- required=False,
401
- install_hint="run: agdt-setup-copilot-cli",
402
- category="Recommended",
403
- ),
404
- _check_dependency(
405
- "gh",
406
- required=False,
407
- install_hint="run: agdt-setup-gh-cli (or https://cli.github.com/)",
408
- category="Recommended",
409
- ),
410
- _check_dependency(
411
- "git",
412
- required=True,
413
- install_hint="https://git-scm.com/downloads",
414
- category="Required",
415
- ),
416
- _check_dependency(
417
- "az",
418
- required=False,
419
- install_hint="https://docs.microsoft.com/cli/azure/install-azure-cli",
420
- category="Optional — needed for Azure DevOps",
421
- ),
422
- _check_dependency(
423
- "code",
424
- required=False,
425
- install_hint="https://code.visualstudio.com/",
426
- category="Optional — needed for VS Code integration",
427
- ),
416
+ _check_dependency(name, required=required, install_hint=hint, category=category)
417
+ for name, required, hint, category in (
418
+ ("copilot", False, "run: agdt-setup-copilot-cli", "Recommended"),
419
+ ("gh", False, "run: agdt-setup-gh-cli (or https://cli.github.com/)", "Recommended"),
420
+ ("git", True, "https://git-scm.com/downloads", "Required"),
421
+ (
422
+ "az",
423
+ False,
424
+ "https://docs.microsoft.com/cli/azure/install-azure-cli",
425
+ "Optional — needed for Azure DevOps",
426
+ ),
427
+ ("code", False, "https://code.visualstudio.com/", "Optional — needed for VS Code integration"),
428
+ )
428
429
  ]
429
- results.append(_check_path_profile())
430
- results.append(_check_git_hooks_config())
431
- return results
430
+ return [*results, _check_path_profile(), _check_git_hooks_config(), _check_editable_install()]
432
431
 
433
432
 
434
433
  def print_dependency_report(statuses: list[DependencyStatus]) -> None:
@@ -13,7 +13,7 @@ from __future__ import annotations
13
13
 
14
14
  import time
15
15
  from collections.abc import Callable
16
- from dataclasses import dataclass, field
16
+ from dataclasses import asdict, dataclass, field
17
17
  from dataclasses import replace as _replace
18
18
  from typing import Any
19
19
 
@@ -250,7 +250,7 @@ def run_doctor(
250
250
  classified_problems: list[tuple[ErrorClass, DependencyStatus]] = []
251
251
  repair_outcomes: list[RepairOutcome] = []
252
252
  phases: list[PhaseResult] = []
253
- extra_details: dict[str, Any] = {}
253
+ extra_details: dict[str, Any] = {"dependencies": [asdict(status) for status in statuses]}
254
254
 
255
255
  # ── Phase 1: check ────────────────────────────────────────────────────────
256
256
  check_start = time.monotonic()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agentic-devtools
3
- Version: 0.2.596
3
+ Version: 0.2.597
4
4
  Summary: Agentic devtools integrate Jira, DevOps & more
5
5
  Author: ayaiayorg
6
6
  License-Expression: MIT
@@ -1,5 +1,5 @@
1
1
  agentic_devtools/__init__.py,sha256=gvLzsZ6L3Abr4sPHr4OJ_rdZDD8cFzXacaV0LGs8dVc,539
2
- agentic_devtools/_version.py,sha256=AvrHmM1z84QxURku5GjpXs4ePlchTMmZCz-bqWtaQkM,524
2
+ agentic_devtools/_version.py,sha256=3lhPeCWgBczn9fFXGxLEXEJKf9nFTnjKQ2reOlfbUiw,524
3
3
  agentic_devtools/agdt_gitignore.py,sha256=vVVqTjBZ_ijn6U3Lnh_JGrARLschYVN-fFal9jDk0Ak,2694
4
4
  agentic_devtools/background_tasks.py,sha256=sFgmqOnCdCjclABJ8V__yDwBXDyi45b1Z-MVv3G2zB8,17664
5
5
  agentic_devtools/config.py,sha256=DEVxTVZhsQbVQwO9qdB_1h19aBpjMzF6xJY_ePYLGLs,15629
@@ -555,8 +555,8 @@ agentic_devtools/cli/setup/commit_template_setup.py,sha256=3xojqN7o8uF12PfnSdtaG
555
555
  agentic_devtools/cli/setup/copilot_cli_installer.py,sha256=LoBWSfuHlyzrDMyUb8h5gOe77JLW5XSyaif_XE7PLXY,10040
556
556
  agentic_devtools/cli/setup/copilot_settings.py,sha256=hLpU4MA3dHVa0Pq19bzoSsVbF8zPaTs-He4T_uDgYpM,9854
557
557
  agentic_devtools/cli/setup/decision_log.py,sha256=KAqxWyPJLcRg2bFT2-pbx6faobo9dZktMlyuE9Qxaz4,12396
558
- agentic_devtools/cli/setup/dependency_checker.py,sha256=F8XZEAt0TtOwj50IpHxUDU7QB-9FUiZUdy-BFUY54FE,15374
559
- agentic_devtools/cli/setup/doctor.py,sha256=cDCNEaHifmJtx6qHvnqa3qRe9FuF7zb-zHxlGGTw9oE,18391
558
+ agentic_devtools/cli/setup/dependency_checker.py,sha256=ytDKcq6QepYAhGt2obHriOuOrCDgO8YzsGqt2kDJj8E,17272
559
+ agentic_devtools/cli/setup/doctor.py,sha256=z1vEDQKI4jSMu2pYLObAxiZv4c5-5SnTNWCf4ipsVJc,18454
560
560
  agentic_devtools/cli/setup/doctor_repair.py,sha256=JmlQZi6dIqke7Rzq19EfIgkbtYbE-a0DdqLYg1iyP4A,6230
561
561
  agentic_devtools/cli/setup/doctor_repairs.py,sha256=_iuruXUB9vrrhP2YcRz-dZfpIKEqWoyQ-WxtQ11YD9M,9809
562
562
  agentic_devtools/cli/setup/exit_codes.py,sha256=56ej8g1n8K5cmsuyE0eEwoITqkJLWONRsNI6DfunuVQ,2553
@@ -1305,8 +1305,8 @@ agentic_devtools/_bundled_skills/skills/speckit-plan/SKILL.md,sha256=qYLpzgLCIZ6
1305
1305
  agentic_devtools/_bundled_skills/skills/speckit-specify/SKILL.md,sha256=HbHRbdphMqbtNw6fL6NcYCj6sSFmUyk2S4U0bZ9p_l4,13681
1306
1306
  agentic_devtools/_bundled_skills/skills/write-github-commit-message/SKILL.md,sha256=Ep1lR8NDN117Iytj172VZgqazFiLpJ56Z7RXgaTnxR8,2626
1307
1307
  agentic_devtools/_bundled_skills/skills/write-github-commit-message/commit-types.md,sha256=bTy_t68ZD6R87rFIzq9wybTu8Wudoahb7nB9IWC4bFo,1839
1308
- agentic_devtools-0.2.596.dist-info/METADATA,sha256=LpdqiT1tbaT8eB4vtvWOdBDdCX5ZY7TdRs7odTvahHs,35589
1309
- agentic_devtools-0.2.596.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
1310
- agentic_devtools-0.2.596.dist-info/entry_points.txt,sha256=kL35_Y5OHI6XpPneeBTcX82ORjjfx2VIK6XfmKHgNm4,13630
1311
- agentic_devtools-0.2.596.dist-info/licenses/LICENSE,sha256=yBEDdICksxhBYLWoERKp9MTqwGnUF6Ryj9BTLwXTc6k,1082
1312
- agentic_devtools-0.2.596.dist-info/RECORD,,
1308
+ agentic_devtools-0.2.597.dist-info/METADATA,sha256=ok2PtJbjiijJ4-eakmLoG6LXGmgA-yMHJEdITp7aS1c,35589
1309
+ agentic_devtools-0.2.597.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
1310
+ agentic_devtools-0.2.597.dist-info/entry_points.txt,sha256=kL35_Y5OHI6XpPneeBTcX82ORjjfx2VIK6XfmKHgNm4,13630
1311
+ agentic_devtools-0.2.597.dist-info/licenses/LICENSE,sha256=yBEDdICksxhBYLWoERKp9MTqwGnUF6Ryj9BTLwXTc6k,1082
1312
+ agentic_devtools-0.2.597.dist-info/RECORD,,