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

destreamed-runner

v0.3.1

Published

Headless autonomer Tuner-Runner für Destreamed — pollt Tasks, triggert wahlweise Claude Code oder Codex als LLM-Worker, mit Toolchain-Modulen (Rust/Python/Go/…), Vault-Integration und GitLab-Repo-Mirror.

Readme

destreamed-runner

Experimental — use at your own risk. Active development. Breaking changes likely. No SLA, no warranty. Don't run against credentials you can't rotate. Licensed under Apache 2.0.

Headless autonomer Tuner-Runner für Destreamed: pollt deinem Tuner zugewiesene Tasks, lässt einen LLM-Worker (Claude Code oder Codex) im Container die Arbeit erledigen, schreibt Echos + Complete via MCP zurück. Vault-Integration für Credentials on-demand, Auto-Update via git pull, modulare Toolchain-Module (Rust, Python, Go, kubectl, gh) per-Tuner pickbar.

Pattern: Dünner deterministischer Wrapper + LLM-CLI als Worker. Inspired by Ralph.

cron → flock → poll Destreamed → Vault-Inject → worker.spawn() → echo + complete via MCP

Quick-Setup (init Wizard)

Sobald als npm-Paket published, ist der Bootstrap ein Einzeiler:

npx @destreamed/runner init
# (oder mit Bootstrap-Token aus der Destreamed-UI sobald DESTREAM-102 fertig:)
# npx @destreamed/runner init --token=brt_xxx

Im Repo selbst (vor publish):

git clone [email protected]:destreamed/destreamed-cli.git ~/destreamed-cli
cd ~/destreamed-cli
npm install && npm run build
node bin/cli.js init

Wizard fragt der Reihe nach:

  • Tuner-Name (default peon)
  • DESTREAMED_AGENT_TOKEN (ds_…)
  • Stream-Filter oder allow_all
  • LLM-Worker (claude-code default oder codex — siehe Worker)
  • Worker-Auth (Claude OAuth/API-Key oder Codex-Token, je nach Wahl)
  • GitLab-PAT als optionaler .env-Fallback (bevorzugt: Token im Vault, on-demand pro Task via ${vault:Gitlab})
  • Vault-Integration (KeyFile-Pfad mit Auto-Suggestion aus ~/Downloads/, Master-Passphrase, Persona-Pick aus dem KeyFile-Inhalt)
  • Toolchains (Multi-Select aus rust, python, go, kubectl, gh — siehe Toolchains)

Schreibt .env atomar (mode 0600), kopiert KeyFile nach secrets/vault-keyfile.dskey, komponiert docker/Dockerfile.<tuner> aus Template + ausgewählten Module-Snippets, erstellt workspace/<tuner>/{tasks,scripts,artifacts}/-Skeleton, und zeigt am Ende einen OS-spezifischen Setup-Hint für Docker-Install + Container-Boot.

Dann:

./bin/tuner up <tuner-name>

Installation auf macOS

Voraussetzungen:

  • macOS (Apple Silicon oder Intel)
  • Homebrew
  • Funktionierender Destreamed-Account mit aktiver Vault-Persona ("Peon")
  • Claude-Code-Subscription (Pro/Team)
  • Optional: GitLab-Account mit PAT für Repo-Operationen

1. Dependencies via Homebrew

brew install git node colima docker docker-compose

colima ist der schlanke OSS-Ersatz für Docker Desktop (Daemon in winziger Lima-VM, free, keine Lizenz-Stress). Wer Docker Desktop schon installiert hat, kann das auch nehmen — colima ist nicht zwingend.

2. Docker-Daemon starten

colima start
docker version           # sollte Server-Version anzeigen

3. Repo klonen

git clone [email protected]:destreamed/destreamed-cli.git ~/destreamed-cli
cd ~/destreamed-cli

(SSH-Key braucht Zugriff auf gitlab.cco.re. Alternativ HTTPS-Klon mit PAT.)

4. Tokens besorgen — drei Stück

| Token | Wo holen | Beispiel | |---|---|---| | Destreamed-Tuner-Token | destreamed.com → Profile → Tuners → New Agent → Token einmalig kopieren | ds_… | | Claude-Code-OAuth-Token | claude.ai → Profile → Headless / CI Token → kopieren | oat_… oder sk-ant-oat-… | | GitLab-PAT (optional) | gitlab.cco.re → User Settings → Access Tokens → Scopes api, read_repository, write_repository → kopieren | glpat-… |

5. Vault-KeyFile besorgen

In der Destreamed-Browser-Extension:

  • Vault-Bereich → Tuner-Identität für „Peon" anlegen (oder bestehende auswählen)
  • KeyFile exportieren — landet als ~/Downloads/destreamed-vault-YYYY-MM-DD.dskey

