npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mobius-os/mobius

v0.3.9

Published

Mobius terminal client. Reuses Mobius frontend TypeScript types and jsonl entry shapes.

Readme

Mobius

A terminal client for Mobius, written in Node + TypeScript + Ink (React for CLIs). It reuses the web frontend's TypeScript domain types and jsonl entry shapes verbatim, and drives the same backend HTTP + SSE API the web UI uses.

mobius/tui/
  src/
    main.tsx              entry — Ink render, exitOnCtrlC disabled
    App.tsx               route machine: login → prep → chat (+ resume)
    config.ts             ~/.mobius/{login,projects,dir2project,dir2project_preference}.json
    api.ts                MobiusClient — all HTTP endpoints (bearer auth)
    sse.ts                SseConnection — streaming fetch SSE frame parser
    markdown.ts           terminal markdown (marked lexer + cli-highlight + chalk)
    types.ts              domain + jsonl entry types (copied from frontend)
    lib/entry-view.ts     jsonl entry → renderable view (copied classify fns)
    hooks/useChat.ts      one session: lazy create + SSE + send
    components/
      primitives.tsx      TextInput / Select (single+multi) / Spinner
      Login.tsx           server + username + optional password
      PrepScreen.tsx      project picker + preference wizard (issue→model→language→skill→memory)
      Chat.tsx            viewport-aware transcript + welcome card + composer/status
      ResumePicker.tsx    /resume — 32 most-recent project sessions
  tests/
    integration.test.ts   real backend end-to-end (your server)
    ui.test.tsx           ink-testing-library + mocked fetch/SSE
  bin/mobius-tui.js       launcher

Run

cd mobius/tui
npm install --include=dev      # NODE_ENV=production prunes devDeps → must pass --include=dev
npm start --silent             # suppress npm's script banner
# or (cleanest): ./bin/mobius-tui.js

On first launch there is no ~/.mobius/login.json, so the login screen appears. Enter your Mobius server URL and username (most servers are passwordless). On success the token is saved and the next launch auto-logs in (validated via /api/auth/me; re-login on expiry).

After a successful login the TUI also starts its local AIMUX reverse connection in the background. The first run creates ~/.mobius/aimux-venv and installs the aimux Python package, then runs:

aimux reverse connect <server>/aimux_bridge --identifier tui-<hostname> --token <jwt> --replace

Python 3.10+ is discovered from MOBIUS_TUI_PYTHON, python3/python (or Windows py). If none is available and uv is installed, the TUI runs uv python install 3.11 for a user-local interpreter. Set MOBIUS_TUI_DISABLE_AIMUX=1 to opt out, for example on a machine that should only use the web API. A failed child is retried automatically with exponential backoff; AIMUX installation or connection failures do not prevent the chat client from opening. Python discovery, virtual-environment creation, pip download progress, bridge heartbeat state, and reconnect attempts remain visible in the TUI status area while the rest of the client stays usable.

Once started, a background heartbeat checks /aimux_bridge/api/remotes/<identifier>/connection every five seconds with the current Mobius JWT. Three consecutive failed checks terminate the stale AIMUX child and reconnect with 1/2/4/8/15-second capped exponential backoff. A successful bridge heartbeat resets the backoff and changes the status indicator to green.

Flow

  1. Login — server / username / password → POST /api/auth/login → save ~/.mobius/login.json.
  2. Prep
    • read cwd; look up dir2project.json[cwd].
    • if unbound → pick an existing project or create one (bound to cwd).
    • preference wizard, stepped only through what's missing: Issue (task)modellanguageskillsmemories. Preferences are stored inside the selected issue, so switching issues restores that issue's choices.
  3. Chat: startup identity/context card, viewport-aware transcript, composer, and persistent model/project/task status at the bottom. The final line always shows the current web issue/session URL as an OSC 8 hyperlink, so supported terminals can open the matching Mobius page directly (the URL remains visible and copyable everywhere).
    • The first submitted message lazily creates a session (POST /api/issues/:iid/sessions) with the saved preferences, opens the SSE stream (GET /api/sessions/:id/events?token=), and posts the message. The session carries pc_client_metadata with is_tui: true, the local AIMUX identifier and current directory; TUI sessions always default to PC mode and always include the mobius-aimux Skill.
    • jsonl_entry events append to the transcript as they arrive; the view keeps recent output inside the current terminal height instead of mixing permanent <Static> rows with dynamic UI.
    • The typing event drives the working indicator. Press Esc (or Ctrl+C) to interrupt a running turn.
    • Slash commands: /clear (new session), /resume (history), /help, /quit. Ctrl+C stops a running turn, or quits when idle.

Reusing the web frontend

The domain interfaces (User, Project, Issue, Session, Message, SessionModelOption) are copied from frontend/src/store.ts; the jsonl entry / render-block types from frontend/src/components/viewer/types.ts; and the pure helpers assistantResponseText, assistantEntryText, entryUserText and the noise predicates from frontend/src/components/viewer/entry-classify.ts. api.ts mirrors the frontend's api() helper (Authorization: Bearer, JSON).

Backend contract notes (gotchas)

  • Sessions are created under issues, not projects: POST /api/issues/:issueId/sessions.
  • Issue title field is title; session name field is name.
  • Worktree flag is use_worktree (issues) / defaultUseWorktree (projects).
  • Skill/Memory preferences are exclusion lists (excluded_skill_ids / excluded_memory_ids); omitting = everything enabled.
  • Model field is a short key from GET /api/sessions/model-options.
  • No SSE done/tool_call events — everything is a jsonl_entry carrying a raw Claude/Codex SDK entry; turn-end = typing active:false.

Test

npm run typecheck
npm run test:ui            # mocked fetch + fake SSE, no network
MOBIUS_TUI_WAIT_MS=90000 npm run test:integration   # real backend (your server)
npm test                   # all three

Build an installable package

From the repository root:

python3 build.py --build-tui

To build and immediately install the global command into the current user's ~/.local prefix:

python3 build.py --build-tui-and-install

For CI or a custom location:

python3 build.py --build-tui-and-install --tui-install-prefix /custom/writable/prefix

The command runs the TUI typecheck and AIMUX regression tests, then writes an installable npm package plus checksum metadata to mobius/tui-builds/:

mobius-tui-<version>.tgz
mobius-tui-<version>.tgz.sha256
manifest.json

Install it without sudo and without writing to /usr/local:

npm install --global --prefix "$HOME/.local" \
  /path/to/mobius/tui-builds/mobius-tui-<version>.tgz
export PATH="$HOME/.local/bin:$PATH"
mobius

If the PATH export is not already in the shell profile, add it to ~/.bashrc once. Using the explicit user prefix avoids the EACCES ... /usr/local/lib/node_modules/mobius error produced by a root-owned npm global prefix. The source and built package both declare tsx as a runtime dependency, so production/global installs can execute the TypeScript entry point without retaining the source checkout's devDependencies.