Skip to content

sp-canvas status reports guessed state, not the running server's #105

Description

@Jing-yilin

What happened

sp-canvas status prints a canvas's state without ever consulting the server it is
reporting on. Both lines below it are guesses, and both can be wrong in ways that
send you off debugging the wrong thing.

Two separate defects, same function (cmd_status):

1. The boards line follows the caller's cwd, not the running server

A canvas started with an explicit --canvases path reports a different boards
directory depending on where you ask from — and none of the answers is the one it
is actually serving:

$ cd ~/proj && sp-canvas start --port 5174 --canvases prototypes/mockups/canvases
boards   /home/me/proj/prototypes/mockups/canvases     # correct, at start

$ cd ~/proj       && sp-canvas status --port 5174
boards would be /home/me/proj/mockups/canvases          # wrong
$ cd /tmp         && sp-canvas status --port 5174
boards would be /tmp/mockups/canvases                   # wrong
$ cd ~/other-repo && sp-canvas status --port 5174
boards would be /home/me/other-repo/mockups/canvases    # wrong

cmd_status recomputes the path from the calling process instead of reading it
back from the server:

# sp_canvas.py, cmd_status
print(f"boards would be {_canvases_dir(a.canvases)}")

# _canvases_dir — resolves against the current process's cwd/args/env
raw = arg or os.environ.get("PROTOTYPING_CANVASES_DIR") or "mockups/canvases"
return Path(raw).expanduser().resolve()

The value is already known at start time — cmd_start holds boards and passes it
to the child as PROTOTYPING_CANVASES_DIR — but the pidfile only keeps the pid:

_pidfile(a.port).write_text(f"{proc.pid}\n")

The phrasing "boards would be" is accurate when nothing is running, and that
case is genuinely useful. The problem is that the same line prints verbatim under
port 5174: answering, where readers take it as a description of the live server.

This is not hypothetical: it cost me a real debugging detour. I had two canvases up
on different ports and used status to work out which one was serving my project's
boards. It confidently pointed at a directory that did not even exist. Reading
PROTOTYPING_CANVASES_DIR off the process (ps -E -o command -p <pid>) gave the
right answer immediately.

2. status treats any listener on the port as a canvas

cmd_status only calls _port_answers(), a bare connect_ex. Anything answering
is reported as ours, including the tmux session line — for a session that does not
exist:

$ python3 -m http.server 5999 --bind 127.0.0.1 &
$ sp-canvas status --port 5999
port 5999: answering
  http://127.0.0.1:5999/
session  canvas-5999                       # no such tmux session
boards would be /home/me/whatever/mockups/canvases

cmd_stop gets this right — it checks the pidfile, drops stale pids, and says so
when the port belongs to someone else:

(something else is answering on {port} — left alone)

start is careful here too, refusing to reuse a port that already answers because
it may be another checkout's canvas. status is the one command that will tell you
a stranger's server is yours.

Where

  • Canvas or skill: sp-canvas CLI (tools/), cmd_status
  • Hosted or local dev server: local dev server
  • Browser / device / OS: n/a (CLI); macOS 15.1, Darwin 25.1.0
  • Versions: plugin 1.4.1, toolkit 1.4.1 (sp-canvas root -v)

How to reproduce

Defect 1

  1. cd ~/proj && mkdir -p prototypes/mockups/canvases
  2. sp-canvas start --port 5174 --canvases prototypes/mockups/canvases — note the
    boards line it prints, which is correct
  3. sp-canvas status --port 5174 from ~/proj, then from /tmp, then from any
    other directory
  4. Each run reports a different boards path; none matches step 2

Defect 2

  1. python3 -m http.server 5999 --bind 127.0.0.1 &
  2. sp-canvas status --port 5999
  3. It reports session canvas-5999 and a boards path for a server that has nothing
    to do with sp-canvas

Suggested fix

Both come down to status reporting what it guessed rather than what is running.

  • Have cmd_start write the boards path into the pidfile next to the pid (or a
    sibling file), and have cmd_status read it back when the port answers. Reading
    PROTOTYPING_CANVASES_DIR from the live process works too and needs no format
    change, at the cost of being platform-specific.
  • Reuse the pidfile/stale-pid check cmd_stop already has, so status can
    distinguish "our canvas", "a stale pidfile", and "something else is on this port".
  • Keep boards would be ... for the not-running case — it answers a real question
    ("what would start pick up from here?"). Print the server's actual directory
    when one is answering.

Happy to send a PR if the approach looks right.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions