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

nature-remo-cli

v0.1.1

Published

A type-safe, agent-friendly CLI for the Nature Remo API.

Readme

nature-remo-cli

An unofficial CLI and TypeScript client for the Nature Remo API.

Installation

Requires Node.js 24.11.0 or newer. macOS and Linux are supported; Windows is not tested. mise, Bun, and Vite+ are development tools and are not required to use the npm package.

npm install --global nature-remo-cli
nature-remo --version
nature-remo --help

For the TypeScript client, install it in your application instead:

npm install nature-remo-cli

The client uses ESM imports. The CLI supports appliance discovery, air conditioners, learned infrared signals, TVs, lights, Remo names and sensor offsets, Homes, and the authenticated User. Other API operations are outside the supported command surface; API coverage records their status.

Authentication

Create an access token at home.nature.global, then enter it into the masked prompt to store it in the macOS Keychain:

nature-remo auth login

The environment takes precedence over Keychain, which keeps CI, non-interactive use, and one-off overrides explicit. Linux requires NATURE_REMO_ACCESS_TOKEN; auth login and auth logout manage macOS Keychain only. Do not pass access tokens as command arguments or store them in the repository. Keychain synchronization through iCloud is not enabled.

Inspect or remove the stored credential without printing it:

nature-remo auth status
nature-remo auth logout

Usage

List appliances as a human-readable table:

nature-remo appliance list

Use JSON for scripts and coding agents:

nature-remo appliance list --format json

Inspect and configure Nature Remo controllers:

nature-remo remo list
nature-remo remo appliances
nature-remo remo rename --name "Living room Remo"
nature-remo remo set-temperature-offset --offset -0.5
nature-remo remo set-humidity-offset --offset 2

Remo reads require basic.read; rename and sensor-offset commands require basic.read and basic.write because --remo resolves an ID or name. TypeScript callers that already know the Remo ID can pass { id } to write with basic.write alone.

Inspect or control an air conditioner. The appliance selector is optional when only one air conditioner is configured:

nature-remo aircon list
nature-remo aircon set --temperature 26.5 --mode cool
nature-remo aircon set --appliance "Living room" --volume auto --direction swing
nature-remo aircon off

Air conditioner reads report the latest settings recorded by Nature Remo. Successful control JSON includes accepted: true, confirmed: false, and the API's returned Appliance under appliance; infrared transmission does not provide confirmation from the air conditioner itself.

List and send learned infrared signals. Appliance and signal names use case-insensitive exact matching:

nature-remo signal list --appliance "Living room"
nature-remo signal send --appliance "Living room" --signal-name "Power"
nature-remo signal send --signal-id "signal-id"

A successful send means Nature Remo accepted the control request; the infrared appliance does not acknowledge it. JSON output includes accepted, confirmed, signal_id, and the resolved signal_name when available. The Cloud API rate limit is 30 requests per five minutes per account. The CLI reports excess requests as RATE_LIMITED.

Discover the buttons advertised by configured TVs and lights, then press one by its case-insensitive exact name:

nature-remo tv list
nature-remo tv press --appliance "Living room TV" --button power
nature-remo light list
nature-remo light press --button on

TV and light discovery and control require basic.read and sendir access. Control JSON includes accepted, confirmed, and recorded_state; the state is Nature Remo's record after the request, not acknowledgement from the physical appliance.

Inspect Homes, their Remos and Members, and the authenticated User:

nature-remo home list
nature-remo home remos --home "Home"
nature-remo home members --home "Home"
nature-remo user show

Home and authenticated-User reads require basic.read access.

Use the API from TypeScript:

import { createNatureRemo } from "nature-remo-cli";

const accessToken = process.env.NATURE_REMO_ACCESS_TOKEN;
if (!accessToken) throw new Error("NATURE_REMO_ACCESS_TOKEN is not set");

const remo = createNatureRemo({ accessToken });
const appliances = await remo.appliances.list();
await remo.aircons.set({ target: "Living room", temperature: "26.5", mode: "cool" });

Output and failures

Data commands accept --format table (default) or --format json. Successful results go to stdout; errors go to stderr. Authentication commands return text. Use --help on each command to discover its arguments.

nature-remo appliance list --format json >appliances.json

JSON errors have this shape:

{
  "error": {
    "code": "AUTH_REQUIRED",
    "exitCode": 2,
    "message": "No Nature Remo access token is configured.",
    "hint": "Set NATURE_REMO_ACCESS_TOKEN. On macOS, run nature-remo auth login to save it to Keychain."
  }
}

