verifaied 0.34.3.dev93__tar.gz → 0.35.0.dev94__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 (93) hide show
  1. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/PKG-INFO +14 -9
  2. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/README.md +12 -7
  3. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/pyproject.toml +11 -11
  4. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/agent_mcp.py +52 -19
  5. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/cli.py +295 -64
  6. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/client.py +68 -1
  7. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/config.py +40 -14
  8. verifaied-0.35.0.dev94/src/verifaied/credentials.py +156 -0
  9. verifaied-0.35.0.dev94/src/verifaied/logincmd.py +194 -0
  10. verifaied-0.35.0.dev94/src/verifaied/setupcmd.py +219 -0
  11. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/skill/SKILL.md +23 -8
  12. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/skill/reference/commands.md +27 -3
  13. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/conftest.py +24 -0
  14. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_agent_mcp.py +53 -17
  15. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_check_done.py +1 -1
  16. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_clear_manual.py +1 -1
  17. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_cli.py +2 -2
  18. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_client.py +4 -1
  19. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_config.py +26 -4
  20. verifaied-0.35.0.dev94/tests/test_credentials.py +128 -0
  21. verifaied-0.35.0.dev94/tests/test_help_markup.py +48 -0
  22. verifaied-0.35.0.dev94/tests/test_login_commands.py +153 -0
  23. verifaied-0.35.0.dev94/tests/test_logincmd.py +308 -0
  24. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_record.py +1 -1
  25. verifaied-0.35.0.dev94/tests/test_setupcmd.py +283 -0
  26. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_testcmd.py +2 -2
  27. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/uv.lock +6 -10
  28. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/.gitignore +0 -0
  29. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/LICENSE +0 -0
  30. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/__init__.py +0 -0
  31. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/__main__.py +0 -0
  32. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/agent_steps.py +0 -0
  33. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/analyzer.py +0 -0
  34. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/audit.py +0 -0
  35. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/collect_browser.js +0 -0
  36. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/collect_browser.py +0 -0
  37. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/failure_text.py +0 -0
  38. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/finishing.py +0 -0
  39. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/instrument.py +0 -0
  40. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/instrument_snippets.py +0 -0
  41. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/instrumenter.js +0 -0
  42. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/instrumenter.py +0 -0
  43. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/lanes.py +0 -0
  44. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/prompts.py +0 -0
  45. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/proxy.py +0 -0
  46. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/record.py +0 -0
  47. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/recorder_driver.js +0 -0
  48. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/recorder_observer.js +0 -0
  49. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/recorder_picker.js +0 -0
  50. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/recorder_refs.js +0 -0
  51. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/recorder_spec.js +0 -0
  52. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/replay_harvest.ts +0 -0
  53. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/repo_config.py +0 -0
  54. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/run_reporter.js +0 -0
  55. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/runner_dir.py +0 -0
  56. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/skillcmd.py +0 -0
  57. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/source_index.py +0 -0
  58. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/stepcheck.py +0 -0
  59. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/subprocess_util.py +0 -0
  60. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/suite_report.py +0 -0
  61. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/testcmd.py +0 -0
  62. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/uploader.py +0 -0
  63. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/varcmd.py +0 -0
  64. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/video_render.js +0 -0
  65. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/src/verifaied/video_render.py +0 -0
  66. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/__init__.py +0 -0
  67. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_audit.py +0 -0
  68. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_browser_settings_parity.py +0 -0
  69. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_caption_parity.py +0 -0
  70. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_check.py +0 -0
  71. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_collect_browser.py +0 -0
  72. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_console_label_parity.py +0 -0
  73. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_finishing.py +0 -0
  74. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_instrument.py +0 -0
  75. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_instrument_detect.py +0 -0
  76. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_instrument_snippets.py +0 -0
  77. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_instrumenter.py +0 -0
  78. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_lanes.py +0 -0
  79. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_pause_parity.py +0 -0
  80. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_prompt_parity.py +0 -0
  81. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_proxy.py +0 -0
  82. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_render_parity.py +0 -0
  83. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_replay_harvest_runner.py +0 -0
  84. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_repo_config.py +0 -0
  85. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_skill_parity.py +0 -0
  86. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_skillcmd.py +0 -0
  87. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_source_index.py +0 -0
  88. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_stepcheck_parity.py +0 -0
  89. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_suite_report.py +0 -0
  90. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_uploader.py +0 -0
  91. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_varcmd.py +0 -0
  92. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_video_render.py +0 -0
  93. {verifaied-0.34.3.dev93 → verifaied-0.35.0.dev94}/tests/test_video_render_runner.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: verifaied
3
- Version: 0.34.3.dev93
3
+ Version: 0.35.0.dev94
4
4
  Summary: Find what's untested in your code — locally, no account required
5
5
  Project-URL: Homepage, https://pypi.org/project/verifaied/
6
6
  Author: Kyle Richards
@@ -34,12 +34,12 @@ Classifier: License :: OSI Approved :: MIT License
34
34
  Classifier: Topic :: Software Development :: Testing
35
35
  Requires-Python: >=3.10
36
36
  Requires-Dist: httpx>=0.27.0
37
+ Requires-Dist: mcp<2.0.0,>=1.27
37
38
  Requires-Dist: rich>=13.7.0
38
39
  Requires-Dist: tomli>=2.0.1; python_version < '3.11'
39
40
  Requires-Dist: tomlkit>=0.13.0
40
41
  Requires-Dist: typer>=0.12.0
41
42
  Provides-Extra: agent
42
- Requires-Dist: mcp<2.0.0,>=1.27; extra == 'agent'
43
43
  Provides-Extra: audit
44
44
  Requires-Dist: playwright<2,>=1.49; extra == 'audit'
45
45
  Description-Content-Type: text/markdown
@@ -118,17 +118,22 @@ so `check` works as a CI gate.
118
118
 
119
119
  ## `verifaied upload` — sync to the app
120
120
 
121
- Mint an API token from the verifAIed app (Settings → API tokens; a free account is
122
- enough). The CLI ships pointing at the hosted API (`https://api.verifaied.app`);
123
- point it elsewhere via `VERIFAIED_API_URL` if you're running the backend locally
124
- or self-hosting:
121
+ Log the CLI in once per machine (a free account is enough). It opens the
122
+ browser; check the code matches your terminal and click Approve, and the CLI
123
+ stores its token in `~/.config/verifaied/credentials.toml` (readable only by
124
+ you). Nothing to copy or export:
125
125
 
126
126
  ```bash
127
- export VERIFAIED_API_TOKEN=vr_live_...
128
- # Only set this if you're not using the hosted API:
129
- export VERIFAIED_API_URL=http://localhost:8000 # local dev
127
+ verifaied login # verifaied login --check: am I logged in?
128
+ verifaied setup claude # optional: connect Claude Code (or: setup codex/cursor/gemini)
130
129
  ```
131
130
 
131
+ CI has no browser: mint a token in the app (Settings → API tokens) and set it
132
+ as `VERIFAIED_API_TOKEN`, which wins over a stored login. The CLI ships pointing
133
+ at the hosted API (`https://api.verifaied.app`); point it elsewhere via
134
+ `VERIFAIED_API_URL` (or `--api-url`) if you're running the backend locally or
135
+ self-hosting — each API URL keeps its own login.
136
+
132
137
  The link printed after an upload opens the web app, worked out from the API
133
138
  URL (`api.verifaied.app` → `verifaied.app`, `localhost:8000` →
134
139
  `localhost:3000`). Set `VERIFAIED_WEB_URL` if yours lives somewhere else.
@@ -72,17 +72,22 @@ so `check` works as a CI gate.
72
72
 
73
73
  ## `verifaied upload` — sync to the app
74
74
 
75
- Mint an API token from the verifAIed app (Settings → API tokens; a free account is
76
- enough). The CLI ships pointing at the hosted API (`https://api.verifaied.app`);
77
- point it elsewhere via `VERIFAIED_API_URL` if you're running the backend locally
78
- or self-hosting:
75
+ Log the CLI in once per machine (a free account is enough). It opens the
76
+ browser; check the code matches your terminal and click Approve, and the CLI
77
+ stores its token in `~/.config/verifaied/credentials.toml` (readable only by
78
+ you). Nothing to copy or export:
79
79
 
80
80
  ```bash
81
- export VERIFAIED_API_TOKEN=vr_live_...
82
- # Only set this if you're not using the hosted API:
83
- export VERIFAIED_API_URL=http://localhost:8000 # local dev
81
+ verifaied login # verifaied login --check: am I logged in?
82
+ verifaied setup claude # optional: connect Claude Code (or: setup codex/cursor/gemini)
84
83
  ```
85
84
 
85
+ CI has no browser: mint a token in the app (Settings → API tokens) and set it
86
+ as `VERIFAIED_API_TOKEN`, which wins over a stored login. The CLI ships pointing
87
+ at the hosted API (`https://api.verifaied.app`); point it elsewhere via
88
+ `VERIFAIED_API_URL` (or `--api-url`) if you're running the backend locally or
89
+ self-hosting — each API URL keeps its own login.
90
+
86
91
  The link printed after an upload opens the web app, worked out from the API
87
92
  URL (`api.verifaied.app` → `verifaied.app`, `localhost:8000` →
88
93
  `localhost:3000`). Set `VERIFAIED_WEB_URL` if yours lives somewhere else.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "verifaied"
3
- version = "0.34.3.dev93"
3
+ version = "0.35.0.dev94"
4
4
  description = "Find what's untested in your code — locally, no account required"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -26,6 +26,13 @@ dependencies = [
26
26
  # and a round-trip through a plain TOML dumper would hand it back with
27
27
  # every comment and every bit of ordering gone.
28
28
  "tomlkit>=0.13.0",
29
+ # `verifaied test mcp` serves the recorder to a coding agent over MCP.
30
+ # A dependency rather than an extra: the recorder is how an agent
31
+ # proves a change in a browser, and an install that silently lacked it
32
+ # registered a server that died at start-up. Pinned to the range the
33
+ # backend's own MCP server is built against, so the two halves of the
34
+ # product speak the same protocol version.
35
+ "mcp>=1.27,<2.0.0",
29
36
  ]
30
37
 
31
38
  [project.optional-dependencies]
@@ -33,12 +40,9 @@ dependencies = [
33
40
  # command that needs one, and a ~300MB browser download has no business
34
41
  # being a dependency of `verifaied check`.
35
42
  audit = ["playwright>=1.49,<2"]
36
- # `verifaied test mcp` serves the recorder to a coding agent over MCP.
37
- # Optional for `audit`'s reason: it is the one command that needs a
38
- # protocol server, and nobody running `verifaied check` should pay for
39
- # one. Pinned to the range the backend's own MCP server is built against,
40
- # so the two halves of the product speak the same protocol version.
41
- agent = ["mcp>=1.27,<2.0.0"]
43
+ # Kept, empty, so `verifaied[agent]` in an existing install command or
44
+ # Makefile still resolves; the MCP library is now a plain dependency.
45
+ agent = []
42
46
 
43
47
  [project.scripts]
44
48
  verifaied = "verifaied.cli:app"
@@ -58,10 +62,6 @@ dev = [
58
62
  "pytest>=8.0.0",
59
63
  "pytest-httpx>=0.30.0",
60
64
  "ruff>=0.8.0",
61
- # `verifaied test mcp` is an optional extra at install time and a
62
- # tested one here: the suite drives the server's tool functions
63
- # directly, so the library has to be present when the suite runs.
64
- "mcp>=1.27,<2.0.0",
65
65
  ]
66
66
 
67
67
  [tool.pytest.ini_options]
@@ -104,11 +104,18 @@ from verifaied.testcmd import (
104
104
  )
105
105
  from verifaied.uploader import detect_branch
106
106
 
107
- INSTALL_HINT = (
108
- "[red]VerifAIed error[/red]: `verifaied test mcp` needs the MCP server "
109
- "library, which is an optional extra.\n"
110
- r" pip install 'verifaied\[agent]' # or: "
111
- r"uv tool install 'verifaied\[agent]'"
107
+ # Every tool ``build_server`` registers, by name. The stand-in server a
108
+ # recorder that cannot start serves (``build_unavailable_server``) answers
109
+ # to the same names, so an agent that calls one learns why instead of
110
+ # finding the tool missing.
111
+ TOOL_NAMES = (
112
+ "list_tests",
113
+ "start_recording",
114
+ "run_steps",
115
+ "read_page",
116
+ "delete_step",
117
+ "finish_recording",
118
+ "cancel_recording",
112
119
  )
113
120
 
114
121
  # How long a settle is waited for. Per step, and capped per call, exactly
@@ -1148,11 +1155,9 @@ class AgentRecorderServer:
1148
1155
  def build_server(recorder: AgentRecorderServer) -> Any:
1149
1156
  """The FastMCP server, with one tool per thing an agent can do.
1150
1157
 
1151
- ``FastMCP`` is imported **here** rather than at module scope because
1152
- the MCP library is an optional extra: at module scope an install
1153
- without it would fail to load ``verifaied.cli`` at all and take every
1154
- other command down with it. The same exception
1155
- :func:`verifaied.audit._load_playwright` takes, for the same reason.
1158
+ ``FastMCP`` is imported **here** rather than at module scope so that
1159
+ every other command — ``check``, ``upload`` — starts without paying
1160
+ for the MCP library's import.
1156
1161
  """
1157
1162
  from mcp.server.fastmcp import FastMCP
1158
1163
 
@@ -1308,9 +1313,7 @@ def run_test_mcp(
1308
1313
  be able to get wrong. Children are kept off fd 1 by
1309
1314
  :func:`quiet_process` and :func:`quiet_shell` for the same reason.
1310
1315
 
1311
- Returns the process exit code. ``1`` when the MCP library is not
1312
- installed, which is the one refusal this command can make before it
1313
- has done anything.
1316
+ Returns the process exit code.
1314
1317
  """
1315
1318
  console = Console(stderr=True)
1316
1319
  err_console = Console(stderr=True)
@@ -1328,11 +1331,7 @@ def run_test_mcp(
1328
1331
  console=console,
1329
1332
  err_console=err_console,
1330
1333
  )
1331
- try:
1332
- server = build_server(recorder)
1333
- except ImportError:
1334
- err_console.print(INSTALL_HINT)
1335
- return 1
1334
+ server = build_server(recorder)
1336
1335
  # Both ends of "this process is going away". atexit covers a clean
1337
1336
  # return and an uncaught exception; SIGTERM does not run atexit on its
1338
1337
  # own, and SIGTERM is how a supervisor stops a stdio server.
@@ -1342,6 +1341,38 @@ def run_test_mcp(
1342
1341
  return 0
1343
1342
 
1344
1343
 
1344
+ def build_unavailable_server(reason: str) -> Any:
1345
+ """A recorder that could not start, still answering on stdio.
1346
+
1347
+ Exiting would leave the agent with nothing but "failed to connect" and
1348
+ no reason. Instead every tool the real server has answers with
1349
+ ``reason`` — say, "not logged in — run `verifaied login`" — so the
1350
+ agent can tell the user exactly what to do. Extra arguments a call
1351
+ carries are ignored."""
1352
+ from mcp.server.fastmcp import FastMCP
1353
+
1354
+ message = (
1355
+ f"verifaied-recorder is not ready: {reason}. Fix that, then reconnect "
1356
+ "this MCP server (in Claude Code: /mcp, then reconnect "
1357
+ "verifaied-recorder)."
1358
+ )
1359
+ mcp = FastMCP("verifaied-recorder", instructions=message)
1360
+ for name in TOOL_NAMES:
1361
+
1362
+ async def unavailable() -> str:
1363
+ return message
1364
+
1365
+ mcp.tool(name=name, description=message)(unavailable)
1366
+ return mcp
1367
+
1368
+
1369
+ def run_unavailable_mcp(reason: str) -> int:
1370
+ """Serve :func:`build_unavailable_server` until the session ends."""
1371
+ Console(stderr=True).print(f"[red]VerifAIed error[/red]: {reason}")
1372
+ build_unavailable_server(reason).run("stdio")
1373
+ return 0
1374
+
1375
+
1345
1376
  def _install_termination_handler(recorder: AgentRecorderServer) -> None:
1346
1377
  """Close the browser on SIGTERM, then let the default handler run.
1347
1378
 
@@ -1363,7 +1394,9 @@ def _install_termination_handler(recorder: AgentRecorderServer) -> None:
1363
1394
  __all__ = [
1364
1395
  "AgentRecorderServer",
1365
1396
  "AgentRecording",
1366
- "INSTALL_HINT",
1397
+ "TOOL_NAMES",
1367
1398
  "build_server",
1399
+ "build_unavailable_server",
1368
1400
  "run_test_mcp",
1401
+ "run_unavailable_mcp",
1369
1402
  ]