Skip to content

feat(crypto): /crypto market data, alongside /ticker - #322

Merged
ralyodio merged 1 commit into
mainfrom
worktree-crypto-command
Aug 8, 2026
Merged

feat(crypto): /crypto market data, alongside /ticker#322
ralyodio merged 1 commit into
mainfrom
worktree-crypto-command

Conversation

@ralyodio

@ralyodio ralyodio commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

advis0r.com now serves crypto under /crypto/**, so the pit gets the sibling of ticker that surface implies: moshcode crypto (and /crypto in the pit), plus a crypto@moshcode plugin for Claude Code.

moshcode crypto BTC                # price, technicals, score, supply, book
moshcode crypto lookup bitcoin     # asset name → BTC/USD
moshcode crypto spark BTC ETH SOL  # recent moves, ranked
moshcode crypto bars ETH --timeframe 1Hour
moshcode crypto book BTC-USD --depth 5

Pairs are accepted as BTC, BTC-USD, BTC/USD or BTCUSD. A bare asset resolves to that asset's USD pair.

Why a sibling, not a mode of ticker

They answer different questions from different data and share only a hostname. A ticker report is a stored snapshot built from transcripts, SEC fundamentals and extracted signals — its risk is a stale price read as a live one. A crypto report is a live venue read with no transcripts, no filings and no signals — its risk runs the other way. One code path would mean one set of labels lying about one of them.

The scores are not comparable either: the crypto technical score counts venue-local liquidity, so ranking a coin against an equity by score is meaningless. Both surfaces ship their own caveats, and both renderers print them.

Two things that would otherwise be quietly wrong

  • Precision. Prices render at the precision the pair trades at. A fixed two decimals renders half the index — SHIB near $0.000006 — as $0.00. Derived numbers are priced like the number beside them, so a $126.10 move on a $65,021.84 coin does not print as $126.0980.
  • --limit on bars. Upstream treats it as a page size over its own window, not a cap on what returns — --limit 5 came back with seventeen bars. The renderer honours the flag and states that it trimmed (5 × 1Hour · newest of 17) rather than breaking the promise silently or printing everything.

Surface

  • src/crypto.mjs — pure argument translation, injectable fetch, rendering as a function of decoded JSON (the same split as src/advisor.mjs).
  • Dispatch in bin/moshcode.mjs and src/tui.mjs; schema entries drive /help, completion and the pit command list.
  • plugins/crypto//crypto, /quote, /book, /bars, /spark, /pairs, /coin. No name collides with the ticker plugin's commands.
  • The plugin frontmatter test now iterates the marketplace manifest instead of hard-coding plugins/ticker, so a plugin added later cannot ship unchecked.

Verification

  • Full suite: 1385 tests, 0 fail (27 new in test/crypto.test.mjs).
  • Smoke-tested live against advis0r for every verb, plus the error paths (unsupported pair, asset name instead of a pair, bad flag values) and /crypto inside the pit.

🤖 Generated with Claude Code

advis0r.com now serves crypto under /crypto/**, so the pit gets the sibling
of `ticker` that surface implies: `moshcode crypto` (and `/crypto` in the pit),
plus a `crypto@moshcode` plugin for Claude Code.

A sibling rather than a mode of `ticker`, because the two answer different
questions from different data. A ticker report is a stored snapshot built from
transcripts, SEC fundamentals and extracted signals — its risk is a stale price
read as a live one. A crypto report is a live venue read with none of those —
its risk runs the other way. One code path would mean one set of labels lying
about one of them, so the technical score, which counts venue-local liquidity,
is never presented as comparable to an equity's.

  moshcode crypto BTC                # price, technicals, score, supply, book
  moshcode crypto lookup bitcoin     # asset name → BTC/USD
  moshcode crypto spark BTC ETH SOL  # recent moves, ranked
  moshcode crypto bars ETH --timeframe 1Hour
  moshcode crypto book BTC-USD --depth 5

Notes on two things that would otherwise be quietly wrong:

- Prices are formatted at the precision the pair trades at. A fixed two
  decimals renders half the index — SHIB near $0.000006 — as "$0.00".
- Upstream treats `bars`' `limit` as a page size over its own window, not a cap
  on what returns: `--limit 5` came back with seventeen bars. The renderer
  honours the flag and says that it trimmed, rather than breaking the promise
  silently or printing everything.

The plugin frontmatter test now iterates the marketplace manifest instead of
hard-coding plugins/ticker, so a plugin added later cannot ship unchecked.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown

ThreatCrush Security Scan

91 finding(s)

HIGH/CRITICAL: 2 | MEDIUM: 41 | LOW: 48

Severity Rule Location
HIGH manifest-typosquat apps/pwa/package.json:19
HIGH js-ssrf-outbound-request apps/pwa/public/sw.js:45
MEDIUM tls-verification-disabled apps/pwa/src/lib/moshpit-gateway.mjs:299
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:61
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:75
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:101
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:265
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:269
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:314
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:499
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:675
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:677
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:736
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:782
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:852
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:955
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:1063
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:1199
MEDIUM js-unescaped-html-sink apps/pwa/src/routes/moshpit.mjs:1419
MEDIUM js-dynamic-code-execution apps/pwa/test/apikey-mask.test.mjs:129
MEDIUM sql-template-interpolation apps/pwa/test/credits-webhook-event-match.test.mjs:111
MEDIUM sql-template-interpolation apps/pwa/test/credits-webhook-event-match.test.mjs:131
MEDIUM sql-template-interpolation apps/pwa/test/moshpit-terms.test.mjs:192
MEDIUM sql-template-interpolation src/dns.mjs:2439
MEDIUM sql-template-interpolation src/selfupdate.mjs:166
MEDIUM sql-template-interpolation src/selfupdate.mjs:170
MEDIUM sql-template-interpolation src/selfupdate.mjs:208
MEDIUM sql-template-interpolation src/selfupdate.mjs:209
MEDIUM insecure-temp-file test/dns-disable-restore.test.mjs:93
MEDIUM insecure-temp-file test/dns-disable-restore.test.mjs:310
MEDIUM insecure-temp-file test/plugins.test.mjs:92
MEDIUM insecure-temp-file test/pty.test.mjs:28
MEDIUM insecure-temp-file test/pty.test.mjs:31
MEDIUM insecure-temp-file test/pty.test.mjs:40
MEDIUM insecure-temp-file test/pty.test.mjs:42
MEDIUM insecure-temp-file test/pty.test.mjs:47
MEDIUM insecure-temp-file test/pty.test.mjs:48
MEDIUM insecure-temp-file test/pty.test.mjs:49
MEDIUM insecure-temp-file test/tabs.test.mjs:8
MEDIUM insecure-temp-file test/tabs.test.mjs:13
MEDIUM insecure-temp-file test/tabs.test.mjs:14
MEDIUM insecure-temp-file test/tabs.test.mjs:22
MEDIUM insecure-temp-file test/trust.test.mjs:240
LOW secret-generic-credential apps/pwa/test/apikey-bearer-scheme.test.mjs:30
LOW secret-generic-credential apps/pwa/test/apikey-mask.test.mjs:38
LOW secret-generic-credential apps/pwa/test/apikey-reveal.test.mjs:35
LOW secret-generic-credential apps/pwa/test/approvals-context.test.mjs:28
LOW secret-generic-credential apps/pwa/test/approvals-credits.test.mjs:28
LOW secret-generic-credential apps/pwa/test/approvals-notify.test.mjs:26
LOW secret-generic-credential apps/pwa/test/approvals-resolve-race.test.mjs:20

…and 41 more. Full results in the Security tab.

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit 5ba3c77 into main Aug 8, 2026
4 checks passed
@ralyodio ralyodio mentioned this pull request Aug 8, 2026
ralyodio added a commit that referenced this pull request Aug 8, 2026
Bump to v0.27.0, releasing `/crypto` — crypto market data from advis0r.com as
a CLI verb, a pit command, and a second Claude Code plugin (#322) — alongside
two commits that have been sitting on main unreleased: the compact() carry fix
for `ticker` (#321) and the move off the deprecated Node 20 runtime (#320).

Minor rather than patch: it adds a command and a plugin, and changes no
existing one.

As with v0.26.0 and `ticker`, the release is what makes the plugin's primary
path work. install.sh serves the latest release tarball, not main, so until a
release carries it every installed binary answers `unknown command "crypto"`
and the plugin's slash commands fall back to curl — which works, but skips the
rendering the verb exists to do.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ralyodio
ralyodio deleted the worktree-crypto-command branch August 8, 2026 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant