<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Florin Dumitru</title>
    <description>The latest articles on DEV Community by Florin Dumitru (@nirolfx).</description>
    <link>https://dev.to/nirolfx</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3869337%2Fce9ebb54-1c5b-482d-b37b-7977f56e74d8.png</url>
      <title>DEV Community: Florin Dumitru</title>
      <link>https://dev.to/nirolfx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nirolfx"/>
    <language>en</language>
    <item>
      <title>I Built Blackdesk, a Keyboard-First Market Research Terminal with AI Connectors</title>
      <dc:creator>Florin Dumitru</dc:creator>
      <pubDate>Thu, 09 Apr 2026 08:30:13 +0000</pubDate>
      <link>https://dev.to/nirolfx/i-built-blackdesk-a-keyboard-first-market-research-terminal-with-ai-connectors-1m5m</link>
      <guid>https://dev.to/nirolfx/i-built-blackdesk-a-keyboard-first-market-research-terminal-with-ai-connectors-1m5m</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Why I built Blackdesk, an open source market research terminal that brings quotes, news, screeners, and AI connectors into one keyboard-first workspace.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you spend a lot of time doing market research, your workspace usually turns into a mess.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;That was the starting point for &lt;strong&gt;&lt;a href="https://blackdesk.ai" rel="noopener noreferrer"&gt;Blackdesk&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Blackdesk is an &lt;strong&gt;open source market research terminal&lt;/strong&gt; built in Go, designed to be &lt;strong&gt;local-first&lt;/strong&gt; and &lt;strong&gt;keyboard-first&lt;/strong&gt;. The idea is simple: quotes, charts, technicals, news, fundamentals, statements, insiders, screeners, and AI connectors, all in one focused desk inside the terminal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem I Wanted to Solve
&lt;/h2&gt;

&lt;p&gt;Most tools are decent at one slice of the problem, but the workflow itself is still fragmented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you search for a symbol in one place&lt;/li&gt;
&lt;li&gt;check the chart somewhere else&lt;/li&gt;
&lt;li&gt;read the news in the browser&lt;/li&gt;
&lt;li&gt;open another tool for screeners&lt;/li&gt;
&lt;li&gt;then manually push context into an AI chat&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For me, that is too much friction.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Blackdesk Is
&lt;/h2&gt;

&lt;p&gt;Blackdesk is organized around five main workspaces:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Markets&lt;/code&gt; for broad market context&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Quote&lt;/code&gt; for the active symbol&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;News&lt;/code&gt; for a normalized market-wide headline wire&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Screeners&lt;/code&gt; for discovery&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AI&lt;/code&gt; for desk-aware analysis based on the current context&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Inside &lt;code&gt;Quote&lt;/code&gt;, you can move quickly between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;chart&lt;/li&gt;
&lt;li&gt;fundamentals&lt;/li&gt;
&lt;li&gt;technicals&lt;/li&gt;
&lt;li&gt;financial statements&lt;/li&gt;
&lt;li&gt;insider activity&lt;/li&gt;
&lt;li&gt;company-specific news&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is simple: stay in one flow instead of constantly switching surfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Local-First and Keyboard-First
&lt;/h2&gt;

&lt;p&gt;I wanted the product to be terminal-native, not just something styled to look like a terminal.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;keyboard-first&lt;/code&gt; means the primary workflow should feel faster from keys than from clicks. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Tab&lt;/code&gt; switches workspaces&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/&lt;/code&gt; opens symbol search&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1-5&lt;/code&gt; jumps directly between views&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.&lt;/code&gt; focuses the AI input&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;c&lt;/code&gt;, &lt;code&gt;f&lt;/code&gt;, &lt;code&gt;t&lt;/code&gt;, &lt;code&gt;s&lt;/code&gt;, and &lt;code&gt;h&lt;/code&gt; switch sub-views inside &lt;code&gt;Quote&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;local-first&lt;/code&gt; means two important things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;the app runs as a local desk, not as a thin client glued to an opaque backend&lt;/li&gt;
&lt;li&gt;the AI layer is built around &lt;strong&gt;CLI-based AI connectors&lt;/strong&gt;, not a single hardcoded provider&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Right now, Blackdesk can work with installed AI CLIs such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Codex&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Claude Code&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OpenCode&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Important Part: AI with Real Context
&lt;/h2&gt;

&lt;p&gt;One thing I cared about early was making sure the AI layer does not receive raw, messy upstream payloads. It should receive &lt;strong&gt;normalized context from Blackdesk&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In practice, that means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the UI and providers are not directly coupled to prompt construction&lt;/li&gt;
&lt;li&gt;external data gets normalized before it flows through the app&lt;/li&gt;
&lt;li&gt;AI receives a relevant desk snapshot instead of a pile of improvised JSON&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That matters for a few reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;responses are more coherent&lt;/li&gt;
&lt;li&gt;the app can enforce clearer boundaries&lt;/li&gt;
&lt;li&gt;the architecture stays replaceable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Technical Stack
&lt;/h2&gt;

&lt;p&gt;Blackdesk is written in &lt;strong&gt;Go&lt;/strong&gt; and uses these libraries in the TUI layer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Bubble Tea&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Bubbles&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Lip Gloss&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ntcharts&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Architecturally, the project is moving toward a &lt;strong&gt;layered / ports-and-adapters&lt;/strong&gt; shape:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;internal/tui&lt;/code&gt; for presentation and interaction&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;internal/application&lt;/code&gt; for orchestration and use cases&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;internal/domain&lt;/code&gt; for normalized models&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;internal/providers&lt;/code&gt; for external data adapters&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;internal/agents&lt;/code&gt; for AI connector integrations&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;internal/storage&lt;/code&gt; for config and cache&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first market-data adapter is currently &lt;strong&gt;Yahoo Finance&lt;/strong&gt;, 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Wanted the Product to Feel Like
&lt;/h2&gt;

&lt;p&gt;I am not trying to build a “cool terminal app” for the sake of it.&lt;/p&gt;

&lt;p&gt;I am trying to build a tool that removes actual research friction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one desk for market context and symbol analysis&lt;/li&gt;
&lt;li&gt;a clear workflow between watchlists, quotes, news, and screeners&lt;/li&gt;
&lt;li&gt;AI that already understands the current context&lt;/li&gt;
&lt;li&gt;an architecture clean enough to replace providers and AI connectors over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To me, Blackdesk should feel closer to a &lt;strong&gt;workbench&lt;/strong&gt; than an app.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Is Not
&lt;/h2&gt;

&lt;p&gt;Blackdesk is not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a broker&lt;/li&gt;
&lt;li&gt;an execution platform&lt;/li&gt;
&lt;li&gt;an investment-advice product&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;That boundary felt important enough to make explicit in the product itself, not bury in a disclaimer.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Try It
&lt;/h2&gt;

&lt;p&gt;If you want to check it out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://blackdesk.ai" rel="noopener noreferrer"&gt;blackdesk.ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/Blackdesk-ai/blackdesk" rel="noopener noreferrer"&gt;github.com/Blackdesk-ai/blackdesk&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://blackdesk.ai/install | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;blackdesk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first workflow I recommend is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;press &lt;code&gt;/&lt;/code&gt; and search for a symbol&lt;/li&gt;
&lt;li&gt;open it in &lt;code&gt;Quote&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;move through &lt;code&gt;c&lt;/code&gt;, &lt;code&gt;f&lt;/code&gt;, &lt;code&gt;t&lt;/code&gt;, &lt;code&gt;s&lt;/code&gt;, and &lt;code&gt;h&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;jump into &lt;code&gt;Markets&lt;/code&gt;, &lt;code&gt;News&lt;/code&gt;, and &lt;code&gt;Screeners&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;open &lt;code&gt;AI&lt;/code&gt; and ask for a summary of the active setup&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What Comes Next
&lt;/h2&gt;

&lt;p&gt;Blackdesk is still under active development, which is part of the fun.&lt;/p&gt;

&lt;p&gt;The direction I want to keep is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;terminal-first without becoming rigid&lt;/li&gt;
&lt;li&gt;AI that is useful, not decorative&lt;/li&gt;
&lt;li&gt;modular architecture&lt;/li&gt;
&lt;li&gt;a product that stays fast, focused, and workflow-driven&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;Quote&lt;/code&gt;, &lt;code&gt;Markets&lt;/code&gt;, &lt;code&gt;News&lt;/code&gt;, &lt;code&gt;Screeners&lt;/code&gt;, and &lt;code&gt;AI&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>go</category>
      <category>claude</category>
      <category>openai</category>
    </item>
  </channel>
</rss>
