Skip to content
claudewheel.processes
Edit
On this page

Measures the resident memory of every process holding a profile in one batched ps call, and stops a holder by the mechanism its kind calls for.

#claudewheel.processes

#claudewheel.processes

Measure and stop the processes holding a profile.

The deletion checklist shows every live process registered under a profile and stops the ones the user ticks. Both halves of that need the world -- reading resident memory, running Claude Code's own daemon-stop command, sending a signal -- so both halves live here, behind :mod:claudewheel.effects.

Resident memory ---------------

ps -o pid=,rss= is the portable answer: it reports KiB on Linux and on macOS, needs no third-party package, and one invocation can measure every pid at once. Three rules the parser keeps:

  • One call for all pids. A per-row call would be one process spawn per

session block, on every refresh.

  • **pid= is always requested.** ps does not answer in argument order, so a

row is only interpretable next to the pid it belongs to.

  • A missing row means the process is gone. ps simply omits a pid it cannot

find, so the pid is absent from the result rather than present with a zero.

Resident memory is never summed across a process tree: shared pages would be counted once per member, and the total would exceed the machine's memory.

Stopping --------

Two mechanisms, chosen by the record's kind rather than by trying one and falling back to the other:

  • The daemon is stopped through Claude Code's own

claude daemon stop --any --keep-workers. The daemon is addressed per config directory: the client derives its runtime socket directory from a hash of the resolved config dir (/tmp/cc-daemon-<uid>/<hash>), so running the command with CLAUDE_CONFIG_DIR pointing at a profile stops that profile's daemon and no other. --keep-workers is always passed, so a detached session the user did NOT tick is never taken down as a side effect of stopping the supervisor -- the checklist stops exactly what was ticked.

  • Everything else -- a daemon worker, a background job, an interactive

session -- gets a SIGTERM to its own pid.

Both go through the effects seam, so a --dry-run deletion records the stops it would perform instead of performing them.

#resident_memory

python
def resident_memory(pids: Iterable[int]) -> dict[int, int]

Resident set size in KiB for each of pids, measured in one ps call.

A pid ps did not report is absent from the mapping: the process is gone (or was never ours), and inventing a zero for it would draw a live row with no memory. A platform with no ps, an unparseable row and a preview that recorded the call instead of running it all yield the same thing -- no measurement for that pid, so the caller simply draws no memory clause.

#stop_daemon

python
def stop_daemon(binary: Path, config_dir: Path, *, env: Mapping[str, str]) -> bool

Stop the Claude Code daemon owning config_dir. True when it worked.

env is the environment the command inherits with CLAUDE_CONFIG_DIR forced to config_dir -- that variable is the whole addressing scheme (see the module docstring), so it is set here rather than left to the caller's ambient environment.

#terminate

python
def terminate(pid: int) -> bool

Send SIGTERM to pid. True when the signal was delivered or moot.

A process that has already exited is not a failure: the checklist's goal is "this no longer holds the profile", and a dead process meets it. A signal we are not allowed to send is a failure, because the process really is still there.

#wait_for_exit

python
def wait_for_exit(pid: int, *, timeout_s: float=EXIT_TIMEOUT_S, poll_s: float=EXIT_POLL_S, alive: Callable[[int], bool]=alive, sleep: Callable[[float], None]=time.sleep, now: Callable[[], float]=time.monotonic) -> bool

Poll until pid is gone. True when it went, False on timeout.

The clock, the sleep and the liveness probe are all parameters so the poll is exercisable without a real process and without real time passing.

More tools from this site

  • claudestream Drive Claude Code from Python: run it as a subprocess and read its output as typed events, with async and sync sessions, sandbox policies, and tools you define in Python
  • dirstat Fast, single-binary directory statistics CLI: every file under a tree grouped by format, with counts, sizes, and lines of code, as a colored terminal table or as JSON
  • fastware A batteries-included ASGI framework: msgspec JSON, a managed Granian server, dependency injection, SSE, WebSockets, auth, and a test client
  • go-toml-edit Zero-dep TOML editing library for Go with comment preservation
  • howmuchleft The fastest Claude Code statusline: context window, 5-hour, and weekly limit usage as three customizable gradient bars, rendering in about 6 ms
  • orxtra
  • pgdesign
  • predraw Declarative rendering pipeline: describe a scene in JSON and get SVG, PNG and WebP out, with light and dark style tokens, reusable components and text converted to path outlines
  • reposummary Turn a git repository's history into a Markdown journal: pick a time window or revision range and get a readable digest of what changed, optionally narrated by an LLM
  • rlsbl Release orchestration and project scaffolding CLI that bumps versions, validates a structured JSONL changelog, tags only the commit CI verified, and publishes to npm, PyPI, Go and more
  • safegit git wrapper CLI that gives each commit its own temporary index and retries ref updates on conflict, so concurrent agents share one repository
  • saferm Command-line replacement for rm that archives every deletion with a mandatory reason and the context it ran in, so deleted files can be listed, inspected and restored
  • selfdoc Static Site Generator that builds a project's documentation site directly from its source code, so the docs can never drift from the code they describe, with SEO/AEO, first-class blog, search, and cross-project linking built in
  • strictcli
  • stricttest An always-on test-isolation floor: a pytest plugin and a Go env-hygiene module that make a test suite structurally unable to reach real credentials, the real HOME, the network, or the development repository.
  • wesktop A Python framework that turns an ASGI web app into a desktop application, serving it from a local Granian server and displaying it in a native OS window via pywebview
Search