solvewright 0.1.0__tar.gz → 0.1.1__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 (33) hide show
  1. {solvewright-0.1.0 → solvewright-0.1.1}/PKG-INFO +5 -3
  2. {solvewright-0.1.0 → solvewright-0.1.1}/README.md +4 -2
  3. {solvewright-0.1.0 → solvewright-0.1.1}/pyproject.toml +1 -1
  4. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/__init__.py +1 -1
  5. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/cli.py +2 -2
  6. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/connection.py +27 -0
  7. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/worker.py +2 -2
  8. {solvewright-0.1.0 → solvewright-0.1.1}/tests/test_connection.py +17 -0
  9. {solvewright-0.1.0 → solvewright-0.1.1}/.gitignore +0 -0
  10. {solvewright-0.1.0 → solvewright-0.1.1}/LICENSE +0 -0
  11. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/__main__.py +0 -0
  12. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/agents.py +0 -0
  13. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/cases/portals/brief.txt +0 -0
  14. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/cases/portals/interviewer.txt +0 -0
  15. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/cases/portals/reported-round.txt +0 -0
  16. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/data/portal-samples/sample-01.json +0 -0
  17. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/data/portal-samples/sample-02.json +0 -0
  18. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/data/portal-samples/sample-03.json +0 -0
  19. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/data/portal-samples/sample-04.json +0 -0
  20. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/data/portal-samples/sample-05.json +0 -0
  21. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/data/portal-samples/sample-06.json +0 -0
  22. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/data/portal-samples/sample-07.json +0 -0
  23. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/data/portal-samples/sample-08.json +0 -0
  24. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/interviewer.txt +0 -0
  25. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/references/case-generation.txt +0 -0
  26. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/references/curriculum.txt +0 -0
  27. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/references/scoring.txt +0 -0
  28. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/references/session-format.txt +0 -0
  29. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/interviewer/tools/portal_lab.py +0 -0
  30. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/runtime.py +0 -0
  31. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/service.py +0 -0
  32. {solvewright-0.1.0 → solvewright-0.1.1}/src/solvewright/settings.py +0 -0
  33. {solvewright-0.1.0 → solvewright-0.1.1}/tests/test_runtime.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: solvewright
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Connect your own Claude Code or Codex to Solvewright Interview Lab for mock technical interviews.
5
5
  Project-URL: Homepage, https://solvewright.app/coding/interviews
6
6
  Project-URL: Source, https://github.com/fus3r/solvewright-connector
@@ -44,8 +44,10 @@ then `solvewright`. Python 3.10 or newer. The package has no dependencies.
44
44
  line for each thing it does (a round prepared, a reply, tests recorded).
45
45
  4. Press Ctrl+C to stop. Nothing keeps running in the background, and nothing starts again by itself.
46
46
 
47
- Next time, `solvewright` reconnects without a new code. `solvewright disconnect` removes this
48
- computer from your account; you can also remove it from Interview Lab, which stops its key at once.
47
+ Next time, run the same command again: it reconnects without a new code, and the terminal reminds you
48
+ which command that is. `uvx` and `pipx run` keep the package in a cache and add no `solvewright`
49
+ command to your shell, so with them, put `uvx` or `pipx run` in front of the commands below (for
50
+ example `uvx solvewright status`). Removing this computer from Interview Lab stops its key at once.
49
51
 
50
52
  | Command | Does |
51
53
  | --- | --- |
@@ -21,8 +21,10 @@ then `solvewright`. Python 3.10 or newer. The package has no dependencies.
21
21
  line for each thing it does (a round prepared, a reply, tests recorded).
22
22
  4. Press Ctrl+C to stop. Nothing keeps running in the background, and nothing starts again by itself.
23
23
 
24
- Next time, `solvewright` reconnects without a new code. `solvewright disconnect` removes this
25
- computer from your account; you can also remove it from Interview Lab, which stops its key at once.
24
+ Next time, run the same command again: it reconnects without a new code, and the terminal reminds you
25
+ which command that is. `uvx` and `pipx run` keep the package in a cache and add no `solvewright`
26
+ command to your shell, so with them, put `uvx` or `pipx run` in front of the commands below (for
27
+ example `uvx solvewright status`). Removing this computer from Interview Lab stops its key at once.
26
28
 
27
29
  | Command | Does |
28
30
  | --- | --- |
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "solvewright"
7
- version = "0.1.0"
7
+ version = "0.1.1"
8
8
  description = "Connect your own Claude Code or Codex to Solvewright Interview Lab for mock technical interviews."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -1,3 +1,3 @@
1
1
  """Solvewright connector: runs your own Claude Code or Codex for Interview Lab."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.1.1"
@@ -93,7 +93,7 @@ def header(out: Out, config, label: str, described: dict, account: str | None =
93
93
 
94
94
  def approve(out: Out, config, service: Service, label: str, open_browser: bool) -> dict:
95
95
  described = agents.describe()
96
- details = {"connector": __version__, "os": connection.operating_system(),
96
+ details = {"connector": __version__, "os": connection.operating_system(), "launcher": connection.launcher(),
97
97
  "python": ".".join(str(part) for part in sys.version_info[:3]),
98
98
  "agents": {name: info["version"] for name, info in described.items() if info["available"]}}
99
99
  pending = connection.request(service, label, details)
@@ -133,7 +133,7 @@ def serve(out: Out, config, service: Service, record: dict) -> int:
133
133
  out.line()
134
134
  out.line("Interview Lab is ready: " + out.bold(f"{config.site_url}/coding/interviews"))
135
135
  out.line("Keep this window open while you practise. Closing it stops the connector;")
136
- out.line("nothing keeps running in the background.")
136
+ out.line("nothing keeps running in the background. Next time, run " + out.bold(connection.next_command()) + ": no new code is needed.")
137
137
  out.line()
138
138
  out.event("Waiting for the Interview Lab")
139
139
  if sys.platform == "win32":
@@ -12,6 +12,7 @@ import json
12
12
  import os
13
13
  import platform
14
14
  import re
15
+ import shutil
15
16
  import subprocess
16
17
  import sys
17
18
  import tempfile
@@ -47,6 +48,32 @@ def computer_name() -> str:
47
48
  return name[:64] or "This computer"
48
49
 
49
50
 
51
+ def launcher() -> str:
52
+ """How this copy was started, so the terminal and Interview Lab can say what to run next time.
53
+
54
+ uvx and pipx run keep the package in a cache and put no command on the PATH, which is why
55
+ a plain `solvewright` would not be found afterwards."""
56
+ prefix = Path(sys.prefix).as_posix().lower()
57
+ if "/uv/" in prefix and "/archive-v" in prefix:
58
+ return "uvx"
59
+ # `pipx run` keeps throwaway environments in a cache whose place changed between pipx versions;
60
+ # `pipx install` keeps them under venvs/ and puts the command on the PATH.
61
+ if "/pipx/" in prefix and "/venvs/" not in prefix:
62
+ return "pipx"
63
+ return "command" if shutil.which("solvewright") else "module"
64
+
65
+
66
+ def next_command(kind: str | None = None) -> str:
67
+ kind = kind or launcher()
68
+ if kind == "uvx":
69
+ return "uvx solvewright"
70
+ if kind == "pipx":
71
+ return "pipx run solvewright"
72
+ if kind == "command":
73
+ return "solvewright"
74
+ return ("py" if sys.platform == "win32" else "python3") + " -m solvewright"
75
+
76
+
50
77
  def operating_system() -> str:
51
78
  if sys.platform == "darwin":
52
79
  return "macOS " + (platform.mac_ver()[0] or "").strip()
@@ -11,7 +11,7 @@ import sys
11
11
  import time
12
12
  import uuid
13
13
 
14
- from . import __version__, agents
14
+ from . import __version__, agents, connection
15
15
  from .service import ServiceError, Unavailable
16
16
 
17
17
  ROUND = re.compile(r"/sessions/([a-f0-9-]{36})(?:/(message|files|test-runs|interrupt))?")
@@ -96,7 +96,7 @@ def describe_job(path: str, body) -> str | None:
96
96
 
97
97
 
98
98
  def details(runtime) -> dict:
99
- return {"connector": __version__, "agents": {name: {"version": info["version"], "isolation": info["isolation"]}
99
+ return {"connector": __version__, "launcher": connection.launcher(), "agents": {name: {"version": info["version"], "isolation": info["isolation"]}
100
100
  for name, info in health(runtime)["agents"].items() if info["available"]}}
101
101
 
102
102
 
@@ -125,3 +125,20 @@ class WorkerTests(unittest.TestCase):
125
125
 
126
126
  if __name__ == "__main__":
127
127
  unittest.main()
128
+
129
+
130
+ class LauncherTests(unittest.TestCase):
131
+ def test_the_next_command_is_the_one_that_started_this_copy(self):
132
+ # uvx and pipx run leave no `solvewright` on the PATH, so a plain `solvewright` would not be found next time.
133
+ cases = [("/Users/a/.cache/uv/archive-v0/x1", None, "uvx", "uvx solvewright"),
134
+ ("/Users/a/.local/pipx/.cache/x2", None, "pipx", "pipx run solvewright"),
135
+ ("/Users/a/Library/Caches/pipx/x3", None, "pipx", "pipx run solvewright"),
136
+ ("/Users/a/.local/pipx/venvs/solvewright", "/Users/a/.local/bin/solvewright", "command", "solvewright"),
137
+ ("/Users/a/.local/share/uv/tools/solvewright", "/Users/a/.local/bin/solvewright", "command", "solvewright")]
138
+ for prefix, found, kind, command in cases:
139
+ with patch.object(connection.sys, "prefix", prefix), patch.object(connection.shutil, "which", return_value=found):
140
+ self.assertEqual(connection.launcher(), kind)
141
+ self.assertEqual(connection.next_command(), command)
142
+ with patch.object(connection.sys, "prefix", "/usr/local"), patch.object(connection.shutil, "which", return_value=None):
143
+ self.assertEqual(connection.launcher(), "module")
144
+ self.assertTrue(connection.next_command().endswith(" -m solvewright"))
File without changes
File without changes