webbee 0.5.1__tar.gz → 0.5.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 (139) hide show
  1. {webbee-0.5.1 → webbee-0.5.2}/CHANGELOG.md +6 -0
  2. {webbee-0.5.1 → webbee-0.5.2}/PKG-INFO +4 -3
  3. {webbee-0.5.1 → webbee-0.5.2}/pyproject.toml +3 -3
  4. webbee-0.5.2/src/webbee/__init__.py +1 -0
  5. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/tools.py +5 -1
  6. {webbee-0.5.1 → webbee-0.5.2}/tests/test_tools.py +27 -0
  7. webbee-0.5.1/src/webbee/__init__.py +0 -1
  8. {webbee-0.5.1 → webbee-0.5.2}/.github/workflows/publish.yml +0 -0
  9. {webbee-0.5.1 → webbee-0.5.2}/.gitignore +0 -0
  10. {webbee-0.5.1 → webbee-0.5.2}/LICENSE +0 -0
  11. {webbee-0.5.1 → webbee-0.5.2}/README.md +0 -0
  12. {webbee-0.5.1 → webbee-0.5.2}/install.sh +0 -0
  13. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/__main__.py +0 -0
  14. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/account.py +0 -0
  15. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/active_sessions.py +0 -0
  16. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/banner_art.py +0 -0
  17. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/boot.py +0 -0
  18. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/browser.py +0 -0
  19. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/checkpoints.py +0 -0
  20. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/cli.py +0 -0
  21. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/clipboard.py +0 -0
  22. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/clipboard_read.py +0 -0
  23. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/clipboard_session.py +0 -0
  24. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/coding_context.py +0 -0
  25. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/commands.py +0 -0
  26. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/config.py +0 -0
  27. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/consent.py +0 -0
  28. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/details.py +0 -0
  29. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/events.py +0 -0
  30. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/frames.py +0 -0
  31. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/home.py +0 -0
  32. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/home_view.py +0 -0
  33. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/http.py +0 -0
  34. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/instance_lock.py +0 -0
  35. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/intel/__init__.py +0 -0
  36. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/intel/graph.py +0 -0
  37. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/intel/outline.py +0 -0
  38. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/intel/query.py +0 -0
  39. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/intel/service.py +0 -0
  40. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/intel/store.py +0 -0
  41. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/intel/vectors.py +0 -0
  42. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/intel/watch.py +0 -0
  43. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/media.py +0 -0
  44. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/modals.py +0 -0
  45. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/mode_store.py +0 -0
  46. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/native_files.py +0 -0
  47. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/native_read.py +0 -0
  48. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/newtab_mode.py +0 -0
  49. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/output_pane.py +0 -0
  50. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/pricing_constants.py +0 -0
  51. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/queue_panel.py +0 -0
  52. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/reflow.py +0 -0
  53. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/remote.py +0 -0
  54. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/render.py +0 -0
  55. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/repl.py +0 -0
  56. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/repo.py +0 -0
  57. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/selection.py +0 -0
  58. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/session.py +0 -0
  59. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/sessions.py +0 -0
  60. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/sizing.py +0 -0
  61. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/slots.py +0 -0
  62. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/steer.py +0 -0
  63. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/stream.py +0 -0
  64. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/tab_store.py +0 -0
  65. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/tabs.py +0 -0
  66. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/thread.py +0 -0
  67. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/tier_store.py +0 -0
  68. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/todo_panel.py +0 -0
  69. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/tokens.py +0 -0
  70. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/tui.py +0 -0
  71. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/update.py +0 -0
  72. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/urlopen.py +0 -0
  73. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/wallet.py +0 -0
  74. {webbee-0.5.1 → webbee-0.5.2}/src/webbee/worktrees.py +0 -0
  75. {webbee-0.5.1 → webbee-0.5.2}/tests/__init__.py +0 -0
  76. {webbee-0.5.1 → webbee-0.5.2}/tests/conftest.py +0 -0
  77. {webbee-0.5.1 → webbee-0.5.2}/tests/test_account.py +0 -0
  78. {webbee-0.5.1 → webbee-0.5.2}/tests/test_active_sessions.py +0 -0
  79. {webbee-0.5.1 → webbee-0.5.2}/tests/test_audit_2026_07_25_findings.py +0 -0
  80. {webbee-0.5.1 → webbee-0.5.2}/tests/test_checkpoints.py +0 -0
  81. {webbee-0.5.1 → webbee-0.5.2}/tests/test_cli.py +0 -0
  82. {webbee-0.5.1 → webbee-0.5.2}/tests/test_clipboard.py +0 -0
  83. {webbee-0.5.1 → webbee-0.5.2}/tests/test_clipboard_read.py +0 -0
  84. {webbee-0.5.1 → webbee-0.5.2}/tests/test_coding_context.py +0 -0
  85. {webbee-0.5.1 → webbee-0.5.2}/tests/test_commands.py +0 -0
  86. {webbee-0.5.1 → webbee-0.5.2}/tests/test_config.py +0 -0
  87. {webbee-0.5.1 → webbee-0.5.2}/tests/test_cpc_contract_stable.py +0 -0
  88. {webbee-0.5.1 → webbee-0.5.2}/tests/test_cpc_outline.py +0 -0
  89. {webbee-0.5.1 → webbee-0.5.2}/tests/test_cross_loop_token.py +0 -0
  90. {webbee-0.5.1 → webbee-0.5.2}/tests/test_details.py +0 -0
  91. {webbee-0.5.1 → webbee-0.5.2}/tests/test_events.py +0 -0
  92. {webbee-0.5.1 → webbee-0.5.2}/tests/test_freeze_fix.py +0 -0
  93. {webbee-0.5.1 → webbee-0.5.2}/tests/test_home.py +0 -0
  94. {webbee-0.5.1 → webbee-0.5.2}/tests/test_home_view.py +0 -0
  95. {webbee-0.5.1 → webbee-0.5.2}/tests/test_inspect_page.py +0 -0
  96. {webbee-0.5.1 → webbee-0.5.2}/tests/test_instance_lock.py +0 -0
  97. {webbee-0.5.1 → webbee-0.5.2}/tests/test_intel_chunker.py +0 -0
  98. {webbee-0.5.1 → webbee-0.5.2}/tests/test_intel_embed.py +0 -0
  99. {webbee-0.5.1 → webbee-0.5.2}/tests/test_intel_graph.py +0 -0
  100. {webbee-0.5.1 → webbee-0.5.2}/tests/test_intel_no_numpy.py +0 -0
  101. {webbee-0.5.1 → webbee-0.5.2}/tests/test_intel_query.py +0 -0
  102. {webbee-0.5.1 → webbee-0.5.2}/tests/test_intel_service.py +0 -0
  103. {webbee-0.5.1 → webbee-0.5.2}/tests/test_intel_store.py +0 -0
  104. {webbee-0.5.1 → webbee-0.5.2}/tests/test_intel_vectors.py +0 -0
  105. {webbee-0.5.1 → webbee-0.5.2}/tests/test_intel_watch.py +0 -0
  106. {webbee-0.5.1 → webbee-0.5.2}/tests/test_marathon.py +0 -0
  107. {webbee-0.5.1 → webbee-0.5.2}/tests/test_modals_e2e.py +0 -0
  108. {webbee-0.5.1 → webbee-0.5.2}/tests/test_mode_store.py +0 -0
  109. {webbee-0.5.1 → webbee-0.5.2}/tests/test_native_files.py +0 -0
  110. {webbee-0.5.1 → webbee-0.5.2}/tests/test_newtab_mode.py +0 -0
  111. {webbee-0.5.1 → webbee-0.5.2}/tests/test_packaging.py +0 -0
  112. {webbee-0.5.1 → webbee-0.5.2}/tests/test_queue_manage_0337.py +0 -0
  113. {webbee-0.5.1 → webbee-0.5.2}/tests/test_reflow.py +0 -0
  114. {webbee-0.5.1 → webbee-0.5.2}/tests/test_render.py +0 -0
  115. {webbee-0.5.1 → webbee-0.5.2}/tests/test_repl.py +0 -0
  116. {webbee-0.5.1 → webbee-0.5.2}/tests/test_repo.py +0 -0
  117. {webbee-0.5.1 → webbee-0.5.2}/tests/test_session.py +0 -0
  118. {webbee-0.5.1 → webbee-0.5.2}/tests/test_sessions.py +0 -0
  119. {webbee-0.5.1 → webbee-0.5.2}/tests/test_sizing.py +0 -0
  120. {webbee-0.5.1 → webbee-0.5.2}/tests/test_slots.py +0 -0
  121. {webbee-0.5.1 → webbee-0.5.2}/tests/test_steer.py +0 -0
  122. {webbee-0.5.1 → webbee-0.5.2}/tests/test_stream.py +0 -0
  123. {webbee-0.5.1 → webbee-0.5.2}/tests/test_tab_restore_0337.py +0 -0
  124. {webbee-0.5.1 → webbee-0.5.2}/tests/test_tabs.py +0 -0
  125. {webbee-0.5.1 → webbee-0.5.2}/tests/test_terminal_ux_0336.py +0 -0
  126. {webbee-0.5.1 → webbee-0.5.2}/tests/test_thread.py +0 -0
  127. {webbee-0.5.1 → webbee-0.5.2}/tests/test_tier_store.py +0 -0
  128. {webbee-0.5.1 → webbee-0.5.2}/tests/test_todo_panel.py +0 -0
  129. {webbee-0.5.1 → webbee-0.5.2}/tests/test_tokens.py +0 -0
  130. {webbee-0.5.1 → webbee-0.5.2}/tests/test_tools_vision_websearch.py +0 -0
  131. {webbee-0.5.1 → webbee-0.5.2}/tests/test_tui.py +0 -0
  132. {webbee-0.5.1 → webbee-0.5.2}/tests/test_tui_hardening.py +0 -0
  133. {webbee-0.5.1 → webbee-0.5.2}/tests/test_update.py +0 -0
  134. {webbee-0.5.1 → webbee-0.5.2}/tests/test_update_badge_0340.py +0 -0
  135. {webbee-0.5.1 → webbee-0.5.2}/tests/test_urlopen.py +0 -0
  136. {webbee-0.5.1 → webbee-0.5.2}/tests/test_version.py +0 -0
  137. {webbee-0.5.1 → webbee-0.5.2}/tests/test_version_badge_corner.py +0 -0
  138. {webbee-0.5.1 → webbee-0.5.2}/tests/test_wallet.py +0 -0
  139. {webbee-0.5.1 → webbee-0.5.2}/tests/test_worktrees.py +0 -0
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.2
4
+
5
+ * **One server, one machine**: a repo synced over your own `ssh` reports every host key of that server your
6
+ `known_hosts` trusts (RSA, ECDSA, ed25519), so the panel and your terminal see one machine, not two.
7
+ * Requires `imperal-sdk >= 6.3.4` (10 MB a file, batched syncs).
8
+
3
9
  ## 0.5.1
4
10
 
5
11
  **Security fixes for the remote and local code sync.**
@@ -1,13 +1,14 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: webbee
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: Webbee 🐝 — the Imperal Cloud coding agent in your terminal
5
5
  Project-URL: Homepage, https://imperal.io
6
6
  Project-URL: Documentation, https://docs.imperal.io
7
7
  Project-URL: Repository, https://github.com/imperalcloud/webbee-code
8
8
  Project-URL: Issues, https://github.com/imperalcloud/webbee-code/issues
9
9
  Project-URL: Protocol, https://icnli.org
10
- Author-email: "Imperal, Inc." <hello@imperal.io>
10
+ Author: Imperal, Inc.
11
+ Author-email: Valentin Scerbacov <valentin@imperal.io>
11
12
  License-Expression: GPL-3.0-or-later
12
13
  License-File: LICENSE
13
14
  Keywords: ai-agent,cli,coding-agent,icnli,imperal,llm,terminal,webbee
@@ -29,7 +30,7 @@ Requires-Dist: asyncssh>=2.14
29
30
  Requires-Dist: httpx-sse>=0.4
30
31
  Requires-Dist: httpx>=0.27
31
32
  Requires-Dist: imperal-mcp>=0.5.0
32
- Requires-Dist: imperal-sdk>=6.3.2
33
+ Requires-Dist: imperal-sdk>=6.3.4
33
34
  Requires-Dist: model2vec>=0.8.2; sys_platform != 'darwin' or platform_machine != 'x86_64' or python_version < '3.13'
34
35
  Requires-Dist: numpy>=2; sys_platform != 'darwin' or platform_machine != 'x86_64' or python_version < '3.13'
35
36
  Requires-Dist: prompt-toolkit>=3
@@ -1,15 +1,15 @@
1
1
  [project]
2
2
  name = "webbee"
3
- version = "0.5.1"
3
+ version = "0.5.2"
4
4
  description = "Webbee 🐝 — the Imperal Cloud coding agent in your terminal"
5
5
  readme = "README.md"
6
6
  license = "GPL-3.0-or-later"
7
7
  license-files = ["LICENSE"]
8
8
  requires-python = ">=3.9"
9
- authors = [{ name = "Imperal, Inc.", email = "hello@imperal.io" }]
9
+ authors = [{ name = "Valentin Scerbacov", email = "valentin@imperal.io" }, { name = "Imperal, Inc." }]
10
10
  dependencies = [
11
11
  "imperal-mcp>=0.5.0",
12
- "imperal-sdk>=6.3.2",
12
+ "imperal-sdk>=6.3.4",
13
13
  "asyncssh>=2.14",
14
14
  "httpx>=0.27",
15
15
  "httpx-sse>=0.4",
@@ -0,0 +1 @@
1
+ __version__ = "0.5.2"
@@ -1111,7 +1111,11 @@ async def _open_sftp(host: str):
1111
1111
  except Exception as e: # unreachable, refused, a host key that changed: said, never guessed past
1112
1112
  return None, None, [], f"{type(e).__name__}: {e}"
1113
1113
  key = conn.get_server_host_key()
1114
- return await conn.start_sftp_client(), conn, ([key.get_fingerprint("sha256")] if key else []), ""
1114
+ # the negotiated key and the host's other keys the user's known_hosts trusts: a server has several (RSA,
1115
+ # ECDSA, ed25519) and another source may have met it by a different one -- one machine, never two
1116
+ fps = sorted({key.get_fingerprint("sha256")} if key else set())
1117
+ fps = sorted(set(fps) | set(known_fingerprints(host)))
1118
+ return await conn.start_sftp_client(), conn, fps, ""
1115
1119
 
1116
1120
 
1117
1121
  async def remote_sync(client, host: str, root: str, paths: list) -> dict:
@@ -887,3 +887,30 @@ def test_system_sftp_refuses_a_control_character_in_a_remote_path():
887
887
  with pytest.raises(OSError):
888
888
  asyncio.run(s.readdir(bad))
889
889
  assert ran == []
890
+
891
+
892
+ def test_an_asyncssh_connect_reports_every_key_of_the_host_the_user_trusts(monkeypatch):
893
+ """Live 2026-10-20: the panel met whm-jump by RSA, the user's ssh by ed25519 -- two machine nodes. The
894
+ client sends the negotiated key and the host's other known_hosts keys: one machine."""
895
+ import asyncio
896
+ import asyncssh
897
+ import webbee.tools as t
898
+ monkeypatch.setattr(t, "master_open", lambda host: False)
899
+ monkeypatch.setattr(t, "known_fingerprints", lambda host: ["SHA256:rsa", "SHA256:ecdsa", "SHA256:ed"])
900
+
901
+ class Key:
902
+ def get_fingerprint(self, alg):
903
+ return "SHA256:ed"
904
+
905
+ class Conn:
906
+ def get_server_host_key(self):
907
+ return Key()
908
+
909
+ async def start_sftp_client(self):
910
+ return "sftp"
911
+
912
+ async def connect(host, **kw):
913
+ return Conn()
914
+ monkeypatch.setattr(asyncssh, "connect", connect)
915
+ sftp, conn, fps, why = asyncio.run(t._open_sftp("whm-jump"))
916
+ assert sftp == "sftp" and why == "" and fps == ["SHA256:ecdsa", "SHA256:ed", "SHA256:rsa"]
@@ -1 +0,0 @@
1
- __version__ = "0.5.1"
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
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
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
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
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
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
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
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
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
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
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
File without changes