agsekit 1.7.2__tar.gz → 1.7.4__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 (201) hide show
  1. {agsekit-1.7.2/agsekit.egg-info → agsekit-1.7.4}/PKG-INFO +1 -1
  2. {agsekit-1.7.2 → agsekit-1.7.4/agsekit.egg-info}/PKG-INFO +1 -1
  3. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit.egg-info/SOURCES.txt +4 -0
  4. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/agent_scripts/codex-glibc.sh +29 -2
  5. agsekit-1.7.4/agsekit_cli/agent_version_sources.py +90 -0
  6. agsekit-1.7.4/agsekit_cli/agents_modules/aider.py +14 -0
  7. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/agents_modules/base.py +6 -0
  8. agsekit-1.7.4/agsekit_cli/agents_modules/claude.py +15 -0
  9. agsekit-1.7.4/agsekit_cli/agents_modules/cline.py +15 -0
  10. agsekit-1.7.4/agsekit_cli/agents_modules/codex.py +14 -0
  11. agsekit-1.7.4/agsekit_cli/agents_modules/codex_glibc.py +15 -0
  12. agsekit-1.7.4/agsekit_cli/agents_modules/codex_glibc_prebuilt.py +23 -0
  13. agsekit-1.7.4/agsekit_cli/agents_modules/forgecode.py +16 -0
  14. agsekit-1.7.4/agsekit_cli/agents_modules/opencode.py +15 -0
  15. agsekit-1.7.4/agsekit_cli/agents_modules/qwen.py +14 -0
  16. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/agents/codex-glibc-prebuilt.yml +4 -2
  17. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/agents/codex-glibc.yml +20 -3
  18. agsekit-1.7.4/agsekit_cli/ansible/agents/codex_code_mode_host.yml +52 -0
  19. agsekit-1.7.4/agsekit_cli/codex_rust_toolchain_version.txt +1 -0
  20. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/check_new_version.py +4 -4
  21. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/daemon.py +1 -1
  22. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/install_agents.py +51 -7
  23. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/locales/en.json +45 -38
  24. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/locales/ru.json +40 -33
  25. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/prepare_strategies.py +96 -3
  26. agsekit-1.7.4/agsekit_cli/state.py +356 -0
  27. {agsekit-1.7.2 → agsekit-1.7.4}/prebuilt-agents/codex-glibc/Dockerfile +5 -1
  28. {agsekit-1.7.2 → agsekit-1.7.4}/prebuilt-agents/codex-glibc/build-codex-glibc.sh +23 -1
  29. {agsekit-1.7.2 → agsekit-1.7.4}/prebuilt-agents/codex-glibc/build.sh +15 -5
  30. {agsekit-1.7.2 → agsekit-1.7.4}/pyproject.toml +2 -1
  31. agsekit-1.7.4/tests/test_agent_latest_versions.py +95 -0
  32. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_ansible_agent_proxychains.py +32 -1
  33. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_daemon_command.py +2 -2
  34. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_install_agents_command.py +125 -4
  35. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_node_agent_installers.py +37 -1
  36. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_prepare_command.py +104 -3
  37. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_state.py +88 -0
  38. agsekit-1.7.2/agsekit_cli/agents_modules/aider.py +0 -8
  39. agsekit-1.7.2/agsekit_cli/agents_modules/claude.py +0 -9
  40. agsekit-1.7.2/agsekit_cli/agents_modules/cline.py +0 -9
  41. agsekit-1.7.2/agsekit_cli/agents_modules/codex.py +0 -8
  42. agsekit-1.7.2/agsekit_cli/agents_modules/codex_glibc.py +0 -7
  43. agsekit-1.7.2/agsekit_cli/agents_modules/codex_glibc_prebuilt.py +0 -7
  44. agsekit-1.7.2/agsekit_cli/agents_modules/forgecode.py +0 -8
  45. agsekit-1.7.2/agsekit_cli/agents_modules/opencode.py +0 -9
  46. agsekit-1.7.2/agsekit_cli/agents_modules/qwen.py +0 -8
  47. agsekit-1.7.2/agsekit_cli/state.py +0 -197
  48. {agsekit-1.7.2 → agsekit-1.7.4}/LICENSE +0 -0
  49. {agsekit-1.7.2 → agsekit-1.7.4}/MANIFEST.in +0 -0
  50. {agsekit-1.7.2 → agsekit-1.7.4}/README.md +0 -0
  51. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit.egg-info/dependency_links.txt +0 -0
  52. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit.egg-info/entry_points.txt +0 -0
  53. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit.egg-info/requires.txt +0 -0
  54. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit.egg-info/top_level.txt +0 -0
  55. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/__init__.py +0 -0
  56. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/agent_scripts/claude-code.sh +0 -0
  57. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/agent_scripts/codex.sh +0 -0
  58. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/agent_scripts/proxychains_common.sh +0 -0
  59. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/agent_scripts/qwen.sh +0 -0
  60. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/agents.py +0 -0
  61. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/agents_modules/__init__.py +0 -0
  62. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/agents/aider.yml +0 -0
  63. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/agents/claude.yml +0 -0
  64. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/agents/cline.yml +0 -0
  65. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/agents/codex.yml +0 -0
  66. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/agents/codex_logrotate.yml +0 -0
  67. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/agents/forgecode.yml +0 -0
  68. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/agents/opencode.yml +0 -0
  69. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/agents/proxychains.yml +0 -0
  70. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/agents/qwen.yml +0 -0
  71. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/bundles/docker.yml +0 -0
  72. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/bundles/golang.yml +0 -0
  73. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/bundles/nodejs.yml +0 -0
  74. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/bundles/nvm.yml +0 -0
  75. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/bundles/pyenv.yml +0 -0
  76. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/bundles/python.yml +0 -0
  77. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/bundles/rust.yml +0 -0
  78. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/callback_plugins/agsekit_progress.py +0 -0
  79. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/callback_plugins/agsekit_rich.py +0 -0
  80. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/connection_plugins/agsekit_multipass.py +0 -0
  81. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/vm_packages.yml +0 -0
  82. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible/vm_ssh.yml +0 -0
  83. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible_runners.py +0 -0
  84. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/ansible_utils.py +0 -0
  85. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/backup.py +0 -0
  86. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/cli.py +0 -0
  87. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/cli_entry.py +0 -0
  88. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/__init__.py +0 -0
  89. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/addmount.py +0 -0
  90. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/backup_clean.py +0 -0
  91. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/backup_once.py +0 -0
  92. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/backup_repeated.py +0 -0
  93. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/config_example.py +0 -0
  94. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/config_gen.py +0 -0
  95. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/create_vm.py +0 -0
  96. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/destroy_vm.py +0 -0
  97. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/doctor.py +0 -0
  98. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/down.py +0 -0
  99. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/list_bundles.py +0 -0
  100. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/mounts.py +0 -0
  101. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/pip_upgrade.py +0 -0
  102. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/portforward.py +0 -0
  103. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/prepare.py +0 -0
  104. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/removemount.py +0 -0
  105. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/restart_vm.py +0 -0
  106. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/run.py +0 -0
  107. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/shell.py +0 -0
  108. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/ssh.py +0 -0
  109. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/start_vm.py +0 -0
  110. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/status.py +0 -0
  111. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/stop.py +0 -0
  112. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/systemd.py +0 -0
  113. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/up.py +0 -0
  114. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/commands/version.py +0 -0
  115. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/config.py +0 -0
  116. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/daemon_backends.py +0 -0
  117. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/debug.py +0 -0
  118. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/host_tools.py +0 -0
  119. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/i18n.py +0 -0
  120. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/interactive.py +0 -0
  121. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/mounts.py +0 -0
  122. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/prebuilt.py +0 -0
  123. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/progress.py +0 -0
  124. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/provision_handlers.py +0 -0
  125. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/run_agent.sh +0 -0
  126. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/run_with_http_proxy.sh +0 -0
  127. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/run_with_proxychains.sh +0 -0
  128. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/systemd/agsekit-portforward.service +0 -0
  129. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/systemd_backend.py +0 -0
  130. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/tui_prompts.py +0 -0
  131. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/versioning.py +0 -0
  132. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/vm.py +0 -0
  133. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/vm_bundle_definitions.py +0 -0
  134. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/vm_bundles.py +0 -0
  135. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/vm_installers/docker.sh +0 -0
  136. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/vm_installers/golang.sh +0 -0
  137. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/vm_installers/nodejs.sh +0 -0
  138. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/vm_installers/nvm.sh +0 -0
  139. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/vm_installers/pyenv.sh +0 -0
  140. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/vm_installers/python.sh +0 -0
  141. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/vm_installers/rust.sh +0 -0
  142. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/vm_local_control_node.py +0 -0
  143. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/vm_prepare.py +0 -0
  144. {agsekit-1.7.2 → agsekit-1.7.4}/agsekit_cli/vm_ssh_bootstrap.py +0 -0
  145. {agsekit-1.7.2 → agsekit-1.7.4}/config-example.yaml +0 -0
  146. {agsekit-1.7.2 → agsekit-1.7.4}/prebuilt-agents/codex-glibc/.dockerignore +0 -0
  147. {agsekit-1.7.2 → agsekit-1.7.4}/setup.cfg +0 -0
  148. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_addmount_command.py +0 -0
  149. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_agents.py +0 -0
  150. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_agents_modules.py +0 -0
  151. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_ansible_multipass_connection.py +0 -0
  152. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_ansible_utils.py +0 -0
  153. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_ansible_vm_bundles.py +0 -0
  154. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_backup_clean_command.py +0 -0
  155. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_backup_lock.py +0 -0
  156. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_backup_progress.py +0 -0
  157. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_backup_repeated.py +0 -0
  158. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_backup_repeated_commands.py +0 -0
  159. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_build_backfill_github_releases.py +0 -0
  160. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_build_check_pypi_version.py +0 -0
  161. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_build_extract_changelog.py +0 -0
  162. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_check_new_version_command.py +0 -0
  163. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_codex_logrotate_installers.py +0 -0
  164. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_config_agents.py +0 -0
  165. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_config_gen_command.py +0 -0
  166. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_config_main.py +0 -0
  167. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_config_mounts.py +0 -0
  168. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_config_vms.py +0 -0
  169. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_create_vm_command.py +0 -0
  170. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_debug.py +0 -0
  171. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_doctor_command.py +0 -0
  172. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_down_command.py +0 -0
  173. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_host_tools.py +0 -0
  174. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_i18n.py +0 -0
  175. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_install_script.py +0 -0
  176. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_interactive_mode.py +0 -0
  177. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_launchd_backend.py +0 -0
  178. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_make_single_backup.py +0 -0
  179. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_mount_commands.py +0 -0
  180. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_mounts.py +0 -0
  181. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_pip_upgrade_command.py +0 -0
  182. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_portforward.py +0 -0
  183. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_portforward_command.py +0 -0
  184. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_prebuilt.py +0 -0
  185. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_progress.py +0 -0
  186. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_provision_handlers.py +0 -0
  187. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_removemount_command.py +0 -0
  188. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_restart_vm_command.py +0 -0
  189. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_run_command.py +0 -0
  190. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_shell_command.py +0 -0
  191. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_ssh_command.py +0 -0
  192. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_start_vm_command.py +0 -0
  193. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_status_command.py +0 -0
  194. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_stop_vm_command.py +0 -0
  195. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_systemd_command.py +0 -0
  196. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_up_command.py +0 -0
  197. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_version_command.py +0 -0
  198. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_vm_compare.py +0 -0
  199. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_vm_launch.py +0 -0
  200. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_vm_local_control_node.py +0 -0
  201. {agsekit-1.7.2 → agsekit-1.7.4}/tests/test_vm_proxychains.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agsekit
3
- Version: 1.7.2
3
+ Version: 1.7.4
4
4
  Summary: Agent Safety Kit command-line utilities
5
5
  Author-email: Mihanentalpo <mihanentalpo@yandex.ru>
6
6
  License: MIT License
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agsekit
3
- Version: 1.7.2
3
+ Version: 1.7.4
4
4
  Summary: Agent Safety Kit command-line utilities
5
5
  Author-email: Mihanentalpo <mihanentalpo@yandex.ru>
6
6
  License: MIT License
@@ -10,12 +10,14 @@ agsekit.egg-info/entry_points.txt
10
10
  agsekit.egg-info/requires.txt
11
11
  agsekit.egg-info/top_level.txt
12
12
  agsekit_cli/__init__.py
13
+ agsekit_cli/agent_version_sources.py
13
14
  agsekit_cli/agents.py
14
15
  agsekit_cli/ansible_runners.py
15
16
  agsekit_cli/ansible_utils.py
16
17
  agsekit_cli/backup.py
17
18
  agsekit_cli/cli.py
18
19
  agsekit_cli/cli_entry.py
20
+ agsekit_cli/codex_rust_toolchain_version.txt
19
21
  agsekit_cli/config.py
20
22
  agsekit_cli/daemon_backends.py
21
23
  agsekit_cli/debug.py
