witbitz-code 1.7.2__tar.gz → 1.7.3__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 (106) hide show
  1. {witbitz_code-1.7.2/src/witbitz_code.egg-info → witbitz_code-1.7.3}/PKG-INFO +1 -1
  2. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/pyproject.toml +1 -1
  3. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/__init__.py +1 -1
  4. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/confidential.py +5 -1
  5. {witbitz_code-1.7.2 → witbitz_code-1.7.3/src/witbitz_code.egg-info}/PKG-INFO +1 -1
  6. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_confidential.py +15 -1
  7. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/LICENSE +0 -0
  8. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/README.md +0 -0
  9. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/setup.cfg +0 -0
  10. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/__main__.py +0 -0
  11. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/_js.py +0 -0
  12. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/account.py +0 -0
  13. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/asks.py +0 -0
  14. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/attachments.py +0 -0
  15. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/auto.py +0 -0
  16. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/auto_runner.py +0 -0
  17. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/cli.py +0 -0
  18. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/codekeys.py +0 -0
  19. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/codetools.py +0 -0
  20. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/compress.py +0 -0
  21. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/computers.py +0 -0
  22. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/confidential_models.json +0 -0
  23. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/connector.py +0 -0
  24. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/devicelink.py +0 -0
  25. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/dirs.py +0 -0
  26. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/folders.py +0 -0
  27. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/gateway.py +0 -0
  28. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/icons/witbitz-code-wsl.ico +0 -0
  29. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/icons/witbitz-code.ico +0 -0
  30. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/images.py +0 -0
  31. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/keys.py +0 -0
  32. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/link.py +0 -0
  33. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/mkdir.py +0 -0
  34. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/models.py +0 -0
  35. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/net.py +0 -0
  36. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/offered_models.json +0 -0
  37. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/opencode_plugins/notes-init.md +0 -0
  38. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/opencode_plugins/witbitz-media-server.mjs +0 -0
  39. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/opencode_plugins/witbitz-notes.js +0 -0
  40. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/opencode_plugins/witbitz-progress.js +0 -0
  41. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/outputs.py +0 -0
  42. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/pair.py +0 -0
  43. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/pairings.py +0 -0
  44. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/payers.py +0 -0
  45. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/plugins.py +0 -0
  46. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/policy.py +0 -0
  47. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/ports.py +0 -0
  48. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/qr.py +0 -0
  49. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/receipt.py +0 -0
  50. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/relay.py +0 -0
  51. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/remind.py +0 -0
  52. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/seccheck.py +0 -0
  53. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/seen.py +0 -0
  54. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/tinfoil_read.py +0 -0
  55. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/tools_catalog.json +0 -0
  56. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/tools_probe.py +0 -0
  57. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/toolsetup.py +0 -0
  58. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/ui.py +0 -0
  59. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/ui_static/app.css +0 -0
  60. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/ui_static/app.js +0 -0
  61. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/ui_static/index.html +0 -0
  62. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/uitools.py +0 -0
  63. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/uninstall.py +0 -0
  64. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/winagent.py +0 -0
  65. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/winbg.py +0 -0
  66. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/winconsole.py +0 -0
  67. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/wizard.py +0 -0
  68. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code/wslstart.py +0 -0
  69. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code.egg-info/SOURCES.txt +0 -0
  70. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code.egg-info/dependency_links.txt +0 -0
  71. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code.egg-info/entry_points.txt +0 -0
  72. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code.egg-info/requires.txt +0 -0
  73. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/src/witbitz_code.egg-info/top_level.txt +0 -0
  74. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_asks.py +0 -0
  75. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_attachments.py +0 -0
  76. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_auto.py +0 -0
  77. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_cli.py +0 -0
  78. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_codekeys.py +0 -0
  79. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_codetools.py +0 -0
  80. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_connector_e2e.py +0 -0
  81. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_devicelink.py +0 -0
  82. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_dirs.py +0 -0
  83. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_files_and_compress.py +0 -0
  84. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_folders.py +0 -0
  85. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_images.py +0 -0
  86. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_outputs.py +0 -0
  87. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_pair_flows.py +0 -0
  88. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_plugins.py +0 -0
  89. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_policy.py +0 -0
  90. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_ports.py +0 -0
  91. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_ports_win.py +0 -0
  92. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_registry.py +0 -0
  93. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_relay_codec.py +0 -0
  94. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_remind.py +0 -0
  95. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_seccheck.py +0 -0
  96. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_setup.py +0 -0
  97. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_tools_probe.py +0 -0
  98. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_toolsetup.py +0 -0
  99. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_ui.py +0 -0
  100. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_uitools.py +0 -0
  101. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_uninstall.py +0 -0
  102. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_winagent.py +0 -0
  103. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_winbg.py +0 -0
  104. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_winconsole.py +0 -0
  105. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_windows_files.py +0 -0
  106. {witbitz_code-1.7.2 → witbitz_code-1.7.3}/tests/test_wslstart.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: witbitz-code
3
- Version: 1.7.2
3
+ Version: 1.7.3
4
4
  Summary: Reach OpenCode on this computer from the Witbitz Spaces Code section, through an end-to-end sealed relay.
5
5
  Author: Witbitz
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "witbitz-code"
7
- version = "1.7.2"
7
+ version = "1.7.3"
8
8
  description = "Reach OpenCode on this computer from the Witbitz Spaces Code section, through an end-to-end sealed relay."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -4,4 +4,4 @@ The Python implementation of tools/witbitz-code.mjs (docs/opencode-relay.md phas
4
4
  vectors and cross-implementation tests.
5
5
  """
6
6
 
7
- __version__ = "1.7.2"
7
+ __version__ = "1.7.3"
@@ -627,7 +627,11 @@ class ConfidentialProxy:
627
627
  hold = attempt["n"] > 1 or (ends is not None and self._now() / 1000 >= ends - HOLD_BEFORE_LAPSE_SEC)
628
628
  n = self._nonce()
629
629
  raw = dumps(stamp_floor(body)).encode("utf-8")
630
- headers = {**_forward_headers(req.headers), "content-type": "application/json", "x-inference-receipt": n}
630
+ # the forwarded headers WITHOUT their own content-type / x-inference-receipt, whatever their case: OpenCode sends
631
+ # "Content-Type", and two of them made TrustedRouter refuse every confidential call (2026-10-17: a small one 400
632
+ # "could not read request"; a large one closed mid-upload — an empty httpx ReadError, "could not reach TrustedRouter ()")
633
+ fwd = {k: v for k, v in _forward_headers(req.headers).items() if k.lower() not in ("content-type", "x-inference-receipt")}
634
+ headers = {**fwd, "content-type": "application/json", "x-inference-receipt": n}
631
635
  tell("waiting", bytes=len(raw))
632
636
  async with self.client.stream("POST", target, headers=headers, content=raw) as up:
633
637
  if not up.is_success:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: witbitz-code
3
- Version: 1.7.2
3
+ Version: 1.7.3
4
4
  Summary: Reach OpenCode on this computer from the Witbitz Spaces Code section, through an end-to-end sealed relay.
5
5
  Author: Witbitz
6
6
  License-Expression: MIT
@@ -110,7 +110,7 @@ class FakeNet:
110
110
  def handler(self, req: httpx.Request):
111
111
  if "googleapis.com/service_accounts" in str(req.url):
112
112
  return httpx.Response(200, json=self.meta["googleJwks"])
113
- self.calls.append({"url": str(req.url), "headers": dict(req.headers), "body": req.content.decode("utf-8")})
113
+ self.calls.append({"url": str(req.url), "headers": dict(req.headers), "raw": list(req.headers.raw), "body": req.content.decode("utf-8")})
114
114
  if self.status != 200:
115
115
  return httpx.Response(self.status, json={"error": {"message": "upstream said no"}})
116
116
  data = self.stream.encode("utf-8")
@@ -176,6 +176,20 @@ def test_a_confidential_answer_streams_through_and_the_receipt_verifies_on_the_r
176
176
  with_proxy(t)
177
177
 
178
178
 
179
+ @needs_fixture
180
+ def test_one_content_type_goes_upstream_whatever_case_opencode_sends_it():
181
+ # 2026-10-17: OpenCode sends "Content-Type"; the proxy forwarded it and added its own "content-type", and TrustedRouter
182
+ # refused every confidential call with two (a small one 400 "could not read request", a large one closed mid-upload —
183
+ # an empty httpx ReadError the owner saw as "could not reach TrustedRouter ()").
184
+ async def t(post, net, _p):
185
+ r = await post(SAY_OK, {"Content-Type": "application/json", "X-Inference-Receipt": "from-the-caller"})
186
+ assert r.status_code == 200
187
+ names = [k.decode().lower() for k, _v in net.calls[0]["raw"]]
188
+ assert names.count("content-type") == 1, names
189
+ assert names.count("x-inference-receipt") == 1 and net.calls[0]["headers"]["x-inference-receipt"] != "from-the-caller"
190
+ with_proxy(t)
191
+
192
+
179
193
  @needs_fixture
180
194
  def test_a_receipt_that_does_not_match_ends_the_step_with_an_error_and_no_tool_runs():
181
195
  meta, stream, _ = fixture()
File without changes
File without changes
File without changes