Commit Graph
243 Commits
Author SHA1 Message Date
redshift cf1ca5941a feat(update): restart daemons after update
The update command previously only downloaded and installed new
binaries for routstrd and cocod without restarting the running
daemons, so updates would not take effect until a manual restart.

- Add restartDaemonsAfterUpdate() helper that gracefully stops and
  restarts both daemons after a successful update
- routstrd: uses POST /stop (drains active connections), polls for
    shutdown, then calls startDaemon() with configured port/provider
- cocod: runs 'cocod stop', then spawns 'cocod daemon' detached,
    polls 'cocod ping' until it comes back up
- Skips restart for daemons that weren't running
- Skips routstrd daemon restart when using a remote daemon
- Collects and reports failures without rolling back the update
- Bump @routstr/sdk to 0.3.15
- Bump routstrd version to 0.3.7

Closes nostr task: update-restart
2026-07-08 16:39:31 +08:00
redshift f58e807807 Add 'update' command to upgrade routstrd and cocod globally 2026-07-06 18:27:00 +08:00
redshift 1ff3b9a4e1 Fix renderToday definite-assignment and usage-summary stale fixtures
renderToday declared todayStats/recentDays/hourlyMap with let but only
assigned inside if (stats.summary); TypeScript flagged them as used
before assignment (TS2454). Initialize with sensible defaults so the
function degrades gracefully when summary is missing.

The usage-summary tz-bucketing test used hardcoded May 2026 timestamps
with a comment dated 2026-06-02. Those entries aged out of
getUsageSummary's 30-day rolling window, so days came back empty.
Recompute timestamps relative to now and assert on dynamically-derived
local-day date strings.
2026-07-05 21:27:20 +05:30
redshift b2738109e3 Sync daemon with SDK discovery adapter API 2026-07-04 21:11:56 +05:30
redshift 3c6161d9bf fix: add periodic Nostr event refresh to daemon
Calls refreshNostrEvents() after initial bootstrap and in the 21-minute
recurring job, covering provider discovery (38421) and lgtm reviews
(38425) which were previously only refreshed on manual trigger.
2026-06-28 10:33:52 +08:00
redshift 9cc3b76483 refactor(tui): separate async fetching from sync rendering
Split the monolithic render() into two distinct functions:
- fetchData(): async background fetch that updates state and triggers
  a repaint, guarded against overlapping calls
- render(): synchronous paint that reads current state and writes to
  stdout, safe to call from key handlers without blocking

Run all four daemon calls concurrently via Promise.all to cut the
blocked window. Remove redundant isDaemonRunning() checks from each
fetch function in data.ts — the single check now lives in fetchData().

Key handlers now call the sync render() directly instead of
void render(false), so scrolling and tab switching feel instant.
2026-06-22 16:39:58 +08:00
redshift f15e18cf05 Adapt request response logging to SDK sink 2026-06-20 17:00:52 +08:00
redshift 1735d97a9e feat: configure raw request response logging 2026-06-20 10:10:21 +08:00
redshift 8c52c90f94 addeed npub filtering for /usage as well 2026-06-11 09:31:32 +08:00
redshift 61acc0b5fb added npub based filter! 2026-06-11 09:17:13 +08:00
redshift 764d2dd826 removed old functions with benchmark which is clearly not needed 2026-06-11 08:49:15 +08:00
redshift 829681ffca removed legacy usage support 2026-06-11 08:33:15 +08:00
redshift ae91c46f01 fix(usage-summary): compute size buckets in JS after SDK removed token-range filters
The SDK dropped minTotalTokens/maxTotalTokens from AggregateUsageOptions
(routstr-sdk c98de6b), so replace the five aggregate() calls with a single
list() and bucket entries in-process.
2026-06-10 17:29:19 +08:00
redshift 6536333224 Merge remote-tracking branch 'origin/main' into pr-43
# Conflicts:
#	package.json
#	src/daemon/index.ts
2026-06-10 17:14:24 +08:00
redshift 0ab608bf88 fixed provider disabling not working while running 2026-06-08 09:43:15 +08:00
redshift d87a911241 viisble lgos 2026-06-07 11:25:02 +08:00
redshift 4a66af87da feat(providers): add --refresh flag to providers list
routstrd providers list --refresh now:
- Re-fetches Nostr kind 38421 provider discovery events
- Re-fetches Nostr kind 38423 routstr21 model list
- Re-fetches Nostr kind 38425 review events (applies LGTM-based disable)
- Fetches models from all discovered providers
- Syncs fresh provider list and disabled status into the store