@@ -64,6 +66,7 @@ agsekit_cli/ansible/agents/cline.yml
64
66
  agsekit_cli/ansible/agents/codex-glibc-prebuilt.yml
65
67
  agsekit_cli/ansible/agents/codex-glibc.yml
66
68
  agsekit_cli/ansible/agents/codex.yml
69
+ agsekit_cli/ansible/agents/codex_code_mode_host.yml
67
70
  agsekit_cli/ansible/agents/codex_logrotate.yml
68
71
  agsekit_cli/ansible/agents/forgecode.yml
69
72
  agsekit_cli/ansible/agents/opencode.yml
@@ -124,6 +127,7 @@ prebuilt-agents/codex-glibc/Dockerfile
124
127
  prebuilt-agents/codex-glibc/build-codex-glibc.sh
125
128
  prebuilt-agents/codex-glibc/build.sh
126
129
  tests/test_addmount_command.py
130
+ tests/test_agent_latest_versions.py
127
131
  tests/test_agents.py
128
132
  tests/test_agents_modules.py
129
133
  tests/test_ansible_agent_proxychains.py
@@ -88,6 +88,13 @@ trap cleanup EXIT INT TERM
88
88
 
89
89
  echo "Building Codex agent with glibc toolchain..."
90
90
 
91
+ RUST_TOOLCHAIN_FILE="$SCRIPT_DIR/../codex_rust_toolchain_version.txt"
92
+ RUST_TOOLCHAIN="$(tr -d '[:space:]' < "$RUST_TOOLCHAIN_FILE")"
93
+ if [ -z "$RUST_TOOLCHAIN" ]; then
94
+ echo "Rust toolchain version file is empty: $RUST_TOOLCHAIN_FILE" >&2
95
+ exit 1
96
+ fi
97
+
91
98
  ensure_swap_for_build
92
99
 
93
100
  sudo apt-get update -y
@@ -100,11 +107,13 @@ if ! command -v rustup >/dev/null 2>&1; then
100
107
  run_with_proxychains curl --proto '=https' --tlsv1.2 -fL https://sh.rustup.rs -o "$RUSTUP_INSTALLER"
101
108
  echo "Running rustup installer in batch mode (-y)..."
102
109
  export RUSTUP_INIT_SKIP_PATH_CHECK=yes
103
- ( set -x; sh "$RUSTUP_INSTALLER" -y --no-modify-path )
110
+ ( set -x; sh "$RUSTUP_INSTALLER" -y --default-toolchain "$RUST_TOOLCHAIN" --no-modify-path )
104
111
  rm -f "$RUSTUP_INSTALLER"
105
112
  echo "Rustup installation finished."
106
113
  fi
107
114
 
115
+ run_with_proxychains rustup toolchain install "$RUST_TOOLCHAIN" --profile minimal
116
+
108
117
  if [ -f "$HOME/.cargo/env" ]; then
109
118
  # shellcheck disable=SC1090
110
119
  . "$HOME/.cargo/env"
@@ -128,6 +137,24 @@ BUILD_ROOT="$(mktemp -d -t codex-src-XXXXXX)"
128
137
  echo "Cloning codex repository..."
129
138
  run_with_proxychains git clone --depth 1 https://github.com/openai/codex.git "$BUILD_ROOT/codex"
130
139
 
140
+ # Recent upstream Codex releases can exceed rustc's default query-depth limit
141
+ # while compiling codex-exec. Apply this only to the temporary checkout.
142
+ CODEX_EXEC_LIB=""
143
+ while IFS= read -r manifest; do
144
+ if grep -q '^name = "codex-exec"' "$manifest"; then
145
+ candidate="$(dirname "$manifest")/src/lib.rs"
146
+ if [ -f "$candidate" ]; then
147
+ CODEX_EXEC_LIB="$candidate"
148
+ break
149
+ fi
150
+ fi
151
+ done < <(find "$BUILD_ROOT/codex" -type f -name Cargo.toml -print)
152
+
153
+ if [ -n "$CODEX_EXEC_LIB" ] && ! grep -qF '#![recursion_limit = "256"]' "$CODEX_EXEC_LIB"; then
154
+ sed -i '1i#![recursion_limit = "256"]' "$CODEX_EXEC_LIB"
155
+ echo "Applied rustc recursion limit workaround to $CODEX_EXEC_LIB"
156
+ fi
157
+
131
158
  MANIFEST_PATH="$(
132
159
  python3 - "$BUILD_ROOT/codex" <<'PYCODE'
133
160
  import pathlib
@@ -179,7 +206,7 @@ export CARGO_BUILD_JOBS=1
179
206
  export CARGO_PROFILE_RELEASE_LTO=off
180
207
  export CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1
181
208
  export CARGO_PROFILE_RELEASE_DEBUG=false
182
- run_with_proxychains cargo build --release --target "$HOST_TARGET" --manifest-path "$MANIFEST_PATH"
209
+ run_with_proxychains cargo +"$RUST_TOOLCHAIN" build --release --target "$HOST_TARGET" --manifest-path "$MANIFEST_PATH"
183
210
  cleanup_swap
184
211
 
185
212
  BUILT_BINARY="$CARGO_TARGET_DIR/$HOST_TARGET/release/codex"
