firekeep-client 1.7.1__tar.gz → 1.7.2__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 (179) hide show
  1. {firekeep_client-1.7.1/firekeep_client.egg-info → firekeep_client-1.7.2}/PKG-INFO +1 -1
  2. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/__init__.py +1 -1
  3. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/cli.py +13 -9
  4. {firekeep_client-1.7.1 → firekeep_client-1.7.2/firekeep_client.egg-info}/PKG-INFO +1 -1
  5. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/pyproject.toml +1 -1
  6. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_hands.py +21 -1
  7. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_package.py +1 -1
  8. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/LICENSE +0 -0
  9. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/NOTICE +0 -0
  10. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/README.md +0 -0
  11. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/adapters/__init__.py +0 -0
  12. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/adapters/base.py +0 -0
  13. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/adapters/claude.py +0 -0
  14. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/adapters/claude_desktop.py +0 -0
  15. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/adapters/codex.py +0 -0
  16. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/adapters/generic.py +0 -0
  17. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/adapters/kiro.py +0 -0
  18. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/adapters/opencode.py +0 -0
  19. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/adapters/pi.py +0 -0
  20. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/autoupdate.py +0 -0
  21. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/background.py +0 -0
  22. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/backups.py +0 -0
  23. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/childenv.py +0 -0
  24. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/config_write.py +0 -0
  25. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/connect.py +0 -0
  26. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/contract/__init__.py +0 -0
  27. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/contract/matrix.py +0 -0
  28. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/decision/__init__.py +0 -0
  29. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/decision/board.py +0 -0
  30. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/decision/server.py +0 -0
  31. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/dexes.py +0 -0
  32. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/docdexsync.py +0 -0
  33. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/gateway.py +0 -0
  34. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/hooklog.py +0 -0
  35. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/hooks/__init__.py +0 -0
  36. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/hooks/__main__.py +0 -0
  37. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/hooks/_git.py +0 -0
  38. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/hooks/_mcp.py +0 -0
  39. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/hooks/destructive.py +0 -0
  40. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/hooks/post_tool.py +0 -0
  41. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/hooks/pre_tool.py +0 -0
  42. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/hooks/precompact.py +0 -0
  43. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/hooks/prompt.py +0 -0
  44. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/hooks/runbooks.py +0 -0
  45. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/hooks/session_end.py +0 -0
  46. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/hooks/session_start.py +0 -0
  47. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/hooks/stop.py +0 -0
  48. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/jobobject.py +0 -0
  49. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/join.py +0 -0
  50. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/joincode.py +0 -0
  51. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/maildexsync.py +0 -0
  52. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/migrate.py +0 -0
  53. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/nightshift.py +0 -0
  54. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/nightshiftdrain.py +0 -0
  55. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/pathenv.py +0 -0
  56. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/promptrecall.py +0 -0
  57. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/report.py +0 -0
  58. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/resolver.py +0 -0
  59. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/serverinit.py +0 -0
  60. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/serverupdate.py +0 -0
  61. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/shim.py +0 -0
  62. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/sidecar.py +0 -0
  63. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/signing.py +0 -0
  64. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/state.py +0 -0
  65. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/stdio.py +0 -0
  66. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/symdexindex.py +0 -0
  67. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/transport.py +0 -0
  68. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/updater.py +0 -0
  69. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/wizard.py +0 -0
  70. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client/worktree_snapshot.py +0 -0
  71. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client.egg-info/SOURCES.txt +0 -0
  72. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client.egg-info/dependency_links.txt +0 -0
  73. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client.egg-info/entry_points.txt +0 -0
  74. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client.egg-info/requires.txt +0 -0
  75. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/firekeep_client.egg-info/top_level.txt +0 -0
  76. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/setup.cfg +0 -0
  77. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_attribution_headers.py +0 -0
  78. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_autoupdate.py +0 -0
  79. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_background.py +0 -0
  80. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_bash_layer_retired.py +0 -0
  81. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_bootstrap_consent_pty.py +0 -0
  82. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_bootstrap_docdex.py +0 -0
  83. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_bootstrap_maildex.py +0 -0
  84. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_bootstrap_ps1.py +0 -0
  85. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_bootstrap_reinstall.py +0 -0
  86. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_bootstrap_sh.py +0 -0
  87. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_bootstrap_symdex.py +0 -0
  88. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_bootstrap_venv_provisioning.py +0 -0
  89. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_ci_publishes_symdex.py +0 -0
  90. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli.py +0 -0
  91. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_backup.py +0 -0
  92. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_dex.py +0 -0
  93. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_docdex.py +0 -0
  94. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_doctor.py +0 -0
  95. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_doctor_generic.py +0 -0
  96. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_doctor_report.py +0 -0
  97. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_entry.py +0 -0
  98. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_generic_install.py +0 -0
  99. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_install.py +0 -0
  100. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_maildex.py +0 -0
  101. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_onboarding.py +0 -0
  102. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_personal.py +0 -0
  103. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_uninstall.py +0 -0
  104. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_uninstall_generic.py +0 -0
  105. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_cli_update.py +0 -0
  106. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_config_migration.py +0 -0
  107. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_connect.py +0 -0
  108. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_decision_board_html.py +0 -0
  109. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_decision_bypass.py +0 -0
  110. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_decision_poll_ceiling.py +0 -0
  111. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_decision_registration.py +0 -0
  112. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_decision_server.py +0 -0
  113. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_dexes.py +0 -0
  114. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_docdexsync.py +0 -0
  115. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_docs_reference_client_kit.py +0 -0
  116. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_doctor_credential_expiry.py +0 -0
  117. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_doctor_embeddings.py +0 -0
  118. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_doctor_no_server.py +0 -0
  119. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_e2e_bootstrap.py +0 -0
  120. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_gateway.py +0 -0
  121. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_gateway_child_env.py +0 -0
  122. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_gateway_schema_slimming.py +0 -0
  123. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_gateway_toolset.py +0 -0
  124. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_generic_config.py +0 -0
  125. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_hooklog.py +0 -0
  126. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_import_boundary.py +0 -0
  127. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_init_self_enroll.py +0 -0
  128. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_init_stale_bundle.py +0 -0
  129. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_install_skill_contract.py +0 -0
  130. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_instruction_budget.py +0 -0
  131. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_jobobject.py +0 -0
  132. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_join.py +0 -0
  133. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_join_config_write.py +0 -0
  134. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_joincode.py +0 -0
  135. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_kit_smoke.py +0 -0
  136. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_maildexsync.py +0 -0
  137. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_make_release.py +0 -0
  138. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_memory_instructions.py +0 -0
  139. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_migration_entrypoints.py +0 -0
  140. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_nightshift.py +0 -0
  141. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_nightshiftdrain.py +0 -0
  142. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_pathenv.py +0 -0
  143. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_promptrecall.py +0 -0
  144. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_report_bootstrap_enums.py +0 -0
  145. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_report_capture.py +0 -0
  146. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_report_consent.py +0 -0
  147. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_report_consent_surfaces.py +0 -0
  148. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_report_flush_points.py +0 -0
  149. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_report_integration.py +0 -0
  150. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_report_schema.py +0 -0
  151. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_report_spool.py +0 -0
  152. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_resolver.py +0 -0
  153. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_resolver_bypass.py +0 -0
  154. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_resolver_single_connection.py +0 -0
  155. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_runbook_match_parity.py +0 -0
  156. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_runbook_state.py +0 -0
  157. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_scratch_ttl.py +0 -0
  158. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_serverinit.py +0 -0
  159. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_serverupdate.py +0 -0
  160. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_shim_bridge.py +0 -0
  161. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_shim_bypass.py +0 -0
  162. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_shim_eof_exit.py +0 -0
  163. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_shim_fail_loud.py +0 -0
  164. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_shim_identity.py +0 -0
  165. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_shim_recovery.py +0 -0
  166. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_shim_skeleton.py +0 -0
  167. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_sidecar.py +0 -0
  168. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_sidecar_robustness.py +0 -0
  169. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_signing.py +0 -0
  170. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_state.py +0 -0
  171. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_stdio_encoding.py +0 -0
  172. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_symdexindex.py +0 -0
  173. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_transport.py +0 -0
  174. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_transport_sse.py +0 -0
  175. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_twin_removed.py +0 -0
  176. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_updater.py +0 -0
  177. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_wizard.py +0 -0
  178. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_wizard_generic.py +0 -0
  179. {firekeep_client-1.7.1 → firekeep_client-1.7.2}/tests/test_worktree_snapshot.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: firekeep-client
3
- Version: 1.7.1
3
+ Version: 1.7.2
4
4
  Summary: Client for Firekeep, the self-hosted operating layer for connected AI agents.
5
5
  License-Expression: LicenseRef-Firekeep-BUSL-1.1
6
6
  Project-URL: Homepage, https://firekeep.ai
@@ -9,4 +9,4 @@ versions without a verdict (`_check_versions`) and judges staleness against the
9
9
  release manifest instead (`_check_client_version`).
10
10
  """
11
11
 
12
- __version__ = "1.7.1"
12
+ __version__ = "1.7.2"
@@ -159,10 +159,11 @@ EMPTY_REGISTRY_HINT = (
159
159
  # §3.1), so this is the one place in the kit that names the wheel's source.
160
160
  HANDS_WHEEL_SPEC = "firekeep-hands>=0.1,<0.2"
161
161
 
162
- # Flip to True in the release that first publishes firekeep-hands through the
163
- # `pypi-hands` trusted publisher (Task 13). Until then a bare `pip install
164
- # firekeep-hands` could resolve to whoever registers the name first.
165
- HANDS_PYPI_PUBLISHED = False
162
+ # True since client 1.7.2: firekeep-hands 0.1.0 was published through the
163
+ # `pypi-hands` trusted publisher on 2026-10-06. While it was False, a bare
164
+ # `pip install firekeep-hands` could have resolved to whoever registered the
165
+ # name first, so `enable` refused without `--from`.
166
+ HANDS_PYPI_PUBLISHED = True
166
167
 
167
168
 
168
169
  def _current_link(home: Path | None = None) -> Path:
@@ -2212,9 +2213,11 @@ def cmd_hands(args) -> int:
2212
2213
  is a translator onto `firekeep_hands.cli.main`, imported lazily so a kit
2213
2214
  without the wheel keeps every other command working.
2214
2215
 
2215
- PyPI squat guard (2026-09-05 ruling): `firekeep-hands` is not published
2216
- yet, so a bare `enable` (no `--from`, no `--pypi`) refuses rather than
2217
- `pip install`-ing a name a third party could still claim.
2216
+ Source: `--from` (a checkout dir, wheel path or pip spec) when given,
2217
+ otherwise the published PyPI wheel (`HANDS_WHEEL_SPEC`). PyPI squat guard
2218
+ (2026-09-05 ruling): while `HANDS_PYPI_PUBLISHED` is False, `enable`
2219
+ without `--from` refuses rather than `pip install`-ing a name a third
2220
+ party could still claim.
2218
2221
  """
