<?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: Milo</title>
    <description>The latest articles on DEV Community by Milo (@milovale).</description>
    <link>https://dev.to/milovale</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4003102%2F94f2fe1c-7d16-4910-8423-484a45c23945.png</url>
      <title>DEV Community: Milo</title>
      <link>https://dev.to/milovale</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/milovale"/>
    <language>en</language>
    <item>
      <title>I got tired of TODO comments losing context, so I built GhostMap</title>
      <dc:creator>Milo</dc:creator>
      <pubDate>Mon, 06 Jul 2026 12:01:00 +0000</pubDate>
      <link>https://dev.to/milovale/i-got-tired-of-todo-comments-losing-context-so-i-built-ghostmap-2icj</link>
      <guid>https://dev.to/milovale/i-got-tired-of-todo-comments-losing-context-so-i-built-ghostmap-2icj</guid>
      <description>&lt;p&gt;I opened an old TypeScript service after a few weeks away from it and found this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// TODO: fix retry logic&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;chargeCustomer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChargeInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The comment was technically useful when I wrote it.&lt;/p&gt;

&lt;p&gt;Later, it was almost useless.&lt;/p&gt;

&lt;p&gt;It did not tell me why the retry logic was risky. It did not tell me whether the issue was still open. It did not tell me if the problem was duplicate charges, provider timeouts, idempotency keys, or cleanup I never finished.&lt;/p&gt;

&lt;p&gt;That is the problem I kept running into with TODO and FIXME comments.&lt;/p&gt;

&lt;p&gt;They are easy to write, but they lose context fast.&lt;/p&gt;

&lt;p&gt;So I built GhostMap, a VS Code extension for structured &lt;a class="mentioned-user" href="https://dev.to/ghost"&gt;@ghost&lt;/a&gt; annotations.&lt;/p&gt;

&lt;p&gt;The idea is simple:&lt;/p&gt;

&lt;p&gt;Keep developer context inside the code, but make it structured and navigable instead of leaving it as scattered comments.&lt;/p&gt;

&lt;p&gt;Marketplace:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=Ghostmap.ghostmap" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=Ghostmap.ghostmap&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with normal TODO comments
&lt;/h2&gt;

&lt;p&gt;A normal TODO usually captures one thing:&lt;/p&gt;

&lt;p&gt;Something is unfinished.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// TODO: handle timeout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is fine for short-lived notes.&lt;/p&gt;

&lt;p&gt;It breaks down when the comment stays in the code longer than expected.&lt;/p&gt;

&lt;p&gt;After a week or two, you usually need more than the note itself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the actual risk?&lt;/li&gt;
&lt;li&gt;Is this still open?&lt;/li&gt;
&lt;li&gt;Who should care about it?&lt;/li&gt;
&lt;li&gt;Does it belong to the function below it, the whole class, or a larger section?&lt;/li&gt;
&lt;li&gt;Is it a cleanup task, production risk, migration marker, or review note?&lt;/li&gt;
&lt;li&gt;Is it still relevant after the last refactor?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The comment is close to the code, which is good.&lt;/p&gt;

&lt;p&gt;The problem is that it has no structure.&lt;/p&gt;

&lt;p&gt;Issue trackers solve some of this, but they are not always the right place for code-local context. Pull requests solve some of it too, but PR context is often gone from your head by the time you revisit the file.&lt;/p&gt;

&lt;p&gt;I wanted something lighter than a tracker and more durable than a random TODO.&lt;/p&gt;

&lt;h2&gt;
  
  
  The smallest useful upgrade: structured comments
&lt;/h2&gt;

&lt;p&gt;Instead of this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// TODO: retry issue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GhostMap uses this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @ghost #payment-retry status:in-progress description: retry can double-charge if provider timeout returns late&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That one line carries more useful information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a class="mentioned-user" href="https://dev.to/ghost"&gt;@ghost&lt;/a&gt; marks it as intentional project context&lt;/li&gt;
&lt;li&gt;#payment-retry gives it a stable name&lt;/li&gt;
&lt;li&gt;status:in-progress makes the state visible&lt;/li&gt;
&lt;li&gt;description: keeps the reason next to the code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GhostMap then turns those annotations into a navigable tree inside VS Code.&lt;/p&gt;

&lt;p&gt;That is the main difference.&lt;/p&gt;

&lt;p&gt;It is not just coloring comments.&lt;/p&gt;

&lt;p&gt;It is turning important code-local context into something you can browse and jump to.&lt;/p&gt;

&lt;h2&gt;
  
  
  A more realistic example
&lt;/h2&gt;

&lt;p&gt;Here is a simplified payment service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// @ghost #payment-retry status:in-progress description: retry can double-charge if provider timeout returns late&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;chargeCustomer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChargeInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// @ghost description: review idempotency behavior before enterprise rollout | status:review&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;buildIdempotencyKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;invoiceId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;invoiceId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// @ghost #legacy-refund-flow start status:todo description: remove once refunds move to provider v3&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;refundPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;paymentId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// old implementation&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;refundPartialPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;paymentId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// old implementation&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// @ghost end&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are three patterns here.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Named anchors
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @ghost #payment-retry status:in-progress description: retry can double-charge if provider timeout returns late&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A named anchor is useful when the note deserves its own identity.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;#payment-retry&lt;/li&gt;
&lt;li&gt;#auth-hardening&lt;/li&gt;
&lt;li&gt;#v2-migration&lt;/li&gt;
&lt;li&gt;#danger-zone&lt;/li&gt;
&lt;li&gt;#cleanup-before-release&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the kind of annotation I would use for a risky area, a migration point, or something I expect to revisit later.&lt;/p&gt;

&lt;p&gt;It becomes easier to talk about because it has a name.&lt;/p&gt;

&lt;p&gt;Instead of saying:&lt;/p&gt;

&lt;p&gt;Look at that retry TODO in the payment service.&lt;/p&gt;

&lt;p&gt;You can say:&lt;/p&gt;

&lt;p&gt;Check #payment-retry.&lt;/p&gt;

&lt;p&gt;That small naming step matters more than I expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Contextual annotations
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @ghost description: review idempotency behavior before enterprise rollout | status:review&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;buildIdempotencyKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;invoiceId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;invoiceId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A contextual annotation does not need a named node.&lt;/p&gt;

&lt;p&gt;It adds context to the nearby symbol.&lt;/p&gt;

&lt;p&gt;That is useful when the important thing is not the annotation itself, but the function, method, or class it belongs to.&lt;/p&gt;

&lt;p&gt;In this case, the note belongs to buildIdempotencyKey.&lt;/p&gt;

&lt;p&gt;I do not need a separate named item for it. I just need the context to stay attached to the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Range anchors
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @ghost #legacy-refund-flow start status:todo description: remove once refunds move to provider v3&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;refundPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;paymentId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// old implementation&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;refundPartialPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;paymentId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// old implementation&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// @ghost end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A range anchor marks a section of code.&lt;/p&gt;

&lt;p&gt;That is useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;migrations&lt;/li&gt;
&lt;li&gt;risky regions&lt;/li&gt;
&lt;li&gt;refactor zones&lt;/li&gt;
&lt;li&gt;temporary compatibility layers&lt;/li&gt;
&lt;li&gt;code that should disappear after a version upgrade&lt;/li&gt;
&lt;li&gt;implementation areas that should be reviewed together&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was one of the main reasons I wanted GhostMap to exist.&lt;/p&gt;

&lt;p&gt;A lot of important context is not attached to one single line.&lt;/p&gt;

&lt;p&gt;Sometimes the context belongs to a region.&lt;/p&gt;

&lt;p&gt;Normal TODO comments are weak at that.&lt;/p&gt;

&lt;h2&gt;
  
  
  What GhostMap does inside VS Code
&lt;/h2&gt;

&lt;p&gt;GhostMap is currently focused on the file you have open.&lt;/p&gt;

&lt;p&gt;It builds a Ghost Tree for the active file and shows code structure like classes, methods, functions, fields, web structure, selectors, and &lt;a class="mentioned-user" href="https://dev.to/ghost"&gt;@ghost&lt;/a&gt; anchors.&lt;/p&gt;

&lt;p&gt;You can click a tree item to jump to the matching line.&lt;/p&gt;

&lt;p&gt;You can also use &lt;a class="mentioned-user" href="https://dev.to/ghost"&gt;@ghost&lt;/a&gt; annotations to keep notes, regions, and work markers next to the code they describe.&lt;/p&gt;

&lt;p&gt;The current Marketplace version supports TypeScript, TSX, JavaScript, JSX, C#, Java, C++, C, Go, Rust, PHP, Python, Ruby, Dart, Scala, Groovy, Solidity, Julia, Elixir, Objective-C, Lua, and SQL.&lt;/p&gt;

&lt;p&gt;It also supports web templates and styles like HTML, CSS, SCSS, Less, Vue, Svelte, and Astro, plus config and docs formats like JSON, YAML, TOML, XML, Markdown, Dockerfile, Makefile, and GraphQL.&lt;/p&gt;

&lt;p&gt;Support quality is not identical across every language and file type. Some languages have stronger symbol extraction than others, and some depend on the editor language server.&lt;/p&gt;

&lt;p&gt;But the core idea is the same:&lt;/p&gt;

&lt;p&gt;Open a file, see its structure, and keep intentional annotations close to the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Snippets
&lt;/h2&gt;

&lt;p&gt;GhostMap includes snippets so you do not have to type the annotation format manually.&lt;/p&gt;

&lt;p&gt;For named annotations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @ghost #name description:  | status: todo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For contextual annotations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @ghost description:  | status: todo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For ranges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @ghost #name start description:  | status: todo&lt;/span&gt;

&lt;span class="c1"&gt;// @ghost end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The syntax is intentionally plain text.&lt;/p&gt;

&lt;p&gt;I wanted the annotations to stay readable even without the extension installed.&lt;/p&gt;

&lt;p&gt;That was important to me.&lt;/p&gt;

&lt;p&gt;If a teammate opens the file without GhostMap, the comment should still make sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  What GhostMap is not
&lt;/h2&gt;

&lt;p&gt;GhostMap is not trying to replace your issue tracker.&lt;/p&gt;

&lt;p&gt;Some work belongs in GitHub Issues, Linear, Jira, or a project board. If something needs prioritization, assignment, discussion, sprint planning, or cross-team visibility, it probably belongs there.&lt;/p&gt;

&lt;p&gt;GhostMap is for context that is useful because it lives next to the code.&lt;/p&gt;

&lt;p&gt;It is also not a workspace-wide map yet.&lt;/p&gt;

&lt;p&gt;V1 maps the active file. Workspace-wide indexing is something I want to explore later, but I wanted the active-file experience to be useful first.&lt;/p&gt;

&lt;p&gt;It is not an AI tool either.&lt;/p&gt;

&lt;p&gt;That said, I think structured annotations can become useful when working with AI coding agents, because vague comments are bad context for both humans and tools.&lt;/p&gt;

&lt;p&gt;A plain TODO says almost nothing.&lt;/p&gt;

&lt;p&gt;A structured annotation gives the code a small amount of memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Privacy and trust
&lt;/h2&gt;

&lt;p&gt;GhostMap runs locally.&lt;/p&gt;

&lt;p&gt;The extension is designed so your source code does not get sent to GhostMap maintainers or GhostMap servers.&lt;/p&gt;

&lt;p&gt;That matters because code annotation tools have to earn trust.&lt;/p&gt;

&lt;p&gt;If a tool is reading your code structure, the default should be clear:&lt;/p&gt;

&lt;p&gt;Your project stays on your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current limitations
&lt;/h2&gt;

&lt;p&gt;This is still pre-1.0.&lt;/p&gt;

&lt;p&gt;Known limitations today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GhostMap maps the active file, not the whole workspace&lt;/li&gt;
&lt;li&gt;Block and JSDoc comments are not the main &lt;a class="mentioned-user" href="https://dev.to/ghost"&gt;@ghost&lt;/a&gt; syntax in V1&lt;/li&gt;
&lt;li&gt;Some language-specific symbol edge cases are still being cleaned up&lt;/li&gt;
&lt;li&gt;Support quality varies by language and file type&lt;/li&gt;
&lt;li&gt;GhostMap is source-available under a non-commercial license, not OSI open source&lt;/li&gt;
&lt;li&gt;Personal, educational, evaluation, testing, and other non-commercial use are allowed&lt;/li&gt;
&lt;li&gt;Company, business, production, revenue-generating, client, resale, white-label, marketplace-republish, and competing-product use require written authorization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am being upfront about this because developer tools only earn trust when the rough edges are visible.&lt;/p&gt;

&lt;p&gt;I would rather say what is missing now than pretend the MVP is more mature than it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built it this way
&lt;/h2&gt;

&lt;p&gt;I did not want another SaaS dashboard.&lt;/p&gt;

&lt;p&gt;I did not want another place where code context goes to die.&lt;/p&gt;

&lt;p&gt;The code already has the most important location context.&lt;/p&gt;

&lt;p&gt;The missing part is structure.&lt;/p&gt;

&lt;p&gt;A plain comment says:&lt;/p&gt;

&lt;p&gt;remember this&lt;/p&gt;

&lt;p&gt;A structured annotation says:&lt;/p&gt;

&lt;p&gt;remember this, here is what it is called, here is its state, here is why it matters, and here is where it lives&lt;/p&gt;

&lt;p&gt;That small difference makes old code easier to re-enter.&lt;/p&gt;

&lt;p&gt;It also makes TODO-style comments feel less disposable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;GhostMap is available on the VS Code Marketplace:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=Ghostmap.ghostmap" rel="noopener noreferrer"&gt;https://marketplace.visualstudio.com/items?itemName=Ghostmap.ghostmap&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Docs:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ghostmap-docs.vercel.app/" rel="noopener noreferrer"&gt;https://ghostmap-docs.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Product site:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ghostmap-liard.vercel.app/" rel="noopener noreferrer"&gt;https://ghostmap-liard.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you already use TODO Tree, Better Comments, VS Code Outline, or your own TODO convention, I would especially like feedback on one question:&lt;/p&gt;

&lt;p&gt;Would structured annotations fit your workflow, or should this stay closer to normal TODO comments?&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>architecture</category>
      <category>typescript</category>
      <category>vscode</category>
    </item>
  </channel>
</rss>