@@ -0,0 +1,90 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import os
5
+ from typing import Any, Dict, Iterable, Optional
6
+ from urllib.error import HTTPError, URLError
7
+ from urllib.parse import quote
8
+ from urllib.request import Request, urlopen
9
+
10
+ from packaging.version import InvalidVersion, Version
11
+
12
+
13
+ class AgentVersionCheckError(RuntimeError):
14
+ """Raised when an upstream agent version cannot be resolved."""
15
+
16
+
17
+ def _headers() -> Dict[str, str]:
18
+ headers = {"Accept": "application/json", "User-Agent": "agsekit-agent-version-check"}
19
+ token = os.getenv("AGSEKIT_GITHUB_TOKEN") or os.getenv("GITHUB_TOKEN")
20
+ if token:
21
+ headers["Authorization"] = f"Bearer {token}"
22
+ return headers
23
+
24
+
25
+ def fetch_json(url: str, *, timeout: float = 30.0) -> Any:
26
+ request = Request(url, headers=_headers())
27
+ try:
28
+ with urlopen(request, timeout=timeout) as response:
29
+ return json.load(response)
30
+ except HTTPError as exc:
31
+ raise AgentVersionCheckError(f"Version request failed for {url}: HTTP {exc.code}") from exc
32
+ except URLError as exc:
33
+ raise AgentVersionCheckError(f"Version request failed for {url}: {exc.reason}") from exc
34
+ except (OSError, ValueError) as exc:
35
+ raise AgentVersionCheckError(f"Invalid version response from {url}: {exc}") from exc
36
+
37
+
38
+ def latest_npm_version(package_name: str, *, timeout: float = 30.0) -> str:
39
+ payload = fetch_json(
40
+ f"https://registry.npmjs.org/{quote(package_name, safe='')}/latest",
41
+ timeout=timeout,
42
+ )
43
+ version = payload.get("version") if isinstance(payload, dict) else None
44
+ if not isinstance(version, str) or not version.strip():
45
+ raise AgentVersionCheckError(f"npm did not report a latest version for {package_name}")
46
+ return version.strip()
47
+
48
+
49
+ def latest_pypi_version(package_name: str, *, timeout: float = 30.0) -> str:
50
+ payload = fetch_json(f"https://pypi.org/pypi/{quote(package_name, safe='')}/json", timeout=timeout)
51
+ info = payload.get("info") if isinstance(payload, dict) else None
52
+ version = info.get("version") if isinstance(info, dict) else None
53
+ if not isinstance(version, str) or not version.strip():
54
+ raise AgentVersionCheckError(f"PyPI did not report a latest version for {package_name}")
55
+ return version.strip()
56
+
57
+
58
+ def _stable_versions(values: Iterable[str]) -> Iterable[Version]:
59
+ for value in values:
60
+ try:
61
+ parsed = Version(value)
62
+ except InvalidVersion:
63
+ continue
64
+ if not parsed.is_prerelease and not parsed.is_devrelease:
65
+ yield parsed
66
+
67
+
68
+ def latest_github_release_version(
69
+ repo: str,
70
+ *,
71
+ tag_prefix: str,
72
+ timeout: float = 30.0,
73
+ ) -> str:
74
+ payload = fetch_json(f"https://api.github.com/repos/{repo}/releases?per_page=100", timeout=timeout)
75
+ if not isinstance(payload, list):
76
+ raise AgentVersionCheckError(f"GitHub did not report releases for {repo}")
77
+
78
+ candidates = []
79
+ for release in payload:
80
+ if not isinstance(release, dict) or release.get("draft") or release.get("prerelease"):
81
+ continue
82
+ tag = release.get("tag_name")
83
+ if not isinstance(tag, str) or not tag.startswith(tag_prefix):
84
+ continue
85
+ candidates.append(tag[len(tag_prefix):])
86
+
87
+ versions = list(_stable_versions(candidates))
88
+ if not versions:
89
+ raise AgentVersionCheckError(f"GitHub did not report a stable {tag_prefix} release for {repo}")
90
+ return str(max(versions))
@@ -0,0 +1,14 @@
1
+ from .base import BaseAgent
2
+ from ..agent_version_sources import latest_pypi_version
3
+
4
+
5
+ class AiderAgent(BaseAgent):
6
+ type_name = "aider"
7
+ runtime_binary = "aider"
8
+ default_version = "0.86.2"
9
+ default_env = {"AIDER_CHECK_UPDATE": "false"}
10
+
11
+ @classmethod
12
+ def check_latest_version(cls, *, architecture=None, timeout=30.0):
13
+ del architecture
14
+ return cls.normalize_version(latest_pypi_version("aider-chat", timeout=timeout))
@@ -33,6 +33,12 @@ class BaseAgent:
33
33
  def needs_nvm(cls) -> bool:
34
34
  return bool(cls._needs_nvm)
35
35
 
36
+ @classmethod
37
+ def check_latest_version(cls, *, architecture: Optional[str] = None, timeout: float = 30.0) -> str:
38
+ del architecture
39
+ del timeout
40
+ raise NotImplementedError(f"Latest-version lookup is not implemented for {cls.type_name}")
41
+
36
42
  @classmethod
37
43
  def playbook_name(cls) -> str:
38
44
  if cls.installer_playbook:
@@ -0,0 +1,15 @@
1
+ from .base import BaseAgent
2
+ from ..agent_version_sources import latest_npm_version
3
+
4
+
5
+ class ClaudeAgent(BaseAgent):
6
+ type_name = "claude"
7
+ runtime_binary = "claude"
8
+ default_version = "2.1.141"
9
+ default_env = {"DISABLE_AUTOUPDATER": "1"}
10
+ _needs_nvm = True
11
+
12
+ @classmethod
13
+ def check_latest_version(cls, *, architecture=None, timeout=30.0):
14
+ del architecture
15
+ return cls.normalize_version(latest_npm_version("@anthropic-ai/claude-code", timeout=timeout))
@@ -0,0 +1,15 @@
1
+ from .base import BaseAgent
2
+ from ..agent_version_sources import latest_npm_version
3
+
4
+
5
+ class ClineAgent(BaseAgent):
6
+ type_name = "cline"
7
+ runtime_binary = "cline"
8
+ default_version = "2.17.0"
9
+ default_env = {"CLINE_NO_AUTO_UPDATE": "1"}
10
+ _needs_nvm = True
11
+
12
+ @classmethod
13
+ def check_latest_version(cls, *, architecture=None, timeout=30.0):
14
+ del architecture
15
+ return cls.normalize_version(latest_npm_version("cline", timeout=timeout))
@@ -0,0 +1,14 @@
1
+ from .base import BaseAgent
2
+ from ..agent_version_sources import latest_npm_version
3
+
4
+
5
+ class CodexAgent(BaseAgent):
6
+ type_name = "codex"
7
+ runtime_binary = "codex"
8
+ default_version = "0.130.0"
9
+ _needs_nvm = True
10
+
11
+ @classmethod
12
+ def check_latest_version(cls, *, architecture=None, timeout=30.0):
13
+ del architecture
14
+ return cls.normalize_version(latest_npm_version("@openai/codex", timeout=timeout))
@@ -0,0 +1,15 @@
1
+ from .base import BaseAgent
2
+ from ..agent_version_sources import latest_github_release_version
3
+
4
+
5
+ class CodexGlibcAgent(BaseAgent):
6
+ type_name = "codex-glibc"
7
+ runtime_binary = "codex-glibc"
8
+ default_version = "0.130.0"
9
+
10
+ @classmethod
11
+ def check_latest_version(cls, *, architecture=None, timeout=30.0):
12
+ del architecture
13
+ return cls.normalize_version(
14
+ latest_github_release_version("openai/codex", tag_prefix="rust-v", timeout=timeout)
15
+ )
@@ -0,0 +1,23 @@
1
+ from .base import BaseAgent
2
+ from ..agent_version_sources import AgentVersionCheckError
3
+ from ..prebuilt import PrebuiltReleaseError, resolve_codex_glibc_prebuilt_release
4
+
5
+
6
+ class CodexGlibcPrebuiltAgent(BaseAgent):
7
+ type_name = "codex-glibc-prebuilt"
8
+ runtime_binary = "codex-glibc-prebuilt"
9
+ default_version = "0.130.0"
10
+
11
+ @classmethod
12
+ def check_latest_version(cls, *, architecture=None, timeout=30.0):
13
+ del timeout
14
+ if not architecture:
15
+ raise AgentVersionCheckError("Current architecture is required for codex-glibc-prebuilt")
16
+ try:
17
+ release = resolve_codex_glibc_prebuilt_release(arch=architecture)
18
+ except PrebuiltReleaseError as exc:
19
+ raise AgentVersionCheckError(str(exc)) from exc
20
+ prefix = "codex-glibc-rust-v"
21
+ if not release.tag.startswith(prefix):
22
+ raise AgentVersionCheckError(f"Unexpected codex-glibc prebuilt tag: {release.tag}")
23
+ return cls.normalize_version(release.tag[len(prefix):])
@@ -0,0 +1,16 @@
1
+ from .base import BaseAgent
2
+ from ..agent_version_sources import latest_github_release_version
3
+
4
+
5
+ class ForgecodeAgent(BaseAgent):
6
+ type_name = "forgecode"
7
+ runtime_binary = "forge"
8
+ default_version = "2.12.14"
9
+ default_env = {"FORGE_TRACKER": "false"}
10
+
11
+ @classmethod
12
+ def check_latest_version(cls, *, architecture=None, timeout=30.0):
13
+ del architecture
14
+ return cls.normalize_version(
15
+ latest_github_release_version("tailcallhq/forgecode", tag_prefix="v", timeout=timeout)
16
+ )
@@ -0,0 +1,15 @@
1
+ from .base import BaseAgent
2
+ from ..agent_version_sources import latest_npm_version
3
+
4
+
5
+ class OpencodeAgent(BaseAgent):
6
+ type_name = "opencode"
7
+ runtime_binary = "opencode"
8
+ default_version = "1.14.50"
9
+ default_env = {"OPENCODE_DISABLE_AUTOUPDATE": "true"}
10
+ _needs_nvm = True
11
+
12
+ @classmethod
13
+ def check_latest_version(cls, *, architecture=None, timeout=30.0):
14
+ del architecture
15
+ return cls.normalize_version(latest_npm_version("opencode-ai", timeout=timeout))
@@ -0,0 +1,14 @@
1
+ from .base import BaseAgent
2
+ from ..agent_version_sources import latest_npm_version
3
+
4
+
5
+ class QwenAgent(BaseAgent):
6
+ type_name = "qwen"
7
+ runtime_binary = "qwen"
8
+ default_version = "0.15.11"
9
+ _needs_nvm = True
10
+
11
+ @classmethod
12
+ def check_latest_version(cls, *, architecture=None, timeout=30.0):
13
+ del architecture
14
+ return cls.normalize_version(latest_npm_version("@qwen-code/qwen-code", timeout=timeout))
@@ -52,8 +52,7 @@
52
52
  (ansible_playbook_python | quote)
53
53
  ~ ' -m agsekit_cli.prebuilt resolve-codex-glibc-prebuilt --arch '
54
54
  ~ (codex_prebuilt_arch | quote)
55
- ~ ' --tag '
56
- ~ (('--tag ' ~ ('codex-glibc-rust-v' ~ requested_agent_version)) if requested_agent_version else '')
55
+ ~ ((' --tag ' ~ ('codex-glibc-rust-v' ~ requested_agent_version)) if requested_agent_version else '')
57
56
  ) | from_json
58
57
  }}
59
58
 
@@ -149,3 +148,6 @@
149
148
  ansible.builtin.command: "{{ codex_install_path }} --version"
150
149
  register: codex_version_check
151
150
  changed_when: false
151
+
152
+ - name: Install version-matched Codex Code Mode host
153
+ ansible.builtin.include_tasks: "{{ playbook_dir }}/codex_code_mode_host.yml"
@@ -23,6 +23,7 @@
23
23
  codex_user_path: "{{ ansible_env.HOME }}/.local/bin/codex-glibc"
24
24
  codex_required_free_kb: 3145728
25
25
  codex_min_swap_kb: 1048576
26
+ rust_toolchain: "{{ lookup('file', playbook_dir ~ '/../../codex_rust_toolchain_version.txt') | trim }}"
26
27
  tasks:
27
28
  - name: Configure proxychains
28
29
  ansible.builtin.include_tasks: "{{ playbook_dir }}/proxychains.yml"
@@ -132,7 +133,7 @@
132
133
  when: rustup_check.rc != 0
133
134
 
134
135
  - name: Install rustup
135
- ansible.builtin.command: /bin/sh /tmp/rustup-init.sh -y --no-modify-path
136
+ ansible.builtin.command: /bin/sh /tmp/rustup-init.sh -y --default-toolchain {{ rust_toolchain }} --no-modify-path
136
137
  environment:
137
138
  RUSTUP_INIT_SKIP_PATH_CHECK: "yes"
138
139
  when: rustup_check.rc != 0
@@ -141,6 +142,9 @@
141
142
  ansible.builtin.set_fact:
142
143
  cargo_bin: "{{ ansible_env.HOME }}/.cargo/bin"
143
144
 
145
+ - name: Ensure pinned Rust toolchain
146
+ ansible.builtin.command: "{{ cargo_bin }}/rustup toolchain install {{ rust_toolchain }} --profile minimal"
147
+
144
148
  - name: Resolve host target
145
149
  ansible.builtin.shell: "{{ cargo_bin }}/rustc -Vv | awk '/^host:/ {print $2}'"
146
150
  register: rustc_info
@@ -154,7 +158,7 @@
154
158
  host_target: "{{ rustc_info.stdout | trim | default(ansible_architecture ~ '-unknown-linux-gnu', true) }}"
155
159
 
156
160
  - name: Add rust target
157
- ansible.builtin.command: "{{ cargo_bin }}/rustup target add {{ host_target }}"
161
+ ansible.builtin.command: "{{ cargo_bin }}/rustup +{{ rust_toolchain }} target add {{ host_target }}"
158
162
 
159
163
  - name: Clone codex repository
160
164
  ansible.builtin.command: >-
@@ -201,6 +205,16 @@
201
205
  args:
202
206
  executable: /bin/bash
203
207
 
208
+ - name: Raise rustc query recursion limit for codex-exec
209
+ ansible.builtin.shell: >-
210
+ set -euo pipefail;
211
+ codex_exec_lib="$(dirname "{{ manifest_path.stdout }}")/src/lib.rs";
212
+ if [ -f "$codex_exec_lib" ] && ! grep -qF '#![recursion_limit = "256"]' "$codex_exec_lib"; then
213
+ sed -i '1i#![recursion_limit = "256"]' "$codex_exec_lib";
214
+ fi
215
+ args:
216
+ executable: /bin/bash
217
+
204
218
  - name: Build codex-glibc
205
219
  ansible.builtin.command: >-
206
220
  {{ proxychains_prefix }}bash -lc "export PATH={{ cargo_bin }}:$PATH;
@@ -210,7 +224,7 @@
210
224
  export CARGO_PROFILE_RELEASE_LTO=off;
211
225
  export CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1;
212
226
  export CARGO_PROFILE_RELEASE_DEBUG=false;
213
- cargo build --release --target {{ host_target }} --manifest-path {{ manifest_path.stdout }}"
227
+ cargo +{{ rust_toolchain }} build --release --target {{ host_target }} --manifest-path {{ manifest_path.stdout }}"
214
228
  changed_when: true
215
229
 
216
230
  - name: Install codex-glibc system-wide
@@ -249,6 +263,9 @@
249
263
  register: codex_version_check
250
264
  changed_when: false
251
265
 
266
+ - name: Install version-matched Codex Code Mode host
267
+ ansible.builtin.include_tasks: "{{ playbook_dir }}/codex_code_mode_host.yml"
268
+
252
269
  - name: Cleanup rust and cargo toolchains used for build
253
270
  ansible.builtin.shell: |
254
271
  set -euo pipefail
