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

orkastor

v0.2.0

Published

The terminal path to Orkastor Cloud. Deploy an image or a repository and get an HTTPS URL.

Readme

npx orkastor

The terminal path to Orkastor Cloud. No install, no global, no runtime dependencies.

npx orkastor login
cd my-project
npx orkastor deploy

What an environment is

An environment is one running copy of your app, with its own URL and its own clock — not a dev/stage/prod tier. Make one per branch, per pull request or per demo, and delete it when you are done.

That sentence is here because the word already means something else everywhere else. On Railway, Heroku, Render and Fly an "environment" is a variant of a project — production, staging, development — so people arrive expecting to pick one of three. Here it is the opposite granularity: the industry name for this shape is a preview or ephemeral environment.

An environment holds one or more apps — 1 on Trial, 5 on Dev, 20 on Team — path-routed behind a single hostname.

Environments are ephemeral by design. Each has a lifetime, and its storage does not survive reclamation. Keep anything you need in your repository or in a database you run.

Commands

orkastor login | logout [--all] | whoami | tokens

orkastor deploy                          # from the current directory
orkastor deploy --image X --port 8080
orkastor deploy --repo owner/name --ref main

orkastor ls
orkastor logs <env> [--app NAME] [--follow]
orkastor open <env>
orkastor rm <env>

orkastor apps <env>
orkastor apps add <env> --image X --port N [--path /api]
orkastor apps rm <env> <name>

orkastor vars <env>                      # or `vars ls <env>`
orkastor vars set <env> NAME=VALUE
orkastor vars set <env> NAME             # value read from stdin
orkastor vars set <env> --from-file .env
orkastor vars rm <env> <name>

orkastor suspend <env>
orkastor resume <env>
orkastor extend <env> --hours N

orkastor ai "<question>"
orkastor dockerfile <env> [--latest]

orkastor help <command> for one command's flags.

Environment variables on an environment

vars, not env. env VAR=x cmd is a shell idiom, and more to the point an environment is this product's central noun — orkastor env ls would read as "list my environments", which is orkastor ls and a different command.

Variables are per environment, not per app. Every app in the environment sees the same set, and the control plane refuses two apps declaring the same name with different values. There is no --app flag for that reason.

You cannot read a value back. Not with any flag, and not later

orkastor vars <env> lists names, versions and when each changed. There is no value, no preview, no first four characters, no length and no digest — and no other command, endpoint or flag anywhere that returns one.

That is deliberate. The value was typed in by you, who already has it; a platform keeping a second readable copy buys you nothing and adds a way to lose it. Fly, GitHub Codespaces and Vercel's sensitive mode all land in the same place.

So there is no orkastor vars pull, and there will not be one. If you are looking for the shape vercel env pull has, it cannot exist against this control plane. The traffic goes the other way: --from-file pushes a whole .env up in one transaction, which is the half that does the work.

Three ways to give it a value, in the order we would pick them

orkastor vars set myenv --from-file .env             # nothing sensitive on the line
printf %s "$DB_URL" | orkastor vars set myenv DATABASE_URL
orkastor vars set myenv DATABASE_URL=postgres://…    # in your shell history, and in `ps`

The third works and prints a warning saying where the value has just been left. A file is refused whole if any line in it is not an assignment — the control plane refuses a bad batch whole too, and a half-applied set of credentials is a state nobody can reason about. The refusal names the line NUMBER, never its text.

Setting an existing name rotates it: the version goes up and the environment's revision advances, so the workload rolls and the new value is read at container start. A running container keeps the old value until then. set does not ask for confirmation, because it spends nothing and destroys nothing.

vars rm does ask, and in CI it needs --yes. Nothing can read the value back, so removing one is not recoverable from anything of ours. If the environment's spec still declares the variable, it then stops deploying rather than starting without it — which is deliberate, because a pod missing its configuration comes up healthy.

⚠ Delivery into a running container has never been exercised end to end. A variable set today is stored, encrypted, listed and resolvable, and no reconciler has yet polled the seam that would inject it. Every set and rm prints the control plane's own sentence saying so.

Suspending, resuming and extending

orkastor suspend myenv           # stop the microVM, release its memory
orkastor resume myenv --yes      # start it again, before a request would
orkastor extend myenv --hours 8 --yes

suspend and resume record a REQUEST. They answer 202 and the environment's state does not move: a reconciler applies it later and reports back. These commands print the control plane's own note verbatim and never report the state that was asked for as though it had happened. Today that note also says whether a reconciler has ever connected — and if none has, the request will not be applied at all.

suspend does not ask for confirmation: it stops the meter and destroys nothing. resume and extend both need --yes in CI, because a suspended environment is not billed for compute and a running one is, and more lifetime is more billed hours. Neither can be priced first — POST /quote prices an environment about to be created and there is no route that prices more hours on an existing one — so they say plainly that they spend rather than showing a figure that would be a guess.

extend is also the undo for an environment inside its grace window: it goes back to RUNNING and the reclamation deadline is cleared. The cap is measured from when the environment was created, not from now, so an extension can be granted short. When it is, the command says so.

The AI

Orkastor has an AI that can read your workspace. Two commands reach it, and neither of them changes anything.

orkastor ai "why did checkout stop responding?"
orkastor dockerfile checkout
orkastor dockerfile checkout --latest     # read the last one; spends nothing

Both spend the workspace's monthly AI budget. Neither spends prepaid credit, which is what --yes guards, so neither asks for it — and both work in CI unchanged. A workspace over its AI budget is refused before anything runs, in the control plane's own words.

ai answers, and sometimes PROPOSES. It never acts

The AI can read your environments, builds, build logs, existing AI proposals and the repositories reachable through your GitHub connection. It cannot create an environment, start a build, deploy, or write to a repository. What it can do is propose one of those, and a proposal is a description of something that has not happened.

So when a proposal comes back, this CLI prints it and stops:

! Proposed: deploy ghcr.io/acme/web:2

    environment: env-8f21
    image:       ghcr.io/acme/web:2

    why: the tag has moved since the last deploy

  Nothing has been created, started, deployed or written. This is a proposal.

  To do it yourself:

    orkastor ls
    orkastor deploy --name <the name of env-8f21> --image ghcr.io/acme/web:2

It will not turn that into a deploy, and there is no flag that makes it. That is the point of the design: propose-then-confirm exists so a person gets to say no, and a client that quietly closes the loop has deleted the only place they could.

Two of the four proposals have no exact equivalent here — starting a build, and patching a repository. Those print with no command, and say so, rather than offering something close.

A patch is yours to apply. If the AI proposes a code fix, it is a diff against your repository. The diff is printed in full so you can read it. Orkastor does not commit to your repository and this CLI offers no command that would. It has not been built and it has not been run.

The answer is a model's, not a measurement

Every ai run prints the reads it actually made before it prints the answer:

  · read list_environments — 3 environments
  · read read_build_log — 200 lines
  The answer below is a model's, not a measurement. …

The answer goes to stdout, so orkastor ai "…" | pbcopy is the answer and nothing else. Everything else — the reads, the caveat, any proposal — is stderr. --json puts the whole run, proposal included, on stdout instead.

When a run produces nothing, the control plane's own sentence is printed unchanged and the exit code is 4. That includes "no AI provider is configured", which is a deployment problem rather than a refusal of your question — the sentence says so, which is why it is quoted rather than replaced. A deployment whose API has no AI route at all exits 6, not 4: a 404 is not a refusal.

dockerfile proposes a Dockerfile you commit yourself

For an environment built from a GitHub repository that has no Dockerfile of its own. It reads the repository's manifests and writes one.

orkastor dockerfile checkout > Dockerfile

The Dockerfile goes to stdout for exactly that reason; the rationale, the base image, every warning and the server's own note go to stderr. Nothing is written to your repository, no branch is pushed and no pull request is opened. The API has a route that opens one, admin-only and off by default — it is deliberately not reachable from here, because a write into your repository should not be one flag away from a read.

It has never been built. Treat it as a starting point, not a result.

--latest reads the most recent proposal back instead of generating a new one, and spends nothing.

There is no orkastor diagnose

Build diagnosis is a real AI feature and it is not exposed here on purpose. It needs a failed build, builds run in Kata microVMs on bare metal, and that metal is not provisioned — kata-deploy sits at DESIRED 0. A command that can never fire is worse than one that does not exist, because it fails in a way that reads as your fault.

What deploy reads, and what it asks

From the current directory it reads, and tells you what it found and where:

| It looks for | It uses it for | |---|---| | Dockerfile → first EXPOSE | the port, when you did not pass --port | | git config remote.origin.url | the repository, when it is a GitHub one | | the checked-out branch | the ref, and part of the name | | the directory name | the environment name | | an environment already called that | it becomes an update, not a second environment |

The port order is --port, then EXPOSE, then 8080, mirroring the control plane's own fallback. If it cannot tell what to run, it asks — and in CI, where there is nobody to ask, it refuses and names the flag rather than guessing.

In CI

Non-TTY is a first-class mode: no spinners, no colour, no prompts.

env:
  ORKASTOR_TOKEN: ${{ secrets.ORKASTOR_TOKEN }}
run: npx orkastor deploy --image ghcr.io/acme/web:${{ github.sha }} --yes

Anything that spends prepaid credit needs --yes; without it the run refuses and exits 7 rather than blocking on a prompt nobody can answer.

Exit codes

| | | |---|---| | 0 | it worked | | 1 | unexpected — a bug in the CLI | | 2 | the command line could not be acted on; nothing was sent | | 3 | no usable credential | | 4 | the control plane received it and refused it | | 5 | the control plane could not be read at all | | 6 | no such route in this deployment | | 7 | a confirmation was needed and could not be obtained; nothing was done |

deploy prints the environment's URL to stdout, alone on its line, at the 202 — before anything is running. Everything else goes to stderr, so npx orkastor deploy --yes | tail -1 is the URL and nothing else.

Environment variables

| | | |---|---| | ORKASTOR_TOKEN | A bearer token. Overrides the stored credential entirely; nothing is read from or written to disk. | | ORKASTOR_WORKSPACE | Which workspace to act on, by id or slug. | | ORKASTOR_API_URL | The control plane. Defaults to https://api.orkastor.cloud. | | ORKASTOR_LOGIN_URL | The browser sign-in page, for self-hosted installs. | | ORKASTOR_AUTH_FILE | Where the credential is stored. | | ORKASTOR_DEBUG | Print a stack trace on an unexpected error. | | NO_COLOR, CI | Both honoured. |

The credential

orkastor login opens a browser, the page signs you in, and it posts a token to a listener the CLI holds on 127.0.0.1 — the same hand-off kubegraf auth login uses, against the same page.

That token is a Firebase ID token and lasts about an hour, so login does one more thing with it before it lapses: it exchanges it, once, for an Orkastor CLI token.

orkcli_<64 hex characters>

It is Orkastor's own credential. api.orkastor.cloud issues it, verifies it against Orkastor's own database, and it authorises nothing anywhere else — not on app.kubegraf.io, not in any cloud account. The prefix is there so that anyone who finds one in a CI log knows whose it is and where to revoke it.

| | | |---|---| | Expires | 90 days after you last use it. Every command pushes that forward. | | Ceiling | 180 days from the day it was issued. This one never moves. | | Stored | Only its SHA-256 reaches our database. It is shown once and cannot be recovered. | | Revoked | orkastor logout, effective on the next request. |

The token is stored in your OS config directory (~/.config/orkastor/auth.json on Linux and macOS, %APPDATA%\orkastor on Windows) with mode 0600. It is never written into your project, never printed, and scrubbed out of any error message that might otherwise carry it.

orkastor tokens lists every CLI token on your account — its label (the machine's hostname), when it was last used, and both deadlines. No part of any secret is shown, because none is kept. Last used is the column that matters: it is what makes revoking the right one safe.

orkastor logout revokes this machine's token at the control plane and then removes the local file, in that order. Deleting the file alone would forget a credential that still works. orkastor logout --all revokes every token on the account, which is what to run when the machine holding one is gone.

Against a control plane that does not have /api/orkastor/cli/tokens yet, login keeps the browser token and says out loud that the sign-in lasts an hour. Nothing here has to change when that deployment catches up.

Pricing

Creating an environment and adding an app both debit prepaid credit. Both commands ask the control plane what the specific thing you are about to create costs, show that total and the balance you will be left with, and only then make the call. If the workspace cannot afford it, they say so before spending rather than after a 402.

There is no rate card here, and there is not one anywhere else either.