Skip to content

feat(ticker): equity research in the pit, shipped as an installable plugin - #318

Merged
ralyodio merged 1 commit into
mainfrom
worktree-advisor-plugin
Aug 6, 2026
Merged

feat(ticker): equity research in the pit, shipped as an installable plugin#318
ralyodio merged 1 commit into
mainfrom
worktree-advisor-plugin

Conversation

@ralyodio

@ralyodio ralyodio commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Adds /ticker and its siblings to moshcode, backed by advis0r.com's API, and ships them as an installable Claude Code plugin.

moshcode ticker / /ticker

moshcode ticker NVDA               # score, technicals, fundamentals, thesis, signals, sources
moshcode ticker lookup rivian      # company name → RIVN
moshcode ticker signals AAPL       # what was said, quoted and sourced
moshcode ticker search "data center"
moshcode ticker reports --limit 10
moshcode ticker discover fusion    # ranked watchlist (slow — analyzes each candidate)
moshcode ticker open NVDA

A bare symbol is the report, so the headline case stays the shortest thing to type. --json on any verb gives the raw response. MOSHCODE_ADVISOR_URL points it at another instance.

Every route used is public, read-only and unauthenticated — no login verb, no write path, no credentials held. The authenticated routes (/api/digest, /api/report/regenerate) are deliberately out of scope.

Two rules the renderers enforce rather than merely document:

  • A stored snapshot always prints its reportGeneratedAt, whether the price is delayed, and which feed produced it. Presenting a stale price as a live quote is the one failure mode here that costs someone money.
  • The API's own disclaimer travels with the data into the output.

A model-written thesis is labelled with its provider and model; a deterministic one is labelled offline. Missing sections (SEC or the market feed rate-limiting) degrade the report rather than preventing one.

moshcode plugin — the marketplace

moshcode already fans MCP servers and skills out across engines but published none of its own commands. This adds .claude-plugin/marketplace.json and a ticker plugin providing /ticker, /signals, /research, /lookup, /reports, /discover inside the engine.

moshcode plugin install           # marketplace add + plugin install
moshcode plugin list
moshcode plugin remove ticker

The fan-out follows the same contract as skills (prd/0003 R8): every engine appears in the summary, and the ones with no plugin primitive say so instead of being silently omitted. MOSHCODE_PLUGIN_SOURCE=. installs from a checkout.

Verification

  • Full suite: 1142 passing, 0 failing (40 new tests across test/advisor.test.mjs and test/plugins.test.mjs).
  • claude plugin validate passes on both manifests, --strict included. It caught a real bug first: an unquoted [--limit n] in argument-hint is a YAML flow sequence, and the parse error silently drops every frontmatter field. There is now a test for that shape.
  • Installed end to end against a local checkout — Claude Code registered all six commands (~186 tokens always-on) — then uninstalled and the temporary marketplace removed, leaving the machine clean.
  • Rendering checked against live responses for every verb.

Drift guards required regenerating the README command table and the PRD index; both are generated, not hand-edited.

Notes

Design and rationale in prd/0008-ticker-research-and-plugin-marketplace.md.

Scored equity research now sits one verb away from an order-placing CLI. The separation is structural rather than advisory: ticker has no write path, trade keeps its preview-by-default guard, and nothing in the plugin can place an order.

🤖 Generated with Claude Code

…lugin

`trade` could quote a price and place an order, but nothing answered the
question that comes first. `moshcode ticker <SYMBOL>` renders advis0r.com's
stored research report — score, technicals, SEC fundamentals, thesis, signals
with their sources — plus verbs for signals, transcript search, company-name
lookup, the stored report index, ranked discovery, and coverage stats. Same
surface as `/ticker` at the mosh prompt.

Every route used is public, read-only and unauthenticated, so there is no login
verb and no write path. Two rules the renderers enforce rather than document: a
stored snapshot always prints its `reportGeneratedAt`, whether the price is
delayed and which feed produced it — a stale price dressed as a live one is the
one failure mode that costs money — and the API's own disclaimer travels with
the data.

Also publishes moshcode's first Claude Code marketplace. `moshcode plugin
install` adds it and installs `ticker@moshcode`, which provides /ticker,
/signals, /research, /lookup, /reports and /discover inside the engine. The
fan-out follows the same contract as skills (prd/0003 R8): every engine appears
in the summary, and the ones with no plugin primitive say so.

See prd/0008.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Comment thread test/plugins.test.mjs

test("the source is overridable, so an unreleased plugin is installable", () => {
assert.equal(marketplaceSource({}), "moshcoder/moshcode");
assert.equal(marketplaceSource({ MOSHCODE_PLUGIN_SOURCE: "/tmp/checkout" }), "/tmp/checkout");
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

ThreatCrush Security Scan

93 finding(s)

HIGH/CRITICAL: 50 | MEDIUM: 43

Severity Rule Location
HIGH manifest-typosquat apps/pwa/package.json:19
HIGH js-ssrf-outbound-request apps/pwa/public/sw.js:45
HIGH secret-generic-credential apps/pwa/test/apikey-bearer-scheme.test.mjs:30
HIGH secret-generic-credential apps/pwa/test/apikey-mask.test.mjs:38
HIGH secret-generic-credential apps/pwa/test/apikey-reveal.test.mjs:35
HIGH secret-generic-credential apps/pwa/test/approvals-context.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/approvals-credits.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/approvals-notify.test.mjs:26
HIGH secret-generic-credential apps/pwa/test/approvals-resolve-race.test.mjs:20
HIGH secret-generic-credential apps/pwa/test/auth-form-email.test.mjs:29
HIGH secret-generic-credential apps/pwa/test/auth-form-email.test.mjs:33
HIGH secret-generic-credential apps/pwa/test/auth-page-error.test.mjs:36
HIGH secret-generic-credential apps/pwa/test/cli-device-token.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/cli-pages-balance.test.mjs:32
HIGH secret-generic-credential apps/pwa/test/cli-token.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/credits-pack.test.mjs:51
HIGH secret-generic-credential apps/pwa/test/credits-webhook-event-match.test.mjs:35
HIGH secret-generic-credential apps/pwa/test/credits-webhook.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/csrf-input-escaping.test.mjs:31
HIGH secret-generic-credential apps/pwa/test/csrf-input-escaping.test.mjs:101
HIGH secret-generic-credential apps/pwa/test/logout-csrf.test.mjs:29
HIGH secret-generic-credential apps/pwa/test/moshpit-api-key.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/moshpit-bulk-claim.test.mjs:23
HIGH secret-generic-credential apps/pwa/test/moshpit-claim-full-name.test.mjs:29
HIGH secret-generic-credential apps/pwa/test/moshpit-crawlable.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/moshpit-ending-page.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/moshpit-pins.test.mjs:22
HIGH secret-generic-credential apps/pwa/test/moshpit-pit-page.test.mjs:33
HIGH secret-generic-credential apps/pwa/test/moshpit-records-page.test.mjs:23
HIGH secret-generic-credential apps/pwa/test/moshpit-records.test.mjs:23
HIGH secret-generic-credential apps/pwa/test/moshpit-registry.test.mjs:20
HIGH secret-generic-credential apps/pwa/test/moshpit-related-endings.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/moshpit-sales.test.mjs:16
HIGH secret-generic-credential apps/pwa/test/moshpit-search.test.mjs:74
HIGH secret-generic-credential apps/pwa/test/moshpit-terms.test.mjs:19
HIGH secret-generic-credential apps/pwa/test/moshpit-tlds-pagination.test.mjs:28
HIGH secret-generic-credential apps/pwa/test/passkey-register-duplicate.test.mjs:38
HIGH secret-generic-credential apps/pwa/test/require-auth-next.test.mjs:31
HIGH secret-generic-credential apps/pwa/test/require-auth-next.test.mjs:35
HIGH secret-generic-credential apps/pwa/test/sessions-output-seq.test.mjs:30
HIGH secret-generic-credential apps/pwa/test/sessions-paste.test.mjs:24
HIGH secret-generic-credential apps/pwa/test/sessions-stream-replay.test.mjs:34
HIGH secret-generic-credential apps/pwa/test/sessions.test.mjs:24
HIGH secret-generic-credential apps/pwa/test/signature.test.mjs:6
HIGH secret-generic-credential test/auth.test.mjs:13
HIGH secret-generic-credential test/auth.test.mjs:148
HIGH secret-generic-credential test/console-cookie-malformed.test.mjs:15
HIGH secret-generic-credential test/console.test.mjs:12
HIGH secret-generic-credential test/mirror.test.mjs:37
HIGH secret-generic-credential test/mirror.test.mjs:77

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

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio marked this pull request as ready for review August 6, 2026 15:34
@ralyodio
ralyodio merged commit fb4ff90 into main Aug 6, 2026
4 checks passed
@ralyodio ralyodio mentioned this pull request Aug 6, 2026
ralyodio added a commit that referenced this pull request Aug 6, 2026
Bump to v0.26.0, releasing two features that have been sitting on main
unreleased: posting to Bluesky and Nostr from the pit (#317), and equity
research via `moshcode ticker` / `/ticker` backed by advis0r.com, shipped
alongside moshcode's first Claude Code plugin marketplace (#318).

Minor rather than patch: both add commands, neither changes an existing one.

This release is also what makes the `ticker` plugin's primary path work.
install.sh serves the latest release tarball, not main, so every machine
running the installed binary reports `unknown command "ticker"` until a
release carries it — the plugin's slash commands fall back to curl in the
meantime, which works but skips the rendering the verb exists to do.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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.

2 participants