2219
2222
  action = getattr(args, "action", None) or "status"
2220
2223
  manifest = dexes.KNOWN_DEXES["hands"]
@@ -2222,7 +2225,7 @@ def cmd_hands(args) -> int:
2222
2225
  if action == "enable":
2223
2226
  source = (getattr(args, "source", None) or "").strip()
2224
2227
  if not source:
2225
- if getattr(args, "pypi", False) and HANDS_PYPI_PUBLISHED:
2228
+ if HANDS_PYPI_PUBLISHED:
2226
2229
  source = HANDS_WHEEL_SPEC
2227
2230
  else:
2228
2231
  print("firekeep: firekeep-hands is not yet published to PyPI — install from a "
@@ -3224,7 +3227,8 @@ def _build_parser() -> argparse.ArgumentParser:
3224
3227
  p_hands.add_argument("--from", dest="source", default=None,
3225
3228
  help="wheel source for enable: a local checkout dir or a pip spec")
3226
3229
  p_hands.add_argument("--pypi", action="store_true",
3227
- help="enable: install the published wheel from PyPI (HANDS_WHEEL_SPEC)")
3230
+ help="enable: install the published wheel from PyPI (the default "
3231
+ "without --from; kept for scripts that pass it)")
3228
3232
  p_hands.add_argument("--no-autostart", action="store_true")
