doorstop-vscode-server
A small FastAPI server that wraps the Doorstop Python API directly (instead of shelling out to the doorstop CLI). It is designed to serve exactly one client — the Doorstop VS Code extension — and answers requests strictly one at a time; there is no concurrent request handling.
Install (editable, for development)
pip install -e .[dev]
Run
python -m doorstop_server --project <path-to-doorstop-project-root> --host 127.0.0.1 --port 7867
or, after installing:
doorstop-vscode-server --project <path-to-doorstop-project-root> --host 127.0.0.1 --port 7867
API
See src/doorstop_server/routers/ for the endpoint implementations. GET /health is the only route that is not serialized behind the request lock.
GET /tree— every document with its items in Doorstop's own order (level, then UID); inactive items included (routers/tree.py)POST /documents/{prefix}/items— create an item; optionallevel, orafter(UID of an item of the same document: the new item gets Doorstop's "append after" level and the followers are renumbered), plusheader/text(routers/documents.py)PATCH /items/{uid}— setheaderand/ortextthrough Doorstop's own setters, one file write (routers/items.py)DELETE /items/{uid}— remove the item and renumber the document likedoorstop remove(routers/items.py)
Tests
The test suite exercises the real FastAPI app against a temporary Doorstop project (no mocking of Doorstop itself), so it doubles as a pinned-down contract for the HTTP interface — every request/response shape, status code, and error format a test asserts on is something the extension can rely on.
pip install -e .[dev]
pytest
tests/conftest.py— shared fixtures (client,project_root,document) and aset_item_texthelper for mutating an item directly via the Doorstop API (bypassing the server) to simulate out-of-band edits.tests/test_serialization.py— proves the one-request-at-a-time guarantee black-box: fires concurrent/itemscalls and checks for zero UID collisions/gaps, rather than inspecting the lock directly.tests/test_errors.py— pins down the structured{"error": {"code", "message"}}shape for both expected (DoorstopError) and unexpected exceptions.
Doorstop version coupling
src/doorstop_server/validation_rules.py recognises Doorstop's validation
output by matching its message wording, because Doorstop 3.2 yields issues
as bare DoorstopError / DoorstopWarning / DoorstopInfo objects carrying
nothing but a string - no check id, no item reference, no field.
CHECK_TABLE in that file is therefore pinned to Doorstop 3.2. On a Doorstop
upgrade, re-check it: run the test suite first (several tests assert exact
check ids against real Doorstop output and will fail loudly if the wording
moved), then compare against contracts/validation-api.md section 2 in the
extension repo.
Two things limit the damage of a missed change:
- An unmatched message is never dropped. It is returned as
check: "unknown"withfield: nullat Doorstop's own severity, so the user still sees the problem - only its placement degrades to the item's first line. - The coupling lives in exactly one named file.
GET /validate must also keep running under read_only_validation(). Doorstop's
validation rewrites requirement files with its shipped defaults: a plain
get_issues() pass over a 9-item project rewrote 7 files and silently stamped
away a suspect link instead of reporting it. test_validate_writes_nothing
is the regression test for this.
Metadata
Release files for doorstop-vscode-server 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| doorstop_vscode_server-0.2.0.tar.gz | 37.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| doorstop_vscode_server-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 63.9 kB
Release files / doorstop_vscode_server-0.2.0.tar.gz
| Download URL | doorstop_vscode_server-0.2.0.tar.gz |
|---|---|
| Size | 37.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
411b210587f8d7e5acf214283b4f117b8e6510482eaabf271ae93d062b82025f
|
|
BLAKE2b-256 checksum How to use checksums |
9823172ccddba5329c146b0efecc8123a2482f4b7b424eea386e6e575b26b9e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.
Transparency logRelease files / doorstop_vscode_server-0.2.0-py3-none-any.whl
| Download URL | doorstop_vscode_server-0.2.0-py3-none-any.whl |
|---|---|
| Size | 26.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
23dd03e137566ae2ba11c0a66eec1479d0a52a7bc496272c904f91cc126261e0
|
|
BLAKE2b-256 checksum How to use checksums |
ea7590e59e2df86335610e3991ef96dbe88cbcc98572a9dfb53883d7feb22135
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.
Transparency log