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

@m1kad0/hannah-proto

v5.4.0

Published

Generated TypeScript gRPC-js client stubs for the Hannah voice assistant proto schema

Readme

hannah-proto

Protobuf/gRPC schema definitions for the Hannah voice assistant ecosystem (Core, satellites, WebUI, ioBroker adapter, Telegram bot, and other consumers). This repo is the single source of truth for the wire protocol shared across all of them.

The .proto files live under hannah/ (per API generation in hannah/v2/ and hannah/v1/), one per functional area — satellite control, event streaming, the ioBroker agent bridge, user registry, timers, automations, and so on. Nothing here is application code, just schema.

Distribution

Three independent, tag-triggered publish targets — pick whichever matches your language. Each contains only generated gRPC stubs/types for the current tagged release.

| Language | Package | Install | |------------|------------------------------------------|---------------------------------------------| | Python | PyPI hannah-proto | pip install hannah-proto | | TypeScript | npm @m1kad0/hannah-proto | npm install @m1kad0/hannah-proto | | Go | github.com/NurPech/hannah-proto-go | go get github.com/NurPech/hannah-proto-go |

Go has no separate package registry, so that tagged GitHub repo is the package — go get resolves it directly.

API generations: hannah.v1 and hannah.v2

The schema lives in versioned packages side by side:

| Package | Files | Status | |---|---|---| | hannah.v2 | hannah/v2/*.proto | current generation (N) — all changes go here | | hannah.v1 | hannah/v1/*.proto | frozen (N−1), kept so older components keep working |

The unversioned hannah package is gone since hannah.v2: a generation older than N−1 is removed. Only hannah/options.proto (the compat_version extension) is left in hannah/, shared by both generations and not copied.

Both carry the same services, but under different gRPC method paths (/hannah.v2.HannahService/... vs /hannah.v1.HannahService/...), so a server can serve both at once and gRPC routes each call to the right one. Hannah Core serves the current generation and the one before it (N and N−1, never more). Clients use the current generation and fall back to the previous one if Core answers UNIMPLEMENTED (Core too old).

A breaking change never happens inside a generation — it starts the next one (hannah.v3), and the oldest one is removed. The API generation is independent of the package version: hannah.v2 ships in 5.x, hannah.v1 in 4.x and 5.x.

| Language | Current generation (N) | Previous generation (N−1) | |---|---|---| | Python | from hannah_proto.v2 import hannah_pb2 | from hannah_proto.v1 import hannah_pb2 | | TypeScript | import { v2 } from '@m1kad0/hannah-proto' → v2.agent.AgentMessage | import { v1 } from '@m1kad0/hannah-proto' | | Go | github.com/NurPech/hannah-proto-go/v5/hannahv2 | github.com/NurPech/hannah-proto-go/v5/hannahv1 |

CI rejects any change under hannah/ outside hannah/v2/ (deletions are allowed — that is how an old generation leaves).

What hannah.v2 changes against hannah.v1

  • Typed device model (hannah/v2/device_model.proto): Hannah defines fixed device classes (DeviceClass) with slots (SlotKind, Slot, SlotValue) and their scales and units. The ioBroker adapter maps ioBroker objects onto them, normalizes the values and writes slot commands (SetSlot) back to the real states; Hannah Core never sees ioBroker state IDs for devices. The agent stream carries TypedDeviceSnapshot, SlotUpdate and DeviceAvailability (adapter → Core) and SetSlot (Core → adapter); GetDevices/ControlDevice work on slots.
  • Removed: the state-based device model (AgentDevice, AgentDeviceSnapshot, canonical_key, StateType, EnumValues), AgentSetResident.presence_state, all reserved entries and all compat_version options (a new generation starts at the implicit 1). AgentStateUpdate, AgentSetState and AgentWatchMore stay for arbitrary watched states.
  • Field numbers of a changed message are not reused with another meaning inside the same lineage (DeviceInfo, ControlDeviceRequest), so bytes of one generation are never silently misread as the other. Between the generations, methods whose messages differ need a real translator, not a byte bridge.

Versioning: PROTO_VERSION

Alongside the semver package/tag version, every release carries a single-integer PROTO_VERSION (see the PROTO_VERSION file). Hannah Core and its clients exchange this value on every call and reject a mismatch at runtime — that's the actual compatibility gate, not the semver tag. A breaking schema change requires bumping PROTO_VERSION; CI enforces this on every merge request via buf breaking.

Per-message compatibility: compat_version

PROTO_VERSION is repo-wide — any breaking change anywhere bumps it, forcing every consumer to reject, even ones that never call the affected RPC. compat_version (options.proto) is a finer-grained, independent counter set on an individual message:

message Foo {
  option (compat_version) = 2;
  ...
}

Bump a message's compat_version only when that specific message has an actual breaking change. A message with no compat_version option carries an implicit value of 1 — don't backfill the option onto messages that have never had a breaking change. This lets a consumer-side interceptor check only the messages a given RPC call actually uses instead of rejecting on any unrelated proto change.

Deprecating fields and RPCs

Don't remove a field or RPC the moment it's unused — that forces every consumer to bump immediately, even ones that never touched it (see the SetGroupRooms incident that forced 9 unrelated components to bump, hannah-proto#9). Instead:

  1. Mark it deprecated = true (protobuf's built-in field/method option) and note why + what replaces it in a comment.
  2. Leave it in place until the next planned major cleanup, not the next release.
  3. Actually remove it (a breaking change, PROTO_VERSION bump) only during that cleanup, batched with other accumulated deprecations rather than one at a time.

Go/TypeScript/Python codegen surface deprecated = true automatically (Go doc comment, TS @deprecated JSDoc) — no extra tooling or config needed.

Compatibility checks

CI runs buf lint and buf breaking (against origin/master) on every MR. To check a local branch against a specific released version:

buf breaking --against '.git#tag=vX.Y.Z'

Changelog

See CHANGELOG.md for what changed release to release, including breaking changes and the consumers they affect.