3229
3233
  p_hands.add_argument("--purge", action="store_true", help="with disable: delete ~/.firekeep/hands")
3230
3234
  p_hands.set_defaults(func=cmd_hands)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: firekeep-client
3
- Version: 1.7.1
3
+ Version: 1.7.2
4
4
  Summary: Client for Firekeep, the self-hosted operating layer for connected AI agents.
5
5
  License-Expression: LicenseRef-Firekeep-BUSL-1.1
6
6
  Project-URL: Homepage, https://firekeep.ai
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "firekeep-client"
7
- version = "1.7.1"
7
+ version = "1.7.2"
8
8
  description = "Client for Firekeep, the self-hosted operating layer for connected AI agents."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -35,7 +35,27 @@ def _args(**kw):
35
35
  return types.SimpleNamespace(**base)
36
36
 
37
37
 
38
- def test_enable_with_no_source_and_pypi_not_published_refuses(registry_home, capsys):
38
+ def test_firekeep_hands_is_published_on_pypi():
39
+ # Flipped in client 1.7.2: firekeep-hands 0.1.0 was published through the
40
+ # `pypi-hands` trusted publisher on 2026-10-06, byte-identical to the wheel
41
+ # on the dist host (sha256 7358bdda...). The squat guard below still
42
+ # protects any kit built with the flag off.
43
+ assert cli.HANDS_PYPI_PUBLISHED is True
44
+
45
+
46
+ def test_bare_enable_installs_from_pypi_once_published(registry_home, monkeypatch):
47
+ calls = []
48
+ monkeypatch.setattr(cli, "_pip_install", lambda python, spec: calls.append(("pip", spec)))
49
+ monkeypatch.setattr(dexes, "is_installed", lambda m: True)
50
+ monkeypatch.setattr(cli, "_run_hands_broker", lambda argv: calls.append(("broker", tuple(argv))) or 0)
51
+ monkeypatch.setattr(cli, "HANDS_PYPI_PUBLISHED", True)
52
+ assert cli.cmd_hands(_args(action="enable")) == 0
53
+ assert calls == [("pip", cli.HANDS_WHEEL_SPEC), ("broker", ("install-autostart",))]
54
+ assert dexes.read_registry()["hands"]["source"] == "pypi"
55
+
56
+
57
+ def test_enable_with_no_source_and_pypi_not_published_refuses(registry_home, monkeypatch, capsys):
58
+ monkeypatch.setattr(cli, "HANDS_PYPI_PUBLISHED", False)
39
59
  assert cli.cmd_hands(_args(action="enable")) == 2
40
60
  err = capsys.readouterr().err
41
61
  assert "not yet published to PyPI" in err
@@ -7,7 +7,7 @@ from pathlib import Path
7
7
  def test_package_imports_and_exposes_frozen_version():
8
8
  import firekeep_client
9
9
 
10
- assert firekeep_client.__version__ == "1.7.1"
10
+ assert firekeep_client.__version__ == "1.7.2"
11
11
 
12
12
 
13
13
  def test_the_version_pins_agree():
File without changes
File without changes