<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[ ]]></title><description><![CDATA[ ]]></description><link>https://florindumitru.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Fri, 18 Sep 2026 00:56:32 GMT</lastBuildDate><atom:link href="https://florindumitru.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[I Built Blackdesk, a Keyboard-First Market Research Terminal with AI Connectors]]></title><description><![CDATA[If you spend a lot of time doing market research, your workspace usually turns into a mess.
You search for a symbol in one app, check the chart somewhere else, read the news in the browser, run a scre]]></description><link>https://florindumitru.hashnode.dev/i-built-blackdesk-a-keyboard-first-market-research-terminal-with-ai-connectors</link><guid isPermaLink="true">https://florindumitru.hashnode.dev/i-built-blackdesk-a-keyboard-first-market-research-terminal-with-ai-connectors</guid><category><![CDATA[openai]]></category><category><![CDATA[Go Language]]></category><category><![CDATA[stockmarket]]></category><category><![CDATA[finance]]></category><dc:creator><![CDATA[Florin Dumitru]]></dc:creator><pubDate>Thu, 09 Apr 2026 08:39:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/5d24c6642408cec879502c19/735dfb9c-be85-4655-89e3-8ce5c7e15c63.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you spend a lot of time doing market research, your workspace usually turns into a mess.</p>
<p>You search for a symbol in one app, check the chart somewhere else, read the news in the browser, run a screener in another tab, and then paste half of that context into an AI chat that has no idea what you were looking at five seconds ago.</p>
<p>That was the starting point for <a href="https://blackdesk.ai"><strong>Blackdesk</strong></a>.</p>
<p>Blackdesk is an <strong>open source market research terminal</strong> built in Go, designed to be <strong>local-first</strong> and <strong>keyboard-first</strong>. The idea is simple: quotes, charts, technicals, news, fundamentals, statements, insiders, screeners, and AI connectors, all in one focused desk inside the terminal.</p>
<h2>The Problem I Wanted to Solve</h2>
<p>Most tools are decent at one slice of the problem, but the workflow itself is still fragmented:</p>
<ul>
<li><p>you search for a symbol in one place</p>
</li>
<li><p>check the chart somewhere else</p>
</li>
<li><p>read the news in the browser</p>
</li>
<li><p>open another tool for screeners</p>
</li>
<li><p>then manually push context into an AI chat</p>
</li>
</ul>
<p>For me, that is too much friction.</p>
<p>I did not want another overloaded “all-in-one dashboard.” I wanted a tool that felt more like a workbench: fast, clear, easy to drive from the keyboard, and modular enough that I can swap market-data providers or AI connectors without rebuilding the whole thing.</p>
<h2>What Blackdesk Is</h2>
<p>Blackdesk is organized around five main workspaces:</p>
<ol>
<li><p><code>Markets</code> for broad market context</p>
</li>
<li><p><code>Quote</code> for the active symbol</p>
</li>
<li><p><code>News</code> for a normalized market-wide headline wire</p>
</li>
<li><p><code>Screeners</code> for discovery</p>
</li>
<li><p><code>AI</code> for desk-aware analysis based on the current context</p>
</li>
</ol>
<p>Inside <code>Quote</code>, you can move quickly between:</p>
<ul>
<li><p>chart</p>
</li>
<li><p>fundamentals</p>
</li>
<li><p>technicals</p>
</li>
<li><p>financial statements</p>
</li>
<li><p>insider activity</p>
</li>
<li><p>company-specific news</p>
</li>
</ul>
<p>The goal is simple: stay in one flow instead of constantly switching surfaces.</p>
<h2>Why Local-First and Keyboard-First</h2>
<p>I wanted the product to be terminal-native, not just something styled to look like a terminal.</p>
<p><code>keyboard-first</code> means the primary workflow should feel faster from keys than from clicks. For example:</p>
<ul>
<li><p><code>Tab</code> switches workspaces</p>
</li>
<li><p><code>/</code> opens symbol search</p>
</li>
<li><p><code>1-5</code> jumps directly between views</p>
</li>
<li><p><code>.</code> focuses the AI input</p>
</li>
<li><p><code>c</code>, <code>f</code>, <code>t</code>, <code>s</code>, and <code>h</code> switch sub-views inside <code>Quote</code></p>
</li>
</ul>
<p><code>local-first</code> means two important things:</p>
<ol>
<li><p>the app runs as a local desk, not as a thin client glued to an opaque backend</p>
</li>
<li><p>the AI layer is built around <strong>CLI-based AI connectors</strong>, not a single hardcoded provider</p>
</li>
</ol>
<p>Right now, Blackdesk can work with installed AI CLIs such as:</p>
<ul>
<li><p><code>Codex</code></p>
</li>
<li><p><code>Claude Code</code></p>
</li>
<li><p><code>OpenCode</code></p>
</li>
</ul>
<p>That distinction matters. Blackdesk is not trying to be “a local LLM terminal app.” The AI layer is a workspace that uses connectors to tools like Codex, Claude Code, and OpenCode, while passing in relevant context from the desk.</p>
<h2>The Important Part: AI with Real Context</h2>
<p>One thing I cared about early was making sure the AI layer does not receive raw, messy upstream payloads. It should receive <strong>normalized context from Blackdesk</strong>.</p>
<p>In practice, that means:</p>
<ul>
<li><p>the UI and providers are not directly coupled to prompt construction</p>
</li>
<li><p>external data gets normalized before it flows through the app</p>
</li>
<li><p>AI receives a relevant desk snapshot instead of a pile of improvised JSON</p>
</li>
</ul>
<p>That matters for a few reasons:</p>
<ul>
<li><p>responses are more coherent</p>
</li>
<li><p>the app can enforce clearer boundaries</p>
</li>
<li><p>the architecture stays replaceable</p>
</li>
</ul>
<p>I also wanted explicit boundaries. For example, screener data is intentionally excluded from AI context. I wanted a clean separation between discovery flows and contextual analysis of the current symbol or market state.</p>
<h2>The Technical Stack</h2>
<p>Blackdesk is written in <strong>Go</strong> and uses these libraries in the TUI layer:</p>
<ul>
<li><p><code>Bubble Tea</code></p>
</li>
<li><p><code>Bubbles</code></p>
</li>
<li><p><code>Lip Gloss</code></p>
</li>
<li><p><code>ntcharts</code></p>
</li>
</ul>
<p>Architecturally, the project is moving toward a <strong>layered / ports-and-adapters</strong> shape:</p>
<ul>
<li><p><code>internal/tui</code> for presentation and interaction</p>
</li>
<li><p><code>internal/application</code> for orchestration and use cases</p>
</li>
<li><p><code>internal/domain</code> for normalized models</p>
</li>
<li><p><code>internal/providers</code> for external data adapters</p>
</li>
<li><p><code>internal/agents</code> for AI connector integrations</p>
</li>
<li><p><code>internal/storage</code> for config and cache</p>
</li>
</ul>
<p>The first market-data adapter is currently <strong>Yahoo Finance</strong>, and market-wide news runs through a separate RSS provider. That separation is important to me: the UI should not depend on the shape of an upstream payload.</p>
<h2>What I Wanted the Product to Feel Like</h2>
<p>I am not trying to build a “cool terminal app” for the sake of it.</p>
<p>I am trying to build a tool that removes actual research friction:</p>
<ul>
<li><p>one desk for market context and symbol analysis</p>
</li>
<li><p>a clear workflow between watchlists, quotes, news, and screeners</p>
</li>
<li><p>AI that already understands the current context</p>
</li>
<li><p>an architecture clean enough to replace providers and AI connectors over time</p>
</li>
</ul>
<p>To me, Blackdesk should feel closer to a <strong>workbench</strong> than an app.</p>
<h2>What It Is Not</h2>
<p>Blackdesk is not:</p>
<ul>
<li><p>a broker</p>
</li>
<li><p>an execution platform</p>
</li>
<li><p>an investment-advice product</p>
</li>
</ul>
<p>It is a research tool. That means market data can be incomplete, delayed, or affected by upstream provider behavior, and important decisions still need to be verified against authoritative sources.</p>
<p>That boundary felt important enough to make explicit in the product itself, not bury in a disclaimer.</p>
<h2>How to Try It</h2>
<p>If you want to check it out:</p>
<ul>
<li><p>Website: <a href="https://blackdesk.ai">blackdesk.ai</a></p>
</li>
<li><p>GitHub: <a href="https://github.com/Blackdesk-ai/blackdesk">github.com/Blackdesk-ai/blackdesk</a></p>
</li>
</ul>
<p>Install:</p>
<pre><code class="language-bash">curl -fsSL https://blackdesk.ai/install | bash
</code></pre>
<p>Run:</p>
<pre><code class="language-bash">blackdesk
</code></pre>
<p>The first workflow I recommend is:</p>
<ol>
<li><p>press <code>/</code> and search for a symbol</p>
</li>
<li><p>open it in <code>Quote</code></p>
</li>
<li><p>move through <code>c</code>, <code>f</code>, <code>t</code>, <code>s</code>, and <code>h</code></p>
</li>
<li><p>jump into <code>Markets</code>, <code>News</code>, and <code>Screeners</code></p>
</li>
<li><p>open <code>AI</code> and ask for a summary of the active setup</p>
</li>
</ol>
<h2>What Comes Next</h2>
<p>Blackdesk is still under active development, which is part of the fun.</p>
<p>The direction I want to keep is:</p>
<ul>
<li><p>terminal-first without becoming rigid</p>
</li>
<li><p>AI that is useful, not decorative</p>
</li>
<li><p>modular architecture</p>
</li>
<li><p>a product that stays fast, focused, and workflow-driven</p>
</li>
</ul>
<p>If you like local tools, carefully designed terminal interfaces, and the idea of putting market research and contextual AI in the same place, Blackdesk will probably make sense to you.</p>
<p>If people are interested, I can also write a more technical follow-up about the architecture, Bubble Tea, AI context design, or how I split the product into <code>Quote</code>, <code>Markets</code>, <code>News</code>, <code>Screeners</code>, and <code>AI</code>.</p>
]]></content:encoded></item></channel></rss>