Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/seahaven/cli/templates/base/AGENTS.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ db_schema_and_fixtures.md, clock.md, testing.md, state.md, reference/lints.md; c
this world adds other worlds.

Commands: `uv run seahaven check` (lint; run before every commit), `uv run pytest`,
`uv run seahaven fixture list`, `uv run seahaven serve`.
`uv run seahaven fixture list`, `uv run --extra serve seahaven serve`.

Rules: time comes from `ctx.clock` and ids and randomness from `ctx.ids`, so a replay of the same
fixture and seed on a `fixed` or `tick` clock gives the same result; SQL goes through `ctx.db`
Expand Down
2 changes: 1 addition & 1 deletion src/seahaven/cli/templates/base/README.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ with $package.world.instance(None) as instance:
instance.call("get_item", item_id=item["id"])
```

Serve it over OpenEnv with `uv run seahaven serve`, and run its tests with
Serve it over OpenEnv with `uv run --extra serve seahaven serve`, and run its tests with
`uv run pytest`.

## Making a fixture
Expand Down
27 changes: 27 additions & 0 deletions tests/test_cli_new.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""

import os
import re
import shlex
import subprocess
import sys
Expand Down Expand Up @@ -116,6 +117,32 @@ def test_the_scaffold_declares_the_conflict_between_serve_and_mcp(scaffold: Path
)


def test_the_scaffold_docs_run_each_server_with_its_extra(scaffold: Path) -> None:
"""Every `uv run seahaven serve` or `seahaven mcp` in the world's docs passes its extra.

The next steps `seahaven new` prints say `uv sync`, which installs no extra,
so a bare `uv run seahaven serve` after it fails with "needs the serve extra".
Each server command is named after the extra it needs.
"""
servers = {"serve", "mcp"}
commands = [
shlex.split(span)
for page in ("README.md", "AGENTS.md")
for span in re.findall(r"`(uv run [^`]+)`", (scaffold / page).read_text(encoding="utf-8"))
]
runs = [
(command, command[at + 1])
for command in commands
for at, word in enumerate(command[:-1])
if word == "seahaven" and command[at + 1] in servers
]
assert runs, "the scaffold's docs run no server, so this test is asking the wrong question"
for command, extra in runs:
assert f"--extra {extra}" in shlex.join(command), (
f"{shlex.join(command)!r} lacks --extra {extra}"
)


def test_the_scaffold_installs_pytest_with_uv_sync(scaffold: Path) -> None:
"""The next steps say `uv run pytest`, and seahaven does not depend on pytest.

Expand Down
Loading