code-aide 1.11.0__tar.gz → 1.11.1__tar.gz

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.
Files changed (50) hide show
  1. {code_aide-1.11.0 → code_aide-1.11.1}/PKG-INFO +1 -1
  2. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/__init__.py +1 -1
  3. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/commands_tools.py +1 -0
  4. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/data/tools.json +8 -4
  5. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/detection.py +8 -2
  6. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/install.py +11 -2
  7. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/operations.py +12 -10
  8. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/status.py +8 -3
  9. {code_aide-1.11.0 → code_aide-1.11.1}/tests/test_detection.py +24 -0
  10. {code_aide-1.11.0 → code_aide-1.11.1}/tests/test_install.py +16 -0
  11. {code_aide-1.11.0 → code_aide-1.11.1}/.github/workflows/ci.yml +0 -0
  12. {code_aide-1.11.0 → code_aide-1.11.1}/.github/workflows/publish.yml +0 -0
  13. {code_aide-1.11.0 → code_aide-1.11.1}/.gitignore +0 -0
  14. {code_aide-1.11.0 → code_aide-1.11.1}/.gitlab-ci.yml +0 -0
  15. {code_aide-1.11.0 → code_aide-1.11.1}/.pre-commit-config.yaml +0 -0
  16. {code_aide-1.11.0 → code_aide-1.11.1}/AGENTS.md +0 -0
  17. {code_aide-1.11.0 → code_aide-1.11.1}/CLAUDE.md +0 -0
  18. {code_aide-1.11.0 → code_aide-1.11.1}/LICENSE +0 -0
  19. {code_aide-1.11.0 → code_aide-1.11.1}/README.md +0 -0
  20. {code_aide-1.11.0 → code_aide-1.11.1}/TODO.md +0 -0
  21. {code_aide-1.11.0 → code_aide-1.11.1}/pyproject.toml +0 -0
  22. {code_aide-1.11.0 → code_aide-1.11.1}/script-archive/README.md +0 -0
  23. {code_aide-1.11.0 → code_aide-1.11.1}/script-archive/amp-install.sh +0 -0
  24. {code_aide-1.11.0 → code_aide-1.11.1}/script-archive/claude-install.sh +0 -0
  25. {code_aide-1.11.0 → code_aide-1.11.1}/script-archive/cursor-install.sh +0 -0
  26. {code_aide-1.11.0 → code_aide-1.11.1}/specs/auto-migrate-deprecated-installs.md +0 -0
  27. {code_aide-1.11.0 → code_aide-1.11.1}/specs/claude-native-installer-migration.md +0 -0
  28. {code_aide-1.11.0 → code_aide-1.11.1}/specs/missing-coding-llm-cli-tools.md +0 -0
  29. {code_aide-1.11.0 → code_aide-1.11.1}/specs/pre-commit-uv-setup.md +0 -0
  30. {code_aide-1.11.0 → code_aide-1.11.1}/specs/remove-bundled-version-baseline.md +0 -0
  31. {code_aide-1.11.0 → code_aide-1.11.1}/specs/unify-upgrade-eligibility-with-shared-evaluator.md +0 -0
  32. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/__main__.py +0 -0
  33. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/commands_actions.py +0 -0
  34. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/config.py +0 -0
  35. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/console.py +0 -0
  36. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/constants.py +0 -0
  37. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/entry.py +0 -0
  38. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/install_types.py +0 -0
  39. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/prereqs.py +0 -0
  40. {code_aide-1.11.0 → code_aide-1.11.1}/src/code_aide/versions.py +0 -0
  41. {code_aide-1.11.0 → code_aide-1.11.1}/tests/test_commands_actions.py +0 -0
  42. {code_aide-1.11.0 → code_aide-1.11.1}/tests/test_commands_tools.py +0 -0
  43. {code_aide-1.11.0 → code_aide-1.11.1}/tests/test_config.py +0 -0
  44. {code_aide-1.11.0 → code_aide-1.11.1}/tests/test_console.py +0 -0
  45. {code_aide-1.11.0 → code_aide-1.11.1}/tests/test_constants.py +0 -0
  46. {code_aide-1.11.0 → code_aide-1.11.1}/tests/test_install_types.py +0 -0
  47. {code_aide-1.11.0 → code_aide-1.11.1}/tests/test_operations.py +0 -0
  48. {code_aide-1.11.0 → code_aide-1.11.1}/tests/test_status.py +0 -0
  49. {code_aide-1.11.0 → code_aide-1.11.1}/tests/test_versions.py +0 -0
  50. {code_aide-1.11.0 → code_aide-1.11.1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-aide
3
- Version: 1.11.0
3
+ Version: 1.11.1
4
4
  Summary: Manage AI coding CLI tools (Claude, Copilot, Cursor, Gemini, Amp, Codex)
5
5
  Project-URL: Homepage, https://github.com/dajobe/code-aide
6
6
  Project-URL: Repository, https://github.com/dajobe/code-aide
@@ -1,3 +1,3 @@
1
1
  """code-aide - Manage AI coding CLI tools."""
2
2
 
3
- __version__ = "1.11.0"
3
+ __version__ = "1.11.1"
@@ -257,6 +257,7 @@ def cmd_status(args: argparse.Namespace) -> None:
257
257
  status["version"],
258
258
  assessment.latest_version,
259
259
  assessment.package_info,
260
+ repo=tool_config.get("freebsd_pkg_repo"),
260
261
  )
