- Updated npubs list to display role (admin/user) for each npub
- Changed header from 'Admin npubs' to 'Npubs' to reflect all roles
- Updated command descriptions to reflect broader scope
- Also fixed 'admin npub' message in add command output
The auth proxy intercepts GET /usage and returns only entries belonging to
the authenticated npub's clients, with owner suffixes stripped. The TUI no
longer needs to filter entries client-side.
- Remove getNpubSuffix and loadConfig from tui/usage/data.ts imports
- Remove old suffix-based filtering logic from fetchUsage()
- Remove unused getNpubSuffix from cli.ts imports
- Added 'routstrd refresh' command that:
- Calls /v1/models?refresh=true to refresh routstr21 models
- Calls runIntegrationsForClients() for all registered clients
- Fixed type signature in refreshModelsAndIntegrations (returns any[] not void)
- Imports getClientsList and runIntegrationsForClients in cli.ts
- Moved addDaemonClient and ensureDaemonClient from daemon-client.ts to clients.ts
- Moved clients list/delete/add action handlers from cli.ts to clients.ts
- Updated cli.ts to call the new action functions from clients.ts
- Updated integrations/index.ts to import ensureDaemonClient from clients.ts
- Fixed circular dependency by having clients.ts import from ../integrations/registry instead of ../integrations
Replace direct store.getState().clientIds access with a shared utility:
- getClientsFromStore(store) for daemon/local usage
- getClientsList() for remote CLI usage via daemon API
This ensures integration refresh logic and client management work
consistently whether running inside the daemon or connecting to a
remote daemon where store access is unavailable.
Updated:
- src/daemon/index.ts: use getClientsFromStore for integration refresh
- src/daemon/http/index.ts: use getClientsFromStore in /clients endpoints
- src/utils/daemon-client.ts: use getClientsList in ensureDaemonClient
- src/cli.ts: use getClientsList in clients list command
- Move get-or-create client logic from integrations/index.ts into
ensureDaemonClient() in daemon-client.ts as a generic utility.
- Update setupIntegration() and the CLI clients add --<integration>
paths to use the new helper.
- Return { client, created } so callers can decide whether to log.
- Remove IntegrationClient alias and ensureIntegrationClient export.
- Add shared DaemonClient type and addDaemonClient() helper in
daemon-client.ts as the single source for POST /clients/add.
- Update ensureIntegrationClient() to use the new helper.
- Update CLI clients add command to use the new helper.
- Keeps existing error handling and 'already exists' fallback in
ensureIntegrationClient().
- clients add: appends _<npub_suffix> to name when daemonUrl+nsec are set
- clients list: filters to only clients matching our npub suffix, strips suffix for display
- clients delete: auto-appends suffix to id before sending if not already present
- adds getNpubSuffix() helper in daemon-client.ts
- clients add --pi-agent/--opencode/--openclaw/--claude-code now call
/clients/add on the daemon instead of writing to local Bun SQLite
- add ensureIntegrationClient helper that creates via daemon and falls
back to fetching existing client on 409
- update install*Integration signatures to accept apiKey instead of SdkStore
- update onboard setupIntegration to use daemon-backed path
- update daemon scheduled refresh to pass apiKeys directly
- Add normalizeNostrPubkey, npubFromPubkey, npubFromSecretKey to nip98.ts
- Extend callDaemon to accept DELETE method
- Add subcommands:
- list: GET /npubs
- add <npub>: POST /npubs (accepts hex pubkey or npub1...)
- delete <npub>: DELETE /npubs/:npub (accepts hex pubkey or npub1...)
- All npubs commands go through callDaemon, so they work with
remote daemons and are automatically NIP-98 signed
- Export getDaemonBaseUrl from daemon-client for shared URL resolution
- Replace all hardcoded http://localhost: in client integrations
(opencode, claudecode, openclaw, pi) with getDaemonBaseUrl(config)
- Replace raw fetch(http://localhost:/models) with callDaemon("/models")
so model fetching works with remote daemons and gets NIP-98 signed
- Fix clients add command output to print the actual daemon base URL
instead of hardcoded localhost
- Add nostr-tools dependency for NIP-98 event signing
- Add nsec field to RoutstrdConfig for remote daemon authentication
- Extract NIP-98 auth utilities into src/utils/nip98.ts (parseSecretKey,
createNIP98Authorization with SHA-256 payload tags)
- Wire NIP-98 Authorization headers into callDaemon and isDaemonRunning
whenever both daemonUrl and nsec are configured
- Refactor refund command to use callDaemon instead of hardcoded localhost
so it works correctly with remote daemon URLs
- Add optional daemonUrl field to RoutstrdConfig
- Update callDaemon and isDaemonRunning to use configurable base URL
- Disable auto-start when daemonUrl is set (Option A)
- Gate local-only commands: onboard, start, restart, mode, logs, service install
- Moved daemon communication helpers (loadConfig, callDaemon,
isDaemonRunning, startDaemonProcess, ensureDaemonRunning,
handleDaemonCommand) from cli-shared.ts to src/utils/daemon-client.ts
- Moved the refund command from cli-shared.ts into cli.ts with the
rest of the CLI commands
- cli.ts now imports program directly from commander and daemon
helpers from utils/daemon-client
- TUI imports are updated to use utils/daemon-client
- Removed src/cli-shared.ts
Updates all user-facing log messages to include the /v1 path suffix,
so clients know to use http://localhost:${port}/v1 when configuring
their API endpoints.
- src/cli.ts:717 — clients add --setup-all flow
- src/cli.ts:757 — clients add -n ${name} flow
- src/daemon/index.ts:206 — daemon startup message
- src/start-daemon.ts:29 — daemon already running message
Add -m/--model option to models serving a
specific model with their pricing details (prompt, completion, request,
max_cost in sats). Providers are sorted by max_cost (cheapest first).
New endpoint: GET /models/:id/providers
New function: getModelProviders() in model service
The daemon's /usage endpoint returns { output: [...] } where output IS
the entries array directly, not an object with entries/totalEntries/etc.
Both the CLI usage command and TUI monitor expected the wrong shape,
causing entries.reduce to fail with 'is not a function'.
- Fix fetchUsage() to parse the array response correctly
- Fix CLI usage command to handle the array response
- Add defensive check in getTotals() for undefined/non-array input