ClaudeMods
☰
ZH-TW
● 0 人在線上 · 瀏覽 0 次
贊助提交作品
GitHub 儲存庫 · 發布者 KilimcininKorOglu

orphan-server

列出在此儲存庫中啟動並在連接埠上監聽的模型的 Bash 呼叫的伺服器,以及它們的年齡和會話,並使用 SIGTERM 停止,然後使用 SIGKILL 停止。

KilimcininKorOglu@KilimcininKorOglu

KilimcininKorOglu/claude-code-mods/tree/main/plugins/orphan-server

已翻譯

關於這個 mod

模型使用 (cmd &) 啟動開發伺服器,會話結束,伺服器保持其連接埠。幾天后,您得到 address already in use,沒有其他資訊告訴您伺服器仍在執行。該 mod 列出了在此儲存庫中啟動的模型的 Bash 呼叫並在連接埠上進行監聽的伺服器,以及它們的年齡和會話以及每個伺服器的停止按鈕。

它讀取偵聽 TCP 進程,僅將那些孤立的(父 1)保留在會話的 git 儲存庫中,將它們與記錄中的原始 Bash 呼叫進行匹配,並在側邊欄部分中顯示它們,每行有一個停止按鈕。停止發送 SIGTERM,然後在 5 秒後發送 SIGKILL。指令:/orphan-server、/orphan-server stop <pid>、/orphan-server on | off。達到L2;透過 claude plugin validate 進行驗證。

安裝

請先查看作者 README,確認 marketplace 與外掛名稱;指令可能隨儲存庫結構而變動。

claude plugin marketplace add KilimcininKorOglu/claude-code-mods
claude plugin install orphan-server
原文 / README

orphan-server

The model starts a dev server with (cmd &), the session ends, and the server keeps holding its port. Days later you get address already in use, and nothing else tells you the server still runs. This mod lists the servers a Bash call of the model started in this repository and left listening on a port, with their age and session and a stop button for each.

What it does

  1. At session start, at the end of each main-loop turn, every 60 s in an interactive session and at /orphan-server, the mod reads the processes that listen on a TCP port (lsof -nP -iTCP -sTCP:LISTEN). The 60 s scan shows a server another session left, or takes down the row of one stopped elsewhere, while this session is idle. A 60 s scan that fails logs its reason once, until a scan passes again.

  2. It keeps only a process whose parent is 1 (it outlived the shell that started it) and whose working directory is the session's git repository or a directory under it.

  3. It reads this repository's transcripts for the Bash call that started each one: a call that ran while the process started (after the model wrote it, before its result) and whose command holds the process's arguments. Only the transcript lines of the minutes that call can sit in are read, and each process is looked up once.

  4. The servers found stand in one sidebar section, oldest first, with a stop button each. In each row the ports are yellow, the age yellow and red past one day, and another session's id faint; this session stays in the default colour:

    :8787 Python -m http.server 8787 · 3h · session 450600b2
    [ stop :8787 ]
    

    While the sidebar is closed, one transcript line names them with their pids, once per set of servers, and the section is drawn at the next scan after the sidebar opens.

  5. The button runs /orphan-server stop <pid>. The mod reads the process again first; a pid that no longer belongs to the listed server (another parent, other arguments, another start time) gets no signal. Otherwise it sends SIGTERM, and SIGKILL after 5 seconds if the server still runs. A line says stopped :8787 ... with stopped green, or says the server still runs after SIGKILL, those words red.

Command

/orphan-server             reads the servers now and lists them with their pids
/orphan-server stop <pid>  SIGTERM, then SIGKILL after 5 s, to a listed server
/orphan-server on | off    on by default; off reads only at /orphan-server

Install

claude plugin marketplace add KilimcininKorOglu/claude-code-mods
claude plugin install orphan-server@kilimcininkoroglu-mods

Function hooks are early access. Claude Code 2.1.288 and later load them by default, so there is nothing to switch on.

After installing

  1. Restart Claude Code.
  2. Install the sidebar mod for the section and its stop buttons. Without it the mod writes one transcript line and /orphan-server stop <pid> stops a server.

What it can reach

Validated with claude plugin validate on Claude Code 2.1.284:

❯ ./register.ts hooks: session.start, command.run{command=orphan-server}, turn.complete
❯ ./register.ts calls: $.clock.after (via later, stop), $.clock.every, $.clock.now (via listenersIn, readProc, runCommand, show, toSidebar), $.command.register, $.env.get, $.process.run (via output, rootOf), $.session.id, $.sidebar.clear (via toSidebar), $.sidebar.set (via toSidebar, toStream), $.store.get (via readSettings), $.store.set (via setEnabled), $.ui.log (via later, show, stop, tick, toStream)
❯ ./register.ts env writes: nothing
❯ ./register.ts env reads: CLAUDE_CONFIG_DIR, HOME

Reach L2, it runs processes and sends signals.

1. Reads:    the listening TCP processes (pid, ports, parent, age, arguments, working directory), and the transcript lines of this repository's sessions for the minutes around each one's start
2. Runs:     git rev-parse --show-toplevel once per session; lsof, ps and grep at session start, at each turn's end, every 60 s in an interactive session and at /orphan-server; kill -TERM and kill -KILL for a server you stop
3. Sends:    nothing to the model and nothing to the network
4. Persists: in $.store, the on/off setting
5. Hostile input: a process's arguments and a transcript's commands are drawn as text and compared as text, never run; the pid of a stop is read again before a signal is sent

Limits

  • Only the transcripts of the repository root and of the session's start directory are read. A server that an old session opened in another subdirectory started is not listed.
  • A server started through a wrapper that still runs (npm run dev, make serve) is not listed, because its parent is the wrapper and not 1.
  • The match is by time and command text. Two processes started in the same call with the same arguments read as one server each, and both are listed.
  • A process with arguments shorter than 3 characters is never matched.
  • A server you started by hand outside Claude Code is never listed, because no transcript holds its Bash call.
  • lsof and ps answer for your own processes only.

Development

make install     # eslint, typescript-eslint, typescript
make lint        # complexity limit 10, the build fails above it
make typecheck   # needs .claude/types/ from /plugin-types
make validate
make test        # claude plugin test

更多類似作品