| Exit code | Meaning | | --------- | ----------------------------------------------------------------- | | 0 | Successful command, help, or cancelled interactive login | | 1 | API, response validation, credential store, or unexpected failure | | 2 | Invalid arguments, missing authentication, or rejected token | | 3 | Insufficient token permissions | | 4 | API rate limit exceeded |

Each API request has a 30-second timeout, including reading its response body. Requests are not automatically retried. A failed control request may already have affected the appliance, even if its response was lost or invalid. Inspect the appliance before repeating an operation, especially a toggle button. The API's recorded state does not confirm an infrared appliance's physical state.

The TypeScript client throws NatureRemoError with a code and an optional HTTP status. CLI exit codes and hints are separate from this client error contract. During 0.x, minor releases may change commands or client types; pin the version when depending on their exact shape.

Agent skill

The nature-remo-cli skill guides command discovery, authentication, target selection, and interpretation of control results. Install it for Codex with GitHub CLI's gh skill command:

gh skill install Hiro5409/nature-remo-cli nature-remo-cli --agent codex --scope user

Use --agent claude-code for Claude Code. The npm package also includes the skill under skills/nature-remo-cli.

Development

Install and activate mise. mise.toml pins Node.js, Bun, and Gitleaks and exposes the locally installed Vite+ commands. Keep its Bun version aligned with the Vite+ package-manager declaration in package.json:

mise trust
mise install
bun install --frozen-lockfile
vp hooks enable
vp pack
bun link

The pre-commit hook formats and checks staged files, then scans them for secrets with Gitleaks. CI uses the same Gitleaks version to scan Git history.

API schema

The generated client and the MSW request handlers used by the tests are reproducible from the committed OpenAPI snapshot:

vp run generate-types

Every operation in the snapshot is classified as implemented, planned, or intentionally excluded:

vp run check:api-coverage

Check whether Nature's published schema changed, then explicitly update the snapshot:

vp run api-schema:check
vp run api-schema:update
vp run generate-types

Quality checks

vp run check

The CI installs a packed artifact into clean macOS and Linux consumers on Node 24.11.0 and the latest Node 24 release. Package checks exercise the CLI, JSON errors, client imports and requests, and an isolated macOS Keychain credential. They do not contact Nature Remo or control physical appliances.

To check a local artifact:

package_dir=$(mktemp -d)
bun pm pack --destination "$package_dir"
node scripts/check-package.ts "$package_dir"/nature-remo-cli-*.tgz

Dependency updates

Dependabot proposes one grouped pull request a week for the Bun dependencies and one for the GitHub Actions, each limited to versions released at least seven days earlier. A maintainer reviews and merges them. Its Bun updater reads bun.lock lockfile version 1, so update the lockfile in place instead of regenerating it.

Dependency Review needs the repository's dependency graph to be enabled. It checks pull requests for vulnerable direct dependencies declared in package.json and for changed GitHub Actions. The dependency graph does not read bun.lock, so bun audit in the CI is the check that covers the locked dependency tree.

GitHub Actions pinned to commit SHAs can receive Dependabot version-update PRs, but not vulnerability alerts.

Releases

A maintainer releases from main: commit the new version in package.json, push the commit to main, then push the annotated tag for that version:

git tag -a v1.2.3 -m v1.2.3
git push origin v1.2.3

The tag starts the Release workflow. The workflow verifies that the tag matches package.json and belongs to main, runs the CI on the tagged commit, and stages the tested artifact on npm through trusted publishing, with provenance. A staged version cannot be installed. A maintainer reviews it in the Staged Packages tab on npmjs.com and approves it with 2FA, which publishes it.

After approving the version, run the workflow again from its tag:

gh workflow run release.yml --ref v1.2.3

This run builds and tests the tagged commit again. The build is reproducible, so the run creates the GitHub Release with the artifact attached only when the version published on npm has the integrity of the artifact it tested.

Publishing relies on three settings outside the repository:

  • The GitHub environment npm, whose deployment policy allows only v* tags.
  • An npm trusted publisher for user Hiro5409, repository nature-remo-cli, workflow filename release.yml, and environment npm, with npm publish and npm dist-tag left unchecked. npm stage publish is always allowed, so the workflow can stage a version but only a maintainer can publish it.
  • 2FA on the npm account of the maintainer who approves.

The same command retries a failed run. Every run acts on what it finds: it stages the artifact while the version is not published on npm, and afterwards creates whichever of the GitHub Release and its attachment is missing. It stops when the published version or an existing attachment differs from the tested artifact, and when it cannot read npm or GitHub.

The workflow cannot see staged versions. A run that starts before the approved version is published stages it again, and npm refuses because the version is already staged; approve the version, then run the workflow again. To replace a staged version, remove it with npm stage reject and run the workflow again.

License

MIT. This project is not affiliated with Nature Inc.