witbitz-code 1.3.3__tar.gz → 1.3.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.
- {witbitz_code-1.3.3/src/witbitz_code.egg-info → witbitz_code-1.3.4}/PKG-INFO +1 -1
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/pyproject.toml +1 -1
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/__init__.py +1 -1
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/codekeys.py +3 -12
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/payers.py +1 -7
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/uninstall.py +1 -1
- {witbitz_code-1.3.3 → witbitz_code-1.3.4/src/witbitz_code.egg-info}/PKG-INFO +1 -1
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code.egg-info/SOURCES.txt +2 -1
- witbitz_code-1.3.4/tests/test_windows_files.py +28 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/LICENSE +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/README.md +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/setup.cfg +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/__main__.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/_js.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/account.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/asks.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/attachments.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/auto.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/auto_runner.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/cli.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/codetools.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/compress.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/computers.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/confidential.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/confidential_models.json +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/connector.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/devicelink.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/folders.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/gateway.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/keys.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/link.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/models.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/net.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/offered_models.json +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/opencode_plugins/notes-init.md +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/opencode_plugins/witbitz-media-server.mjs +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/opencode_plugins/witbitz-notes.js +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/opencode_plugins/witbitz-progress.js +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/outputs.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/pair.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/pairings.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/plugins.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/policy.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/ports.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/qr.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/receipt.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/relay.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/seen.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/tinfoil_read.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/tools_probe.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/winagent.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/winconsole.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/wizard.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code.egg-info/dependency_links.txt +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code.egg-info/entry_points.txt +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code.egg-info/requires.txt +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code.egg-info/top_level.txt +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_asks.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_attachments.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_auto.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_cli.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_codekeys.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_codetools.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_confidential.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_connector_e2e.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_devicelink.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_files_and_compress.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_folders.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_outputs.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_pair_flows.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_plugins.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_policy.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_ports.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_registry.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_relay_codec.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_setup.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_tools_probe.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_uninstall.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_winagent.py +0 -0
- {witbitz_code-1.3.3 → witbitz_code-1.3.4}/tests/test_winconsole.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "witbitz-code"
|
|
7
|
-
version = "1.3.
|
|
7
|
+
version = "1.3.4"
|
|
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"
|
|
@@ -15,7 +15,6 @@ from __future__ import annotations
|
|
|
15
15
|
import base64
|
|
16
16
|
import json
|
|
17
17
|
import os
|
|
18
|
-
import tempfile
|
|
19
18
|
import time
|
|
20
19
|
from email.utils import parsedate_to_datetime
|
|
21
20
|
from pathlib import Path
|
|
@@ -147,17 +146,9 @@ def read_all() -> dict:
|
|
|
147
146
|
|
|
148
147
|
|
|
149
148
|
def _write_all(doc: dict) -> None:
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
try:
|
|
154
|
-
os.fchmod(fd, 0o600)
|
|
155
|
-
with os.fdopen(fd, "w", encoding="utf-8") as f:
|
|
156
|
-
f.write(json.dumps(doc, indent=1) + "\n")
|
|
157
|
-
os.replace(tmp, path)
|
|
158
|
-
except BaseException:
|
|
159
|
-
Path(tmp).unlink(missing_ok=True)
|
|
160
|
-
raise
|
|
149
|
+
# pairings.write_private: 0600, atomic, and Windows-safe (Windows Python 3.12 has no os.fchmod — the owner's native
|
|
150
|
+
# Windows pairing died here, the real error hidden by a cleanup that could not delete the still-open temp file).
|
|
151
|
+
pp.write_private(keys_path(), json.dumps(doc, indent=1) + "\n")
|
|
161
152
|
|
|
162
153
|
|
|
163
154
|
def for_computer(computer_id: str) -> dict | None:
|
|
@@ -16,7 +16,6 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
import json
|
|
18
18
|
import os
|
|
19
|
-
import tempfile
|
|
20
19
|
import threading
|
|
21
20
|
from pathlib import Path
|
|
22
21
|
|
|
@@ -49,12 +48,7 @@ class SessionPayers:
|
|
|
49
48
|
if not self._persist:
|
|
50
49
|
return
|
|
51
50
|
try:
|
|
52
|
-
self._path.
|
|
53
|
-
fd, tmp = tempfile.mkstemp(dir=str(self._path.parent), prefix=".session-payers.")
|
|
54
|
-
os.fchmod(fd, 0o600)
|
|
55
|
-
with os.fdopen(fd, "w", encoding="utf-8") as f:
|
|
56
|
-
f.write(json.dumps({"v": 1, "owners": self._owner}))
|
|
57
|
-
os.replace(tmp, self._path)
|
|
51
|
+
pp.write_private(self._path, json.dumps({"v": 1, "owners": self._owner})) # Windows-safe (no os.fchmod there)
|
|
58
52
|
except OSError:
|
|
59
53
|
pass # memory still knows; a restart forgets, and a forgotten conversation is refused, never misbilled
|
|
60
54
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Private files on Windows (the owner's native Windows run, 2026-10-08: pairing succeeded, then "FATAL — [WinError 32] The
|
|
2
|
+
process cannot access the file because it is being used by another process: …\\.account-keys.<tmp>"). Windows Python 3.12
|
|
3
|
+
(the installer's) has no os.fchmod; the keys writer called it on the open temp file, and its cleanup then tried to delete
|
|
4
|
+
that still-open file — which Windows refuses, hiding the real error. Every private file goes through pairings.write_private."""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from witbitz_code import codekeys
|
|
10
|
+
from witbitz_code.payers import SessionPayers
|
|
11
|
+
|
|
12
|
+
SRC = Path(__file__).resolve().parent.parent / "src" / "witbitz_code"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_the_keys_and_payers_files_are_written_where_python_has_no_fchmod(monkeypatch):
|
|
16
|
+
from fakes import give_code_keys
|
|
17
|
+
|
|
18
|
+
monkeypatch.delattr(os, "fchmod", raising=False)
|
|
19
|
+
e = give_code_keys("cmp_win")
|
|
20
|
+
assert codekeys.for_computer("cmp_win")["keyId"] == e["keyId"]
|
|
21
|
+
p = SessionPayers()
|
|
22
|
+
assert p.begin("ses_W", "cmp_win")
|
|
23
|
+
assert SessionPayers().payer("ses_W") == "cmp_win", "the payer was saved, not lost to an AttributeError"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_no_module_calls_fchmod():
|
|
27
|
+
hits = [f.name for f in SRC.glob("*.py") if "os.fchmod(" in f.read_text(encoding="utf-8")]
|
|
28
|
+
assert hits == [], f"os.fchmod does not exist on Windows Python before 3.13 — use pairings.write_private: {hits}"
|
|
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
|
{witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/opencode_plugins/witbitz-media-server.mjs
RENAMED
|
File without changes
|
{witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/opencode_plugins/witbitz-notes.js
RENAMED
|
File without changes
|
{witbitz_code-1.3.3 → witbitz_code-1.3.4}/src/witbitz_code/opencode_plugins/witbitz-progress.js
RENAMED
|
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
|