261
262
  elif assessment.latest_version:
262
263
  if assessment.version_state == VersionDisplayState.UP_TO_DATE:
@@ -37,7 +37,8 @@
37
37
  ],
38
38
  "docs_url": "https://code.claude.com/docs/en/setup",
39
39
  "default_install": true,
40
- "freebsd_port": "claude-code"
40
+ "freebsd_port": "claude-code",
41
+ "freebsd_pkg_repo": "FreeBSD-latest"
41
42
  },
42
43
  "gemini": {
43
44
  "name": "Gemini CLI",
@@ -54,7 +55,8 @@
54
55
  ],
55
56
  "docs_url": "https://github.com/google-gemini/gemini-cli",
56
57
  "default_install": true,
57
- "freebsd_port": "gemini-cli"
58
+ "freebsd_port": "gemini-cli",
59
+ "freebsd_pkg_repo": "FreeBSD-latest"
58
60
  },
59
61
  "amp": {
60
62
  "name": "Amp (Sourcegraph)",
@@ -87,7 +89,8 @@
87
89
  ],
88
90
  "docs_url": "https://github.com/openai/codex",
89
91
  "default_install": false,
90
- "freebsd_port": "codex"
92
+ "freebsd_port": "codex",
93
+ "freebsd_pkg_repo": "FreeBSD-latest"
91
94
  },
92
95
  "copilot": {
93
96
  "name": "Copilot CLI",
@@ -104,7 +107,8 @@
104
107
  ],
105
108
  "docs_url": "https://github.com/github/copilot-cli",
106
109
  "default_install": false,
107
- "freebsd_port": "github-copilot-cli"
110
+ "freebsd_port": "github-copilot-cli",
111
+ "freebsd_pkg_repo": "FreeBSD-latest"
108
112
  },