Datei ins Repo legen + ablegen:

mkdir -p secrets
cp ~/Downloads/destreamed-vault-*.dskey secrets/vault-keyfile.dskey

Die Datei ist Argon2id-encrypted, du brauchst die Master-Passphrase die du beim Browser-Vault-Setup vergeben hast.

6. .env befüllen

cp .env.example .env
$EDITOR .env

Mindest-Werte:

DESTREAMED_AGENT_TOKEN=ds_xxxxx          # aus Schritt 4
CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat-xxx   # aus Schritt 4
GITLAB_TOKEN=glpat-xxx                   # optional
TUNER_VAULT_PASSPHRASE=deine-passphrase  # aus Schritt 5
TUNER_VAULT_AGENT_ID=697352f5-…          # die UUID deiner Persona; bin/tuner enroll listet sie
TUNER_NAME=peon                          # default ist peon
TUNER_VAULT_KEYFILE_PATH=/Users/$USER/destreamed-cli/secrets/vault-keyfile.dskey

Die Persona-UUID rauszufinden:

npm install
npx tsx src/cli.ts vault enroll
# → listet alle Personas im KeyFile mit ihrer UUID
# trage die gewünschte UUID in .env als TUNER_VAULT_AGENT_ID ein

7. Container starten

./bin/tuner up peon
./bin/tuner logs peon                    # Logs streamen (Ctrl+C beendet das Streamen, nicht den Container)

Erste Tick-Ausgabe nach max 2min. Bei korrekt befülltem .env: {"l":"info","msg":"no_tasks"} (sofern der Tuner gerade nichts zu tun hat).

8. Verifikation

In Destreamed:

  1. Stream "Sandbox" o.ä. anlegen, Peon als Tuner adden
  2. Task droppen: „Echo hello world zurück und complete den Task"
  3. Innerhalb von 2 min sollte ein Echo + Complete erscheinen

Wenn ja: läuft. Wenn nein: → Troubleshooting unten.

9. Auto-Update einrichten (optional)

crontab -e
# Folgende Zeile hinzufügen:
*/15 * * * * /Users/$USER/destreamed-cli/bin/auto-update.sh

Das Skript checkt alle 15 min ob ein neuer Commit auf origin/main liegt; wenn ja: pull + Container-Rebuild. Logs landen in ~/destreamed-cli/auto-update.log.

ENV-Overrides möglich (alle optional):

  • DCLI_BRANCH=main — welcher Branch
  • DCLI_TUNER=peon — welcher Tuner-Name
  • DCLI_LOG=/var/log/dcli.log — Log-Pfad

Architektur

| Komponente | Rolle | |---|---| | src/cli.ts | Entry: tick, check, vault {enroll,whoami,list,get}, git mirror, echo, complete, search, read | | src/vault/{crypto,keystore,client,inject,runtime}.ts | Vault-Crypto + REST-Client + Placeholder-Inject | | src/destreamed/client.ts | MCP-Client für Destreamed (tasks, beat, stream, search) | | src/git-mirror.ts | GitLab-Group-Mirror in workspace | | src/prompt-builder.ts | Token-bewusster Prompt für worker.spawn() | | src/workers/{types,claude-code,codex,registry}.ts | Worker-Abstraction — austauschbarer LLM-Subprocess | | src/dockerfile-composer.ts | Bastelt docker/Dockerfile.<tuner> aus Template + Module-Snippets | | docker/Dockerfile.template | Base-Image mit {{TOOLCHAIN_MODULES}} Placeholder | | docker/modules/<name>.dockerfile | Toolchain-Snippets (rust, python, go, kubectl, gh) | | docker/{tick,entrypoint}.sh | Cron-Wrapper | | bin/tuner | Multi-Tuner-Helper (add/list/up/down/logs) — komponiert Dockerfile bei up | | bin/auto-update.sh | Host-side updater (git pull + rebuild) |

Ein-Tick-Loop (deterministisch, kein LLM für die Steuerung):

  1. flock — single-flight
  2. tasks.get_my_tasks via MCP über Destreamed
  3. stream.get_memos für aktiven Stream
  4. Bei Repo-Hint im Task: git clone ins Per-Task-Workspace
  5. ${vault:NAME}-Platzhalter im Task scannen → Vault holt Plaintexts → extraEnv für Worker
  6. Worker laden (workers/registry.ts) + Auth-Detect aus ENV
  7. MCP-Config schreiben (nur wenn Worker mcpSupported; bei Codex skipped)
  8. worker.spawn() mit Prompt + ENV — kapselt claude -p resp. codex exec
  9. Bei Exit ≠ 0: Fehler-Echo. Bei Exit 0: Logs (Worker erledigt echo+complete selbst — bei Codex via Bash-Subcommands destreamed-cli echo|complete|search|read)

Worker

RUNNER_WORKER in .env wählt den LLM-Subprocess:

| Worker | ENV vars | MCP | Container-Install | |---|---|---|---| | claude-code (default) | CLAUDE_CODE_OAUTH_TOKEN (oat_/sk-ant-oat) oder ANTHROPIC_API_KEY | ✓ nativ | im Base-Image | | codex | CODEX_AUTH_TOKEN | ✗ — Beat-Ops via Bash-Subcommands | Toolchain-Modul codex (npm @openai/codex) |

destreamed-cli check zeigt aktuell gewählten Worker + Auth-Status. Wechsel: RUNNER_WORKER=… editieren, Container neu starten (bin/tuner up <name>).


Toolchain-Module

Per-Tuner Container-Build aus modularen Snippets:

docker/
├── Dockerfile.template        # Base + {{TOOLCHAIN_MODULES}} Placeholder
└── modules/
    ├── rust.dockerfile        # ~400 MB
    ├── python.dockerfile      # ~150 MB (Python 3 + uv)
    ├── go.dockerfile          # ~300 MB
    ├── kubectl.dockerfile     # ~80 MB (kubectl + helm)
    ├── gh.dockerfile          # ~30 MB (GitHub CLI)
    └── codex.dockerfile       # ~50 MB (OpenAI Codex CLI — für RUNNER_WORKER=codex)

Selection in .env (komma-separiert):

RUNNER_TOOLCHAINS=rust,python

bin/tuner up <name> ruft den Composer auf bevor compose läuft → schreibt docker/Dockerfile.<name>. Per-Tuner Image, gemeinsamer Layer-Cache wenn Selection identisch ist. Manuell: destreamed-cli compose-dockerfile --tuner peon --toolchains rust,python.

Eigenes Modul anlegen: neue Datei docker/modules/<name>.dockerfile mit RUN/ENV-Snippets (kein FROM!). Das Snippet darf USER root setzen, sollte aber mit USER peon enden.


Workspace-Layout

Bind-Mount zwischen Host und Container, per-Tuner gescoped:

host:                                   container sieht:
./workspace/peon/                       /workspace/
├── tasks/<task-id>/                    ├── tasks/<task-id>/   ← per-task scratch
├── scripts/                            ├── scripts/           ← User → Container
├── artifacts/                          ├── artifacts/         ← Container → User
└── repos/destreamed/{frontend,…}/      └── repos/             ← git mirror output
  • scripts/ — User-managed, Container darf executen
  • artifacts/ — Container schreibt Output, User holt ab
  • repos/ — wird von Tasks befüllt (z.B. via destreamed-cli git mirror <ns> als ad-hoc-Befehl)
  • tasks/<id>/ — Per-Task-Scratch, enthält generierte .mcp.json

Tuner B sieht NICHT in Tuner A's workspace — der Mount ist physisch auf workspace/<TUNER_NAME>/ gescoped.


Multi-Tuner

bin/tuner add <name>     # neuer Tuner: <name>.env + workspace/<name>/
bin/tuner list           # alle mit Run-Status
bin/tuner up <name>      # starten (compose --env-file --project-name up -d --build)
bin/tuner down <name>    # stoppen
bin/tuner logs <name>    # logs -f

Vault-KeyFile ist user-global (alle Personas in einem File secrets/vault-keyfile.dskey). Jeder Tuner pickt seine Persona via TUNER_VAULT_AGENT_ID in seinem <name>.env. Beim Hinzufügen einer neuen Persona: im Browser enrollen → KeyFile re-exportieren → secrets/vault-keyfile.dskey ersetzen. Container brauchen keinen Restart (loadVaultAgent liest File bei jedem Aufruf neu).

Manuell statt Helper:

docker compose --env-file scout.env --project-name scout up -d --build

Vault-Integration

Lese-Subcommands (ohne MCP-Overhead):

destreamed-cli vault enroll      # listet Personas im KeyFile
destreamed-cli vault whoami      # bestätigt Server-Identität
destreamed-cli vault list        # alle gegrant'eten Credentials
destreamed-cli vault get <name>  # plaintext auf stdout

Auto-Inject im Tick: Tasks/Memos können ${vault:NAME} enthalten. Beim Tick werden die Werte einmal aus dem Vault gezogen und als ENV in den claude-Subprocess gepusht ($NAME). Plaintext lebt nur für die Subprocess-Lebensdauer.

# Beispiel-Task in Destreamed:
"Verbinde dich mit GitLab via ${vault:Gitlab} als Token. Liste meine Repos."

# Wird im Tick zu:
"Verbinde dich mit GitLab via $GITLAB als Token. Liste meine Repos."
+ ENV={GITLAB: "<plaintext>"}

Hard-fail wenn Credential nicht resolvable (403/missing) — Echo erklärt was fehlt, Task bleibt offen.


GitLab-Repo-Mirror (optional, Power-User)

Manuelles Subcommand — KEINE automatische Cron-Synchronisation. Wird über Vault-Cred Gitlab authentifiziert:

destreamed-cli git mirror destreamed                    # alle destreamed/*-Repos
destreamed-cli git mirror destreamed --dest /tmp/foo    # eigener Pfad

Output landet in workspace/<tuner>/repos/<group>/<project>/. Für regelmäßige Sync: drop einen Task in Destreamed, der das Subcommand aufruft — der Runner führt's aus, kein eingebauter Cron.


Token-Modell

| Token | Wer nutzt | Wofür | |---|---|---| | DESTREAMED_AGENT_TOKEN (ds_…) | CLI | MCP-Polling, Tasks holen, Echos, Complete | | CLAUDE_CODE_OAUTH_TOKEN / ANTHROPIC_API_KEY | claude-code Worker | LLM-Calls an Anthropic (Format auto-detected) | | CODEX_AUTH_TOKEN | codex Worker | LLM-Calls an OpenAI Codex | | TUNER_VAULT_PASSPHRASE | CLI | Master-Passphrase zum Entschlüsseln des KeyFiles (Argon2id) | | GITLAB_TOKEN (in .env, optional) | CLI für git clone initial | nur wenn Repo-Tasks ohne Vault gewünscht | | Vault-credential „Gitlab" | dynamisch geholt von CLI + Worker | bevorzugte Methode für GitLab-Auth — rotation ohne .env-Touch |


Operationelle Notizen

  • Logs: bin/tuner logs peon (NDJSON).
  • Cron-Intervalle: */2 tick, 5 */6 mirror. Anpassen in docker/crontab + rebuild.
  • Stale Lock: Bei Crash bleibt /tmp/destreamed-cli.lock im Container liegen; Container-Restart räumt auf. PID-Detection ist Phase-2-Feature.
  • Failure-Mode: claude -p failed → Fehler-Echo, Task NICHT completed → nächster Tick versucht erneut. Vorsicht bei nicht-idempotenten Side-Effects.
  • Workspace-Cleanup: Aktuell keiner; Volume wächst. tick --gc ist Folge-Iteration.
  • Token-Mask: Mirror-Errors mask oauth2:<token>@ zu oauth2:***@. Andere Code-Pfade noch nicht gehärtet — siehe Security-Sektion.

Troubleshooting

config_invalid: TUNER_STREAM_FILTER fehlt Du hast keinen Filter UND kein TUNER_ALLOW_ALL_STREAMS=true. Setze einen Stream-ID-Filter oder erlaube explizit alle Streams.

vault GET /vault/me 401

  • KeyFile-Persona auf Server nicht enrolled (DB hat keinen vault_pubkey_sign für die UUID)
  • Browser-Vault zeigt vermutlich auf eine andere Server-Instanz (lokal vs production)
  • Re-Enroll im Browser → KeyFile re-exportieren

Cron-Job loggt nichts:

  • crontab -u peon muss installiert sein → check via docker exec peon-tuner crontab -l -u peon
  • ENV nicht in /etc/destreamed-runtime.env → entrypoint hat sie nicht gefroren, check Container-Logs

fatal: detected dubious ownership

  • safe.directory greift nicht — Dockerfile-Step fehlt oder Container nicht rebuildet (bin/tuner up peon mit --build)

colima vs Docker Desktop:

  • Beide funktionieren. Bei Wechsel: ~/.docker/config.json credsStore-Zeile prüfen (Docker-Desktop hinterlässt osxkeychain-Verweis, der bei colima failed)

Tokens leak in Logs:

  • Aktuell teilweise gemasked (Mirror-Errors), aber NICHT systematisch. Im Logger registrierter Sanitizer ist Phase-2-Feature.

Aktueller Status

✅ Phase 1: deterministischer Tick mit Lock, Vault-Integration, Repo-Mirror, Multi-Tuner-Isolation, Auto-Update ✅ Phase B (v0.3.0): Modulare Toolchain-Module (Rust/Python/Go/kubectl/gh), per-Tuner Dockerfile-Composition ✅ Phase C (v0.3.0): Worker-Abstraction — Claude Code / Codex pickbar, Worker-Interface für künftige Anbieter ✅ v0.3.1: Codex-Toolchain-Modul + worker-aware Prompt (Codex sieht keine MCP-Tools mehr, nur Bash-Subcommands) ⚠️ Stale-Lock-PID-Detection fehlt ⚠️ Workspace-Garbage-Collection fehlt ⚠️ Image-basierter Production-Update (Pattern C mit Watchtower) ist Folge-Iteration

Lizenz

Internal — kein Public-Use, no warranty.