Usage: routstrd providers list --refresh
2026-06-07 11:13:39 +08:00
redshift 27b13c30b0 made relays configurable 2026-06-07 10:56:06 +08:00
redshift 70230d9030 cached otkens now appear on the TUI 2026-06-07 09:06:53 +08:00
redshift d86a231ed3 fix: use Bun-safe SDK entrypoints for ModelManager and storage
- Import ModelManager from @routstr/sdk/bun instead of @routstr/sdk
- Import storage helpers from @routstr/sdk/storage/bun instead of @routstr/sdk/storage
- Fix createBunSqliteUsageTrackingDriver call: async and no longer needs
  manual bun:sqlite import (now handled internally by the sdk entrypoint)
- Verified sharded discovery adapter setup matches SDK pattern in
  scripts/routstr-daemon.ts at 6077aa7
2026-06-06 18:13:06 +08:00
Bilthon bc7ac9ff01 fix(daemon): import bun ModelManager for event persistence 2026-06-03 11:39:16 -05:00
Bilthon 6b746debed fix(monitor): use all-time summary totals in overview and exclude today from recent days 2026-06-02 22:03:56 -05:00
Bilthon c47145137d fix(test): export reset hook and call it in beforeEach for cache isolation 2026-06-02 15:27:19 -05:00
Bilthon bc8611ba7f fix(daemon): include client identity in usage-summary cache key 2026-06-02 15:26:55 -05:00
Bilthon c08f64941e fix(monitor): align top-models-per-client across summary and legacy 2026-06-02 15:26:43 -05:00
Bilthon b60b810dc8 fix(monitor): match summary today bucket to local day 2026-06-02 15:26:14 -05:00
Bilthon f0978f22c1 test: cover /usage/summary builder 2026-06-02 14:53:38 -05:00
Bilthon 21eb887346 feat(monitor): consume /usage/summary with legacy fallback 2026-06-02 14:51:02 -05:00
Bilthon 8f77da3911 feat(daemon): add /usage/summary aggregated endpoint 2026-06-02 14:45:06 -05:00
Bilthon 0c382209af refactor: import bun sqlite drivers from @routstr/sdk/storage/bun 2026-06-02 14:43:35 -05:00
Bilthon c6c4ed61e1 fix(monitor): display usage timestamps in local time instead of UTC 2026-06-01 18:10:14 -05:00
redshift fec0d99d72 fix: switch clients commands back to callDaemon
Clients management endpoints (/clients, /clients/add, /clients/delete)
should route through the daemon directly, not the auth proxy.
2026-06-01 16:07:44 +08:00
redshift dfc7fbf1f3 added nsec creation during onboarding. 2026-06-01 00:01:23 +08:00
redshift f9412af8b3 version bump and using the new adapters and a local eventsDb. 2026-05-30 18:25:18 +08:00
redshiftandGitHub 2dc2cf64ec Merge pull request #39 from Routstr/feat/auth-url-for-npubs-clients-usage
feat: add auth URL for npubs clients usage
2026-05-30 06:22:45 +00:00
redshiftandGitHub f9a85b3fc6 Merge pull request #38 from Routstr/feat/pi-integration-contexts
feat: add context window support to pi integration
2026-05-30 06:22:03 +00:00
redshift 17529e762e feat: add context window support to pi integration
- Add optional contextWindow field to PiModelEntry type
- Map model.context_length to contextWindow when available
- Add context_length to RoutstrModel type in registry
2026-05-30 14:04:24 +08:00
redshift 94cd2ff15d feat: add authUrl config for routing management commands to auth proxy
Adds an authUrl field to RoutstrdConfig so CLI management commands
(npubs, clients, usage) can be directed to the routstrd-auth proxy
instead of the daemon. This fixes 'routstrd npubs list' failing with
'Only POST is supported' when the auth proxy and daemon run on
separate ports (e.g., Cloudron setup: proxy on 8008, daemon on 8009).

Changes:
- config.ts: add authUrl to RoutstrdConfig
- daemon-client.ts: add getAuthBaseUrl(), callAuth(), refactor callDaemon
- cli.ts: npubs/usage commands use callAuth, remote command accepts --auth-url
- clients.ts: clients commands use callAuth
2026-05-30 05:30:42 +00:00
Jeroen UbbinkandClaude Sonnet 4.6 739034b043 fix(onboard): show integration menu and progress in terminal
The logger utility in this project is a file-only logger — every call to
logger.log() / logger.error() writes to ~/.routstrd/logs/YYYY-MM-DD.log
and produces no terminal output whatsoever. This is intentional and correct
for the background daemon (daemon/, start-daemon.ts), which has no attached
terminal.

However, the onboarding and integration code was mistakenly using logger.log
instead of console.log for all of its user-facing output:

- setupIntegration() printed the 1-6 integration menu with logger.log, so
  the user only ever saw the bare prompt 'Select integration [1]: ' with no
  options above it. The selection appeared to be broken.

- Every install*Integration function (opencode, openclaw, claudecode, hermes,
  pi) reported all progress and results with logger.log, so after picking an
  integration nothing appeared to happen.

