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

@miadi/tide

v0.1.2

Published

Typed client boundary for the ironsilk `tide` runtime. Daemon Unix-socket transport with CLI fallback.

Readme

@miadi/tide

Typed client boundary between Miadi and the ironsilk tide runtime (historically hermes-navigator). The single place the web app talks to tide — replacing the per-route exec("/home/jgi/anaconda3/bin/tide …") calls.

Grounded in foundations/terminal-workspace-orchestration/ (Decision C) and rispecs/tide-runtime/05-ui-surface.spec.md (daemon-socket transport).

Runtime dependency — install tide

This package is a client; it does not bundle the runtime. The tide CLI is the console entry point of the ironsilk PyPI package ([project.scripts] tide = hermes_navigator.cli:main). Install / upgrade it in the Python env the Next.js server can reach:

pip install -U ironsilk      # provides the `tide` CLI (currently 0.9.13)
tide --help                  # verify

Source for the runtime lives at /usr/local/src/ironsilk/runtime/ (editable: pip install -e .). @miadi/tide resolves the binary via TIDE_BINwhich tide → legacy /home/jgi/anaconda3/bin/tide; set TIDE_BIN when tide is outside the server's PATH. The daemon socket is resolved separately via TIDE_SOCKET (see below).

Verbs

import { getContext, getTerminals, detect, peek, steerProposal, send, sendKeys, buildSendKeysPlan, pingDaemon, describeTransport, TideError } from "@miadi/tide"

const snapshot  = await getContext()          // R2 live context (daemon socket → CLI fallback)
const terminals = await getTerminals()        // operator terminals inventory (CLI, read-only)
const match     = await detect({ pane: "56" })// R1 domain detection for a pane/cwd → match | null (CLI)
const scroll    = await peek("56", 80)        // operator peek %56  (CLI)
const proposal  = await steerProposal("56", "continue from checkpoint")  // (CLI)
const sent      = await send("56", "continue") // guarded --run, controller mode (CLI)

// Direct, simple steer transport — `tmux send-keys` via execFile (no shell, no Python):
const keyed     = await sendKeys("56", "continue")                 // types text + Enter
const noEnter   = await sendKeys("56", "ls -la", { submit: false })// types text, leaves it unsubmitted
const plan      = buildSendKeysPlan("56", "ls -la", false)         // pure dry-run plan (no execution)

const up   = await pingDaemon()              // daemon liveness (ping → pong)
const how  = describeTransport()             // { transport: "socket"|"cli", socketPath, socketAvailable }

sendKeys — the operator cockpit's primary steer path

sendKeys(pane, message, { submit }) drives tmux send-keys directly through execFile with argument arrays (no shell, no escaping, no Python spawn, no reviewed-proposal artifact) — the simple, robust transport behind POST /api/tide/steer. submit (default true) controls the trailing Enter (C-m): set it false to type content into the pane and leave it on the prompt for a human to review and submit. buildSendKeysPlan(...) returns the exact tmux argv pair without executing — used for the cockpit's inline command preview. The tmux binary is resolved via TIDE_TMUX_BIN -> tmux on PATH.

getTerminals and detect are the read-only surface behind GET /api/tide/terminals and GET /api/tide/detect — the typed half of operator-terminal triage and manual domain assignment (jgwill/Miadi#382). The write-back half (assign a pane to a domain) is deferred to the runtime + a guarded route.

Transport status

| Layer | Status | |---|---| | One-shot CLI (tide … --format json, execFile arg-arrays, no shell) | implemented | | Daemon + Unix-domain-socket transport (hermes.navigator.daemon.v1) | implemented (src/socket.ts) | | Schema-first contract (tide-api.schema.json → generated types) | planned |

How transport selection works

getContext() is transport-aware:

  • auto (default): use the daemon socket if it is up; on absence or daemon error, fall back to the CLI. No Python spawn on the hot path when the daemon is running (~µs socket round-trip vs ~200–500 ms CLI spawn).
  • socket: daemon only — throws TideDaemonError if unavailable.
  • cli: force the CLI.

peek / steerProposal / send are CLI-only: the daemon exposes get_context / ping / detect, not the operator mutation verbs. sendKeys is independent of both — it talks to tmux directly. They join the socket path when the runtime adds those actions — verb signatures are the stable surface; only the transport underneath changes.

Wire protocol (mirrors hermes_navigator/daemon.py)

Newline-delimited JSON over a Unix socket. Request {contract_version:"hermes.navigator.daemon.v1", request_id, action, payload}{contract_version, request_id, ok:true, data} (or ok:false, error:{code,message,retryable}}).

Socket path resolution

TIDE_SOCKET (explicit) → ${HNAVIG_HOME || HERMES_HOME || ~/.miadi/navigator}/daemon.sock (mirrors the runtime's get_config_dir()). Binary resolution for the CLI fallback: TIDE_BINwhich tide → legacy /home/jgi/anaconda3/bin/tide.

Operator-cockpit surface (next)

describeTransport() + pingDaemon() are the building blocks for a GET /api/tide/health endpoint so a Hermes/Ava/Miadi session can see which transport is live and whether the daemon is answering before it reads context or proposes a steer. See the foundations plan.

Tests

cd packages/tide && npm test

Compiles src + test to /tmp/miadi-tide-test (CJS) and runs node --test. The suite proves socket selection and CLI fallback with a fake Unix-socket daemon and a fake tide binary — no live daemon, no live tide required.

App wiring (current)

Resolved as source via a tsconfig.json path alias ("@miadi/tide": ["./packages/tide/src/index.ts"]) — same pattern as @miadi/a2a-contracts, no pnpm install, no lockfile change. Switch to a workspace:* dependency + dist/ build when a real build step is introduced.