109
113
  "opencode": {
110
114
  "name": "OpenCode",
@@ -290,7 +290,9 @@ def get_brew_package_info(
290
290
  return result
291
291
 
292
292
 
293
- def get_pkg_package_info(package_name: str) -> PackageVersionInfo:
293
+ def get_pkg_package_info(
294
+ package_name: str, repo: Optional[str] = None
295
+ ) -> PackageVersionInfo:
294
296
  """Get package version info for a FreeBSD pkg-installed tool."""
295
297
  result: PackageVersionInfo = {
296
298
  "package": package_name,
@@ -318,8 +320,12 @@ def get_pkg_package_info(package_name: str) -> PackageVersionInfo:
318
320
  pass
319
321
 
320
322
  try:
323
+ rquery_cmd = ["pkg", "rquery"]
324
+ if repo:
325
+ rquery_cmd.extend(["-r", repo])
326
+ rquery_cmd.extend(["%v", package_name])
321
327
  proc = subprocess.run(
322
- ["pkg", "rquery", "%v", package_name],
328
+ rquery_cmd,
323
329
  capture_output=True,
324
330
  text=True,
325
331
  timeout=10,
@@ -260,11 +260,20 @@ def install_tool(tool_name: str, dryrun: bool = False, force: bool = False) -> b
260
260
  if not freebsd_port:
261
261
  error(f"{tool_config['name']} is not available on FreeBSD (no port exists)")
262
262
  return False
263
+ pkg_repo = tool_config.get("freebsd_pkg_repo")
263
264
  if dryrun:
264
- info(f"[DRYRUN] Would install FreeBSD port: pkg install {freebsd_port}")
265
+ repo_flag = f" -r {pkg_repo}" if pkg_repo else ""
266
+ info(
267
+ f"[DRYRUN] Would install FreeBSD port: "
268
+ f"pkg install{repo_flag} {freebsd_port}"
269
+ )
265
270
  return True
266
271
  try:
267
- run_command(["sudo", "pkg", "install", "-y", freebsd_port], check=True)
272
+ cmd = ["sudo", "pkg", "install", "-y"]
273
+ if pkg_repo:
274
+ cmd.extend(["-r", pkg_repo])
275
+ cmd.append(freebsd_port)
276
+ run_command(cmd, check=True)
268
277
  success(f"{tool_config['name']} installed successfully via FreeBSD pkg")
269
278
  info(tool_config["next_steps"])
270
279
  if "docs_url" in tool_config:
@@ -195,11 +195,12 @@ def upgrade_tool(tool_name: str) -> UpgradeResult:
195
195
  if not pkg_name:
196
196
  error(f"No FreeBSD port configured for {tool_config['name']}")
197
197
  return UpgradeResult.FAILED
198
- run_command(
199
- ["sudo", "pkg", "upgrade", "-y", pkg_name],
200
- check=True,
201
- capture=False,
202
- )
198
+ cmd = ["sudo", "pkg", "upgrade", "-y"]
199
+ pkg_repo = tool_config.get("freebsd_pkg_repo")
200
+ if pkg_repo:
201
+ cmd.extend(["-r", pkg_repo])
202
+ cmd.append(pkg_name)
203
+ run_command(cmd, check=True, capture=False)
203
204
 
204
205
  elif method == InstallMethod.SYSTEM:
205
206
  error(
@@ -343,11 +344,12 @@ def remove_tool(tool_name: str) -> bool:
343
344
  if not pkg_name:
344
345
  error(f"No FreeBSD port configured for {tool_config['name']}")
345
346
  return False
346
- run_command(
347
- ["sudo", "pkg", "delete", "-y", pkg_name],
348
- check=True,
349
- capture=False,
350
- )
347
+ cmd = ["sudo", "pkg", "delete", "-y"]
348
+ pkg_repo = tool_config.get("freebsd_pkg_repo")
349
+ if pkg_repo:
350
+ cmd.extend(["-r", pkg_repo])
351
+ cmd.append(pkg_name)
352
+ run_command(cmd, check=True, capture=False)
351
353
  success(f"{tool_config['name']} removed successfully")
352
354
 
353
355
  elif method == InstallMethod.SYSTEM:
@@ -251,7 +251,10 @@ class ToolUpgradeEvaluator:
251
251
  pkg_name = install_info.get("detail") or self.tool_config.get(
252
252
  "freebsd_port"
253
253
  )
254
- self._package_info = get_pkg_package_info(pkg_name) if pkg_name else None
254
+ pkg_repo = self.tool_config.get("freebsd_pkg_repo")
255
+ self._package_info = (
256
+ get_pkg_package_info(pkg_name, repo=pkg_repo) if pkg_name else None
257
+ )
255
258
  elif method == InstallMethod.SYSTEM:
256
259
  tool_path = self._tool_path or shutil.which(self.tool_config["command"])
257
260
  self._package_info = (
@@ -396,6 +399,7 @@ def print_pkg_version_status(
396
399
  cli_version: str,
397
400
  latest_version: Optional[str],
398
401
  pkg_info: PackageInfo,
402
+ repo: Optional[str] = None,
399
403
  ) -> None:
400
404
  """Print version status for a FreeBSD pkg-managed tool."""
401
405
  avail_ver = pkg_info.get("available_version")
@@ -411,6 +415,7 @@ def print_pkg_version_status(
411
415
 
412
416
  if avail_ver:
413
417
  pkg_name = pkg_info.get("package") or "FreeBSD pkg"
418
+ repo_suffix = f", {repo}" if repo else ""
414
419
  show_upstream = (
415
420
  latest_version
416
421
  and not status_version_matches_latest(avail_ver, latest_version)
@@ -420,11 +425,11 @@ def print_pkg_version_status(
420
425
  )
421
426
  if show_upstream:
422
427
  print(
423
- f" Packaged: {avail_ver} ({pkg_name}) "
428
+ f" Packaged: {avail_ver} ({pkg_name}{repo_suffix}) "
424
429
  f"{Colors.YELLOW}(upstream: {latest_version}){Colors.NC}"
425
430
  )
426
431
  else:
427
- print(f" Packaged: {avail_ver} ({pkg_name})")
432
+ print(f" Packaged: {avail_ver} ({pkg_name}{repo_suffix})")
428
433
 
429
434
 
430
435
  def get_tool_status(tool_name: str, tool_config: Dict[str, Any]) -> ToolStatus:
@@ -218,6 +218,30 @@ class TestGetPkgPackageInfo(unittest.TestCase):
218
218
  self.assertEqual(result["available_version"], "2.1.63")
219
219
  self.assertFalse(result["outdated"])
220
220
 
221
+ @mock.patch.object(cli_detection, "command_exists", return_value=True)
222
+ @mock.patch.object(cli_detection.subprocess, "run")
223
+ def test_repo_passes_r_flag_to_rquery(self, mock_run, mock_cmd):
224
+ calls = []
225
+
226
+ def side_effect(cmd, **kwargs):
227
+ calls.append(list(cmd))
228
+ result = mock.Mock()
229
+ result.returncode = 0
230
+ result.stdout = "2.1.63\n"
231
+ return result
232
+
233
+ mock_run.side_effect = side_effect
234
+
235
+ cli_detection.get_pkg_package_info("claude-code", repo="FreeBSD-latest")
236
+
237
+ # pkg query (local) should NOT have -r
238
+ self.assertEqual(calls[0], ["pkg", "query", "%v", "claude-code"])
239
+ # pkg rquery (remote) should have -r
240
+ self.assertEqual(
241
+ calls[1],
242
+ ["pkg", "rquery", "-r", "FreeBSD-latest", "%v", "claude-code"],
243
+ )
244
+
221
245
 
222
246
  class TestFormatInstallMethodSystem(unittest.TestCase):
223
247
  """Tests for format_install_method with system method."""
@@ -99,6 +99,22 @@ class TestInstallToolFreeBSD(unittest.TestCase):
99
99
  ["sudo", "pkg", "install", "-y", "test-tool-port"], check=True
100
100
  )
101
101
 
102
+ @mock.patch.object(cli_install.platform, "system", return_value="FreeBSD")
103
+ @mock.patch.object(cli_install, "command_exists", return_value=False)
104
+ @mock.patch.object(cli_install, "run_command")
105
+ def test_freebsd_with_repo_passes_r_flag(self, mock_run, mock_cmd, mock_sys):
106
+ tool_config = self._make_tool_config(
107
+ freebsd_port="test-tool-port",
108
+ freebsd_pkg_repo="FreeBSD-latest",
109
+ )
110
+ with mock.patch.dict(cli_install.TOOLS, {"test": tool_config}, clear=True):
111
+ result = cli_install.install_tool("test")
112
+ self.assertTrue(result)
113
+ mock_run.assert_called_once_with(
114
+ ["sudo", "pkg", "install", "-y", "-r", "FreeBSD-latest", "test-tool-port"],
115
+ check=True,
116
+ )
117
+
102
118
 
103
119
  class TestExtractTarMember(unittest.TestCase):
104
120
  """Tests for extract_tar_member."""
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes