verifaied 0.34.2.dev92__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.
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/PKG-INFO +15 -10
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/README.md +13 -8
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/pyproject.toml +11 -11
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/agent_mcp.py +52 -19
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/cli.py +295 -64
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/client.py +68 -1
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/config.py +40 -14
- verifaied-0.35.0.dev94/src/verifaied/credentials.py +156 -0
- verifaied-0.35.0.dev94/src/verifaied/logincmd.py +194 -0
- verifaied-0.35.0.dev94/src/verifaied/setupcmd.py +219 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/skill/SKILL.md +23 -8
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/skill/reference/commands.md +27 -3
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/conftest.py +24 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_agent_mcp.py +53 -17
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_check_done.py +1 -1
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_clear_manual.py +1 -1
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_cli.py +2 -2
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_client.py +4 -1
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_config.py +26 -4
- verifaied-0.35.0.dev94/tests/test_credentials.py +128 -0
- verifaied-0.35.0.dev94/tests/test_help_markup.py +48 -0
- verifaied-0.35.0.dev94/tests/test_login_commands.py +153 -0
- verifaied-0.35.0.dev94/tests/test_logincmd.py +308 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_record.py +1 -1
- verifaied-0.35.0.dev94/tests/test_setupcmd.py +283 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_testcmd.py +2 -2
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/uv.lock +6 -10
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/.gitignore +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/LICENSE +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/__init__.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/__main__.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/agent_steps.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/analyzer.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/audit.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/collect_browser.js +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/collect_browser.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/failure_text.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/finishing.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/instrument.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/instrument_snippets.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/instrumenter.js +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/instrumenter.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/lanes.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/prompts.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/proxy.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/record.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/recorder_driver.js +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/recorder_observer.js +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/recorder_picker.js +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/recorder_refs.js +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/recorder_spec.js +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/replay_harvest.ts +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/repo_config.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/run_reporter.js +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/runner_dir.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/skillcmd.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/source_index.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/stepcheck.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/subprocess_util.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/suite_report.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/testcmd.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/uploader.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/varcmd.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/video_render.js +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/src/verifaied/video_render.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/__init__.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_audit.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_browser_settings_parity.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_caption_parity.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_check.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_collect_browser.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_console_label_parity.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_finishing.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_instrument.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_instrument_detect.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_instrument_snippets.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_instrumenter.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_lanes.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_pause_parity.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_prompt_parity.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_proxy.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_render_parity.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_replay_harvest_runner.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_repo_config.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_skill_parity.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_skillcmd.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_source_index.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_stepcheck_parity.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_suite_report.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_uploader.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_varcmd.py +0 -0
- {verifaied-0.34.2.dev92 → verifaied-0.35.0.dev94}/tests/test_video_render.py +0 -0
- {verifaied-0.34.2.dev92 → 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.
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
or
|
|
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
|
-
|
|
128
|
-
|
|
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.
|
|
@@ -1314,7 +1319,7 @@ Do the following, in order:
|
|
|
1314
1319
|
# 2. Verify the CLI is installed and configured
|
|
1315
1320
|
|
|
1316
1321
|
- Run `verifaied --help`. If it exits non-zero, install it: `uv tool install verifaied` (preferred) or `pipx install verifaied`.
|
|
1317
|
-
- Check `echo $VERIFAIED_API_TOKEN`. If empty, stop and tell the user to mint one from the verifAIed app (Settings →
|
|
1322
|
+
- Check `echo $VERIFAIED_API_TOKEN`. If empty, stop and tell the user to mint one from the verifAIed app (Settings → API tokens) and export it: `export VERIFAIED_API_TOKEN=vr_live_...`. Do NOT invent a placeholder and do NOT proceed without it.
|
|
1318
1323
|
|
|
1319
1324
|
# 3. Write the loop into the agent-instructions file
|
|
1320
1325
|
|
|
@@ -72,17 +72,22 @@ so `check` works as a CI gate.
|
|
|
72
72
|
|
|
73
73
|
## `verifaied upload` — sync to the app
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
or
|
|
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
|
-
|
|
82
|
-
|
|
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.
|
|
@@ -1268,7 +1273,7 @@ Do the following, in order:
|
|
|
1268
1273
|
# 2. Verify the CLI is installed and configured
|
|
1269
1274
|
|
|
1270
1275
|
- Run `verifaied --help`. If it exits non-zero, install it: `uv tool install verifaied` (preferred) or `pipx install verifaied`.
|
|
1271
|
-
- Check `echo $VERIFAIED_API_TOKEN`. If empty, stop and tell the user to mint one from the verifAIed app (Settings →
|
|
1276
|
+
- Check `echo $VERIFAIED_API_TOKEN`. If empty, stop and tell the user to mint one from the verifAIed app (Settings → API tokens) and export it: `export VERIFAIED_API_TOKEN=vr_live_...`. Do NOT invent a placeholder and do NOT proceed without it.
|
|
1272
1277
|
|
|
1273
1278
|
# 3. Write the loop into the agent-instructions file
|
|
1274
1279
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "verifaied"
|
|
3
|
-
version = "0.
|
|
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
|
-
#
|
|
37
|
-
#
|
|
38
|
-
|
|
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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
|
1152
|
-
|
|
1153
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
"
|
|
1397
|
+
"TOOL_NAMES",
|
|
1367
1398
|
"build_server",
|
|
1399
|
+
"build_unavailable_server",
|
|
1368
1400
|
"run_test_mcp",
|
|
1401
|
+
"run_unavailable_mcp",
|
|
1369
1402
|
]
|