- initDaemon() used logger.log for 'Initialization complete!' and the
  follow-up wallet instructions, so those were also silently dropped.

- installCocodOrExit() used logger.log for the 'cocod not found, installing'
  message and the success/failure result.

Fix: replace logger.log/logger.error with console.log/console.error in all
CLI-facing code paths (cli.ts, integrations/index.ts, and all five
integration installers). Remove the now-unused logger import from the five
integration files. The logger import in integrations/index.ts is kept because
refreshModelsAndIntegrations() is called by the daemon's internal scheduler
and correctly logs to file there.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 09:02:36 +02:00
redshift e9775c10d4 Display cooldown in minutes instead of milliseconds
- Add cooldownMinutes field to /nwc/status and /nwc/auto-refill responses
- Change auto-refill log from ms to minutes display
- Keep cooldownMs internally for calculations
2026-05-24 10:23:29 +08:00
redshift 789fd9db2b fix(auto-refill): broken backoff and preimage crash causing payment spam
Two bugs caused the auto-refill loop to retry every 5s regardless of outcome:

1) Backoff used lastRefillAt which was only set on success. On failure
   it stayed at 0, so now - 0 < backoffInterval never blocked once the
   daemon had been running > 30s. Switched to a separate lastAttemptAt
   that is updated on every attempt (success or failure).

2) preimage.slice() crashed when NWC returned a payment result without
   a preimage field. This turned successful payments into exceptions,
   triggering retries and causing the wallet to be charged repeatedly.
   Guard preimage with an if-check before calling .slice().
2026-05-24 10:16:16 +08:00
redshift 99244a8bdb feat: hot-reload NWC connection (remove restart requirement)
- Add reconnect() method to wallet adapter that tears down old
  WalletConnect/RelayPool and creates a new one on the fly
- Auto-refill loop now uses a getWallet() getter so it always
  references the latest wallet instance after reconnect
- POST /nwc/connect and /nwc/disconnect handlers call reconnect()
  after saving config, no restart needed
- Remove 'Run routstrd restart' messages from CLI connect/disconnect
2026-05-24 09:22:45 +08:00
redshift 5799c5c5b0 auto-refill: update wallet auto-refill logic 2026-05-24 09:11:13 +08:00
redshift e5f5c0995d auto-refill: add error categorization, exponential backoff, and fatal error handling 2026-05-23 23:13:52 +08:00
redshift 92ca9a7cb0 chore: remove legacy NWC client, fix auto-refill getter 2026-05-23 23:03:48 +08:00
redshift c98709e383 feat: auto-refill no longer requires daemon restart
Changed startAutoRefillLoop to accept a config getter instead of a static
config object. The getter reads config from disk on every check cycle, so
CLI changes (nwc auto-refill on/off) take effect immediately.

- auto-refill.ts: config parameter replaced with getConfig() callback
- wallet/index.ts: always start loop when wallet exists, use getter
- daemon/index.ts: pass getAutoRefillConfig reading from disk sync
- config-store.ts: added loadDaemonConfigSync() for sync disk reads
- http/index.ts + cli.ts: removed 'Restart daemon to apply' messages
2026-05-23 22:37:43 +08:00
redshift b9d30b12a9 nwc: add progress logs to fundFromNWC, trim response to amount+balance
- Add step-by-step logging to fundFromNWC (initial/final balance, invoice,
  payment status, fees) matching pay_invoice.mts pattern
- Remove invoice and preimage from POST /nwc/fund response
- Add final wallet balance to the response after funding completes
2026-05-23 22:26:10 +08:00
redshift 5ee6a39567 refactor: replace custom NwcClient with applesauce-wallet-connect
- auto-refill.ts: use WalletConnect instance directly instead of
  NwcClient + RelayPool; check wallet.service for connection state
- wallet/index.ts: create single shared WalletConnect for auto-refill,
  fundFromNWC, and getNwcStatus; remove NwcClient entirely
- daemon/index.ts: strip all NwcClient creation/connect/logging/cleanup;
  auto-refill now gates on connectionString alone
- add applesauce-wallet-connect dependency
2026-05-23 22:14:15 +08:00
redshift fd07a688fa simplify NWC client: NIP-04 only, remove encryption negotiation, trim test 2026-05-23 14:42:28 +08:00
redshift 62bd014836 feat: rewrite NWC client with encryption auto-negotiation, EOSE waiting, add test script
- Encryption auto-detection: reads wallet info event (kind 13194) on connect
  to choose NIP-04 vs NIP-44 per NIP-47 spec
- Subscription readiness: wait for EOSE before resolving connect()
- Dual NIP-04 / NIP-44 encrypt/decrypt support
- Proper encryption tags on NIP-44 requests
- test_nwc.ts: standalone NWC test script for make_invoice + pay_invoice
2026-05-23 14:26:45 +08:00