@@ -0,0 +1,52 @@
1
+ ---
2
+ - name: Extract installed Codex version for Code Mode host
3
+ ansible.builtin.set_fact:
4
+ codex_code_mode_host_version: >-
5
+ {{ codex_version_check.stdout | regex_search('[0-9]+\.[0-9]+\.[0-9]+(?:[-+][0-9A-Za-z.-]+)?') }}
6
+
7
+ - name: Fail when installed Codex version cannot be determined
8
+ ansible.builtin.fail:
9
+ msg: >-
10
+ Could not determine the installed Codex version from: {{ codex_version_check.stdout }}
11
+ when: not codex_code_mode_host_version
12
+
13
+ - name: Determine Codex Code Mode host release target
14
+ ansible.builtin.set_fact:
15
+ codex_code_mode_host_target: >-
16
+ {{ 'aarch64-unknown-linux-musl' if ansible_architecture in ['aarch64', 'arm64'] else 'x86_64-unknown-linux-musl' }}
17
+ codex_code_mode_host_path: "{{ codex_install_path | dirname }}/codex-code-mode-host"
18
+
19
+ - name: Remove previous Codex Code Mode host download
20
+ ansible.builtin.file:
21
+ path: /tmp/codex-code-mode-host.tar.gz
22
+ state: absent
23
+
24
+ - name: Download version-matched Codex Code Mode host
25
+ ansible.builtin.command: >-
26
+ {{ proxychains_prefix }}curl -fsSL --write-out %{http_code}
27
+ "https://github.com/openai/codex/releases/download/rust-v{{ codex_code_mode_host_version }}/codex-code-mode-host-{{ codex_code_mode_host_target }}.tar.gz"
28
+ -o /tmp/codex-code-mode-host.tar.gz
29
+ register: codex_code_mode_host_download
30
+ changed_when: codex_code_mode_host_download.rc == 0
31
+ failed_when:
32
+ - codex_code_mode_host_download.rc != 0
33
+ - codex_code_mode_host_download.stdout | trim != "404"
34
+
35
+ - name: Install Codex Code Mode host beside Codex binary
36
+ ansible.builtin.shell: |
37
+ set -euo pipefail
38
+ rm -rf /tmp/codex-code-mode-host-extract
39
+ mkdir -p /tmp/codex-code-mode-host-extract
40
+ tar -xzf /tmp/codex-code-mode-host.tar.gz -C /tmp/codex-code-mode-host-extract
41
+ helper="/tmp/codex-code-mode-host-extract/codex-code-mode-host-{{ codex_code_mode_host_target }}"
42
+ test -f "$helper"
43
+ {{ 'sudo ' if codex_install_mode == 'system' else '' }}install -m 0755 "$helper" "{{ codex_code_mode_host_path }}"
44
+ rm -rf /tmp/codex-code-mode-host-extract /tmp/codex-code-mode-host.tar.gz
45
+ args:
46
+ executable: /bin/bash
47
+ when: codex_code_mode_host_download.rc == 0
48
+
49
+ - name: Verify Codex Code Mode host works
50
+ ansible.builtin.command: "{{ codex_code_mode_host_path }} --help"
51
+ changed_when: false
52
+ when: codex_code_mode_host_download.rc == 0
@@ -5,7 +5,7 @@ from typing import Optional
5
5
 
6
6
  import click
7
7
 
8
- from ..config import resolve_config_path
8
+ from ..config import ConfigError, resolve_config_path
9
9
  from ..i18n import tr
10
10
  from ..state import CHANGELOG_URL, get_state_manager, initialize_state, run_check_new_version
11
11
  from ..versioning import is_newer_version
@@ -24,7 +24,7 @@ from . import debug_option, non_interactive_option
24
24
  help=tr("config.option_path"),
25
25
  )
26
26
  def check_new_version_command(config_path: Optional[str], non_interactive: bool, debug: bool) -> None:
27
- """Check PyPI through pip, update state.yaml, and report whether a newer version exists."""
27
+ """Refresh cached agsekit and configured-agent versions in state.yaml."""
28
28
  del non_interactive
29
29
  del debug
30
30
 
@@ -32,8 +32,8 @@ def check_new_version_command(config_path: Optional[str], non_interactive: bool,
32
32
  initialize_state(resolved_path)
33
33
  manager = get_state_manager()
34
34
  try:
35
- latest = run_check_new_version()
36
- except RuntimeError as exc:
35
+ latest = run_check_new_version(resolved_path)
36
+ except (ConfigError, RuntimeError) as exc:
37
37
  raise click.ClickException(tr("check_new_version.failed", error=str(exc)))
38
38
 
39
39
  if is_newer_version(latest, manager.current_version):
@@ -77,7 +77,7 @@ def run_daemon_status() -> None:
77
77
 
78
78
  @click.group(name="daemon", help=tr("daemon.group_help"))
79
79
  def daemon_group() -> None:
80
- """Commands for managing the portforward daemon."""
80
+ """Commands for managing the agsekit background daemon."""
81
81
 
82
82
 
83
83
  @daemon_group.command(name="install", help=tr("daemon.install_help"))