<?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: Nishikanta Ray</title>
    <description>The latest articles on DEV Community by Nishikanta Ray (@nishikantaray).</description>
    <link>https://dev.to/nishikantaray</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%2F478296%2F4472af16-2478-4273-a8cd-42c39effe3c0.jpg</url>
      <title>DEV Community: Nishikanta Ray</title>
      <link>https://dev.to/nishikantaray</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nishikantaray"/>
    <language>en</language>
    <item>
      <title>What If Your Coding Agent Could Remember What It Learned Yesterday?</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Thu, 17 Sep 2026 16:28:47 +0000</pubDate>
      <link>https://dev.to/nishikantaray/what-if-your-coding-agent-could-remember-what-it-learned-yesterday-2okj</link>
      <guid>https://dev.to/nishikantaray/what-if-your-coding-agent-could-remember-what-it-learned-yesterday-2okj</guid>
      <description>&lt;p&gt;&lt;em&gt;I built Attic to help Claude Code and Codex CLI remember what they discover — and now you can save knowledge from your browser too.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;You ask your AI coding assistant to investigate a bug.&lt;/p&gt;

&lt;p&gt;It searches the repository. Reads five files. Follows a few imports. Runs some commands. Finally, it tells you:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Found it. The authentication check happens after the desktop sub-window is created."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Great. You fix the bug.&lt;/p&gt;

&lt;p&gt;A few days later, you start a new session.&lt;/p&gt;

&lt;p&gt;You ask the assistant to investigate another issue in the same area.&lt;/p&gt;

&lt;p&gt;It searches the same files.&lt;/p&gt;

&lt;p&gt;Reads the same imports.&lt;/p&gt;

&lt;p&gt;Runs the same commands.&lt;/p&gt;

&lt;p&gt;And eventually discovers the same thing you already knew.&lt;/p&gt;

&lt;p&gt;You just paid for the same investigation twice.&lt;/p&gt;

&lt;p&gt;Maybe three times.&lt;/p&gt;

&lt;p&gt;This is the problem I wanted to solve with &lt;strong&gt;Attic&lt;/strong&gt; — an open-source knowledge persistence tool for AI coding assistants.&lt;/p&gt;

&lt;p&gt;But the interesting part isn't simply saving notes.&lt;/p&gt;

&lt;p&gt;It's the design behind making those notes useful across sessions, after context compaction, and now even from your browser.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/NishikantaRay/Attic" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/Attic&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem: Your AI knows more than your codebase
&lt;/h2&gt;

&lt;p&gt;Let's start with a simple example.&lt;/p&gt;

&lt;p&gt;Imagine you're working on a JavaScript monorepo.&lt;/p&gt;

&lt;p&gt;You ask Claude Code:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why is the cloud package failing to load?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The assistant investigates and finds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// packages/cloud/index.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;cloudClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;cloudConfig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two default exports.&lt;/p&gt;

&lt;p&gt;The file throws a syntax error.&lt;/p&gt;

&lt;p&gt;The assistant explains the issue. You fix it.&lt;/p&gt;

&lt;p&gt;But where does that knowledge go?&lt;/p&gt;

&lt;p&gt;If you only keep the conversation, the discovery is trapped inside that session.&lt;/p&gt;

&lt;p&gt;If you start a new session, your assistant may have to rediscover the same problem.&lt;/p&gt;

&lt;p&gt;The codebase contains the bug fix, but it doesn't necessarily contain the &lt;em&gt;reasoning that helped you find it&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And reasoning is often what you need the next time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Another example: Documentation versus reality
&lt;/h3&gt;

&lt;p&gt;Suppose your project has a rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"All desktop sub-windows must wait for authentication before rendering."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But the actual implementation creates the window before the authentication gate finishes.&lt;/p&gt;

&lt;p&gt;Your assistant investigates and discovers the contradiction.&lt;/p&gt;

&lt;p&gt;That's valuable knowledge.&lt;/p&gt;

&lt;p&gt;Not just:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;There is a bug.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The desktop sub-window can be created before the authentication gate
completes, despite the documented requirement.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That tells the next investigation where to look.&lt;/p&gt;

&lt;p&gt;It also tells a teammate what assumption is unsafe.&lt;/p&gt;

&lt;p&gt;It explains &lt;em&gt;why&lt;/em&gt; the code behaves the way it does.&lt;/p&gt;

&lt;p&gt;This kind of knowledge is easy to lose.&lt;/p&gt;

&lt;p&gt;And it isn't limited to bugs.&lt;/p&gt;

&lt;p&gt;It includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architectural decisions.&lt;/li&gt;
&lt;li&gt;Repository conventions.&lt;/li&gt;
&lt;li&gt;Failed approaches.&lt;/li&gt;
&lt;li&gt;Important file locations.&lt;/li&gt;
&lt;li&gt;Authentication assumptions.&lt;/li&gt;
&lt;li&gt;Performance discoveries.&lt;/li&gt;
&lt;li&gt;Why a particular implementation exists.&lt;/li&gt;
&lt;li&gt;Things you should never repeat.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your codebase is a library of implementation.&lt;/p&gt;

&lt;p&gt;Your AI assistant's discoveries are the notes in the margins.&lt;/p&gt;

&lt;p&gt;The question is: &lt;strong&gt;Where do those notes live?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Meet Attic: A memory shelf for your coding agent
&lt;/h2&gt;

&lt;p&gt;Attic is an open-source tool designed to help AI coding assistants persist and reuse knowledge.&lt;/p&gt;

&lt;p&gt;It works with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code.&lt;/li&gt;
&lt;li&gt;Codex CLI.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Write what you learn to a file. Keep a small index in context. Retrieve the details when you need them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No need to put every discovery into the assistant's context forever.&lt;/p&gt;

&lt;p&gt;No need to rebuild the same understanding from scratch every session.&lt;/p&gt;

&lt;p&gt;And no need to turn your entire repository into a giant collection of instructions.&lt;/p&gt;

&lt;p&gt;Attic gives the agent a place to store useful discoveries.&lt;/p&gt;

&lt;p&gt;Think of it as a small knowledge library inside your project.&lt;/p&gt;




&lt;h2&gt;
  
  
  The library analogy that makes Attic click
&lt;/h2&gt;

&lt;p&gt;Imagine you have a library.&lt;/p&gt;

&lt;p&gt;You have 200 books.&lt;/p&gt;

&lt;p&gt;You don't carry all 200 books around with you.&lt;/p&gt;

&lt;p&gt;You carry a catalogue.&lt;/p&gt;

&lt;p&gt;The catalogue tells you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which books exist.&lt;/li&gt;
&lt;li&gt;Where they are.&lt;/li&gt;
&lt;li&gt;Which ones are important.&lt;/li&gt;
&lt;li&gt;What each book is about.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you need a particular book, you look it up.&lt;/p&gt;

&lt;p&gt;Attic follows the same idea.&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;.attic/&lt;/code&gt; folder is the library
&lt;/h3&gt;

&lt;p&gt;A typical Attic knowledge folder contains Markdown files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.attic/
├── INDEX.md
├── DECISIONS.md
└── items/
    ├── f1.md
    ├── f2.md
    ├── f3.md
    └── ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact files and commands depend on the installed version, but the core concept is consistent:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The knowledge lives on disk. The index helps the agent find it.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;INDEX.md&lt;/code&gt; is the catalogue card
&lt;/h3&gt;

&lt;p&gt;The index is not supposed to contain every detail.&lt;/p&gt;

&lt;p&gt;It's a compact representation of what matters.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Attic Index&lt;/span&gt;

&lt;span class="gu"&gt;## Pinned&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; f3: Authentication must complete before
  desktop sub-windows are created.

&lt;span class="gu"&gt;## Recent findings&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; f12: Cloud package has duplicate default exports.
&lt;span class="p"&gt;-&lt;/span&gt; f11: API client is initialized in the shared module.
&lt;span class="p"&gt;-&lt;/span&gt; f10: The docs and implementation disagree
  about the authentication lifecycle.

&lt;span class="gu"&gt;## Older items&lt;/span&gt;

95 older items not shown.
Use /attic-recall &lt;span class="nt"&gt;&amp;lt;topic&amp;gt;&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an illustrative example of the idea, not a claim about the exact generated format.&lt;/p&gt;

&lt;p&gt;The agent can see the important information without loading the entire knowledge base into every prompt.&lt;/p&gt;

&lt;p&gt;When more detail is needed, it can recall the relevant item.&lt;/p&gt;

&lt;p&gt;That's the distinction:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The index is the catalogue. The Markdown files are the books.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why not just put everything in the system prompt?
&lt;/h2&gt;

&lt;p&gt;This is a reasonable question.&lt;/p&gt;

&lt;p&gt;If the assistant needs the information, why not inject all of it?&lt;/p&gt;

&lt;p&gt;Because context is limited.&lt;/p&gt;

&lt;p&gt;And even when you have enough context, more context isn't automatically better.&lt;/p&gt;

&lt;p&gt;Imagine an assistant working on a project with 200 findings.&lt;/p&gt;

&lt;p&gt;If every finding is included in every session, the prompt becomes filled with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Old discoveries.&lt;/li&gt;
&lt;li&gt;Superseded decisions.&lt;/li&gt;
&lt;li&gt;Unrelated bugs.&lt;/li&gt;
&lt;li&gt;Details from previous tasks.&lt;/li&gt;
&lt;li&gt;Information that may not matter to the current question.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent now has to spend attention deciding what matters.&lt;/p&gt;

&lt;p&gt;Attic takes a different approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep the index small
&lt;/h3&gt;

&lt;p&gt;Attic's runtime includes logic for loading the index and keeping its injected representation compact.&lt;/p&gt;

&lt;p&gt;The repository's design notes describe an index that prioritizes pinned findings, recent items, and compact summaries for older knowledge.&lt;/p&gt;

&lt;p&gt;The important idea is not a magic token number.&lt;/p&gt;

&lt;p&gt;It's this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't force the assistant to carry the entire library when a catalogue will do.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Retrieve the details when needed
&lt;/h3&gt;

&lt;p&gt;Suppose the agent is investigating authentication.&lt;/p&gt;

&lt;p&gt;It doesn't need to read every database discovery, UI decision, and deployment note.&lt;/p&gt;

&lt;p&gt;It needs the authentication-related knowledge.&lt;/p&gt;

&lt;p&gt;That's where recall becomes useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  The four commands: Put knowledge in, get knowledge out
&lt;/h2&gt;

&lt;p&gt;Attic's commands are organized around a simple workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;stash&lt;/code&gt; — save what you learned
&lt;/h3&gt;

&lt;p&gt;After an investigation, save the discovery.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/attic-stash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact command options depend on the installed version.&lt;/p&gt;

&lt;p&gt;Conceptually, you are turning an ephemeral chat discovery into a persistent Markdown item.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;"I think the auth gate is somewhere in the desktop code."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You save:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Authentication gate and desktop sub-windows&lt;/span&gt;

The desktop sub-window creation path can run
before the authentication gate completes.

When investigating window lifecycle bugs,
check the auth gate before the window creation path.

Tags:
&lt;span class="p"&gt;-&lt;/span&gt; authentication
&lt;span class="p"&gt;-&lt;/span&gt; desktop
&lt;span class="p"&gt;-&lt;/span&gt; lifecycle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that discovery has a home.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;code&gt;recall&lt;/code&gt; — find what you already know
&lt;/h3&gt;

&lt;p&gt;Later, you can ask Attic to retrieve relevant knowledge.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/attic-recall authentication
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The assistant can use the stored findings instead of starting from zero.&lt;/p&gt;

&lt;p&gt;This is particularly useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A new session starts.&lt;/li&gt;
&lt;li&gt;You run &lt;code&gt;/compact&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A teammate clones the project.&lt;/li&gt;
&lt;li&gt;You return to an old feature.&lt;/li&gt;
&lt;li&gt;You forgot why a particular design exists.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;code&gt;index&lt;/code&gt; — inspect the catalogue
&lt;/h3&gt;

&lt;p&gt;The index helps you understand what the agent can see.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/attic-index
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea is to inspect the compact catalogue rather than opening every item.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;code&gt;pin&lt;/code&gt;, &lt;code&gt;prune&lt;/code&gt;, and &lt;code&gt;archive&lt;/code&gt; — manage the shelf
&lt;/h3&gt;

&lt;p&gt;Not every discovery deserves permanent prominence.&lt;/p&gt;

&lt;p&gt;Some knowledge is important forever.&lt;/p&gt;

&lt;p&gt;Some is useful for a week.&lt;/p&gt;

&lt;p&gt;Some becomes obsolete after a refactor.&lt;/p&gt;

&lt;p&gt;Attic provides commands for managing that lifecycle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/attic-pin
/attic-prune
/attic-archive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact syntax depends on the version and installed commands.&lt;/p&gt;

&lt;p&gt;The important design decision is that knowledge needs management.&lt;/p&gt;

&lt;p&gt;A memory system that only writes and never cleans up eventually becomes another source of noise.&lt;/p&gt;




&lt;h2&gt;
  
  
  The part I find most interesting: The index is not the memory
&lt;/h2&gt;

&lt;p&gt;This is the design detail worth understanding.&lt;/p&gt;

&lt;p&gt;A common approach to agent memory is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Store a large amount of information and inject it into the next prompt.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Attic separates storage from injection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Storage
&lt;/h3&gt;

&lt;p&gt;The detailed findings live in Markdown files.&lt;/p&gt;

&lt;p&gt;They can contain context, explanations, file references, and reasoning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Injection
&lt;/h3&gt;

&lt;p&gt;The assistant receives a compact index.&lt;/p&gt;

&lt;p&gt;The index tells it what exists and how to find it.&lt;/p&gt;

&lt;p&gt;This separation gives you a useful property:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can have a large knowledge base without making every prompt equally large.&lt;/strong&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Knowledge on disk:

200 findings
│
├── Pinned findings
├── Recent findings
└── Older findings
    └── Available through recall
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The assistant doesn't need all 200 findings in context.&lt;/p&gt;

&lt;p&gt;It needs enough information to navigate the collection.&lt;/p&gt;

&lt;p&gt;This is a familiar pattern in software engineering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database versus index.&lt;/li&gt;
&lt;li&gt;Filesystem versus directory listing.&lt;/li&gt;
&lt;li&gt;Library versus catalogue.&lt;/li&gt;
&lt;li&gt;Search engine versus document store.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Attic applies that idea to coding-agent memory.&lt;/p&gt;




&lt;h2&gt;
  
  
  What happens when you use &lt;code&gt;/compact&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;This is one of the reasons persistent memory matters.&lt;/p&gt;

&lt;p&gt;Imagine a long coding session.&lt;/p&gt;

&lt;p&gt;At the beginning, you ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Understand the authentication flow."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent investigates.&lt;/p&gt;

&lt;p&gt;It discovers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The auth gate lives in one module.&lt;/li&gt;
&lt;li&gt;The desktop window is created in another.&lt;/li&gt;
&lt;li&gt;The window creation can happen before auth finishes.&lt;/li&gt;
&lt;li&gt;The documentation assumes the opposite order.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You fix the problem.&lt;/p&gt;

&lt;p&gt;Then the conversation becomes huge.&lt;/p&gt;

&lt;p&gt;You use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/compact
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The context is reduced.&lt;/p&gt;

&lt;p&gt;The agent may no longer have every detail from the earlier investigation.&lt;/p&gt;

&lt;p&gt;If the key discovery existed only in the conversation, it can be difficult to recover.&lt;/p&gt;

&lt;p&gt;But if you saved it to Attic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.attic/items/f3.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The knowledge remains on disk.&lt;/p&gt;

&lt;p&gt;A later session can recall it.&lt;/p&gt;

&lt;p&gt;The discovery has survived the conversation.&lt;/p&gt;

&lt;p&gt;This is the central promise of persistent agent memory:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your knowledge should outlive the context window.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  The browser extension: Knowledge doesn't only happen in your terminal
&lt;/h1&gt;

&lt;p&gt;Now let's talk about the feature that makes Attic particularly interesting.&lt;/p&gt;

&lt;p&gt;Most coding-agent memory tools focus on what happens inside the terminal.&lt;/p&gt;

&lt;p&gt;But developers learn things everywhere.&lt;/p&gt;

&lt;p&gt;You might discover a useful fact while reading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A GitHub issue.&lt;/li&gt;
&lt;li&gt;A pull request.&lt;/li&gt;
&lt;li&gt;A Stack Overflow answer.&lt;/li&gt;
&lt;li&gt;A technical blog.&lt;/li&gt;
&lt;li&gt;A framework documentation page.&lt;/li&gt;
&lt;li&gt;A browser tab containing an important explanation.&lt;/li&gt;
&lt;li&gt;A discussion about a design decision.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You might think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This is useful. I should save it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then you close the tab.&lt;/p&gt;

&lt;p&gt;Or forget.&lt;/p&gt;

&lt;p&gt;Or leave it in your browser history.&lt;/p&gt;

&lt;p&gt;The information never makes it into your project's knowledge base.&lt;/p&gt;

&lt;p&gt;Attic's browser companion is designed to close that gap.&lt;/p&gt;

&lt;p&gt;Instead of only remembering what the coding agent discovers, you can save useful knowledge from the browser into the same Attic shelf.&lt;/p&gt;

&lt;p&gt;That is a powerful extension of the original idea.&lt;/p&gt;




&lt;h2&gt;
  
  
  Browser to project memory
&lt;/h2&gt;

&lt;p&gt;Let's say you're investigating a bug in a Node.js application.&lt;/p&gt;

&lt;p&gt;You open a GitHub issue discussing a subtle behavior in a dependency.&lt;/p&gt;

&lt;p&gt;The issue contains the explanation you need.&lt;/p&gt;

&lt;p&gt;You don't want to copy the entire page into your project.&lt;/p&gt;

&lt;p&gt;You want to save the useful discovery.&lt;/p&gt;

&lt;p&gt;The workflow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Read useful information in browser
          │
          ▼
       Clip it
          │
          ▼
  Save to Attic knowledge
          │
          ▼
  Recall it in a future session
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser becomes another input into your project memory.&lt;/p&gt;

&lt;p&gt;This is important because developers don't learn only by asking an AI agent questions.&lt;/p&gt;

&lt;p&gt;They learn by reading.&lt;/p&gt;

&lt;p&gt;And a lot of that reading happens outside the terminal.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is a clip?
&lt;/h2&gt;

&lt;p&gt;A clip is a way to capture useful browser content and save it as a knowledge item.&lt;/p&gt;

&lt;p&gt;Imagine reading this on a documentation page:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The authentication callback must complete before the desktop window is created."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of copying the entire article into a notes app, you can clip the useful content into Attic.&lt;/p&gt;

&lt;p&gt;The saved item might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Authentication callback lifecycle&lt;/span&gt;

Source: Browser research

The authentication callback must complete
before the desktop window is created.

This matters because creating the window
too early can bypass the expected auth gate.

Tags:
&lt;span class="p"&gt;-&lt;/span&gt; authentication
&lt;span class="p"&gt;-&lt;/span&gt; desktop
&lt;span class="p"&gt;-&lt;/span&gt; lifecycle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your browser research becomes part of the same knowledge collection used by your coding agent.&lt;/p&gt;

&lt;p&gt;The exact clip UI and available options depend on the installed extension version.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why reuse the CLI writer instead of building a second memory system?
&lt;/h2&gt;

&lt;p&gt;This is one of the most important design calls in Attic's browser companion.&lt;/p&gt;

&lt;p&gt;A tempting approach would be to build a separate browser storage system.&lt;/p&gt;

&lt;p&gt;Something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser extension
       │
       ▼
Browser database
       │
       ▼
Browser-only notes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the CLI would have its own memory system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CLI
 │
 ▼
.attic/
 │
 ▼
CLI-only notes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have two systems.&lt;/p&gt;

&lt;p&gt;Two storage formats.&lt;/p&gt;

&lt;p&gt;Two sets of rules.&lt;/p&gt;

&lt;p&gt;Two places to search.&lt;/p&gt;

&lt;p&gt;Two systems to maintain.&lt;/p&gt;

&lt;p&gt;Attic takes a different approach.&lt;/p&gt;

&lt;p&gt;The browser companion reuses the CLI writer.&lt;/p&gt;

&lt;p&gt;The repository's design notes explicitly call out that the companion uses the existing CLI writer rather than reimplementing it.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 ┌────────────────────┐
                 │  Browser extension │
                 └─────────┬──────────┘
                           │
                           ▼
                 ┌────────────────────┐
                 │   CLI writer       │
                 └─────────┬──────────┘
                           │
                           ▼
                      .attic/
                           │
                 ┌─────────┴──────────┐
                 ▼                    ▼
             INDEX.md             items/*.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a classic software engineering principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reuse the existing source of truth instead of creating a second implementation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The CLI already knows how to write Attic items.&lt;/p&gt;

&lt;p&gt;The browser companion should not need to invent a different way to do the same job.&lt;/p&gt;

&lt;p&gt;That keeps the storage model consistent.&lt;/p&gt;

&lt;p&gt;It also means the knowledge saved from your browser can be used by the CLI.&lt;/p&gt;

&lt;p&gt;And knowledge saved from the CLI can be found in the same collection.&lt;/p&gt;

&lt;p&gt;One shelf.&lt;/p&gt;

&lt;p&gt;Multiple ways to put books on it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The subtle distinction: Edit is not stash
&lt;/h2&gt;

&lt;p&gt;This is another design decision worth talking about.&lt;/p&gt;

&lt;p&gt;At first glance, these two actions might seem similar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stash
&lt;/h3&gt;

&lt;p&gt;You discover something new.&lt;/p&gt;

&lt;p&gt;You want to add it to the knowledge base.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New discovery → Add a knowledge item
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Edit
&lt;/h3&gt;

&lt;p&gt;You already have a knowledge item.&lt;/p&gt;

&lt;p&gt;You want to correct or update it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Existing item → Replace its content
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are not the same operation.&lt;/p&gt;

&lt;p&gt;Suppose you have this finding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Authentication lifecycle&lt;/span&gt;

The desktop window is created before
the authentication callback completes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Later, you investigate more deeply and discover that the bug has been fixed.&lt;/p&gt;

&lt;p&gt;You edit the existing item:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Authentication lifecycle&lt;/span&gt;

The desktop window now waits for the
authentication callback to complete.

The previous behavior was caused by
the window creation path running too early.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have updated the knowledge.&lt;/p&gt;

&lt;p&gt;You haven't discovered a second, unrelated fact.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why appending everything is a problem
&lt;/h3&gt;

&lt;p&gt;If editing simply appended another copy, you could end up with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Authentication lifecycle&lt;/span&gt;

The desktop window is created before auth.
&lt;span class="p"&gt;
---
&lt;/span&gt;
&lt;span class="gh"&gt;# Authentication lifecycle&lt;/span&gt;

The desktop window waits for auth.
&lt;span class="p"&gt;
---
&lt;/span&gt;
&lt;span class="gh"&gt;# Authentication lifecycle&lt;/span&gt;

The previous behavior was caused by...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the agent has to reconcile multiple versions.&lt;/p&gt;

&lt;p&gt;That's noise.&lt;/p&gt;

&lt;p&gt;The repository's design notes explicitly distinguish editing from stashing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Editing replaces; stashing appends.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a small detail, but it reflects a larger principle:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memory needs both creation and correction.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A knowledge system that only adds information eventually becomes cluttered with stale information.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why there is no delete endpoint
&lt;/h2&gt;

&lt;p&gt;This might sound strange.&lt;/p&gt;

&lt;p&gt;If a knowledge item is wrong, why not just delete it?&lt;/p&gt;

&lt;p&gt;The design notes for Attic's browser companion call out that there is no delete endpoint.&lt;/p&gt;

&lt;p&gt;Instead, the system provides management operations such as archive and prune.&lt;/p&gt;

&lt;p&gt;There is a reason to be careful here.&lt;/p&gt;

&lt;p&gt;Deleting knowledge can be destructive.&lt;/p&gt;

&lt;p&gt;Imagine an agent saves an important architectural decision.&lt;/p&gt;

&lt;p&gt;A browser clip accidentally overwrites it.&lt;/p&gt;

&lt;p&gt;Or a user removes an item because it looks old.&lt;/p&gt;

&lt;p&gt;The information may be gone before anyone realizes it was useful.&lt;/p&gt;

&lt;p&gt;A safer approach is to separate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Editing an existing item.&lt;/li&gt;
&lt;li&gt;Archiving an item.&lt;/li&gt;
&lt;li&gt;Pruning stale knowledge.&lt;/li&gt;
&lt;li&gt;Permanently removing data, if supported through an intentional local workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a design choice, not a universal rule.&lt;/p&gt;

&lt;p&gt;Different tools may reasonably choose different deletion models.&lt;/p&gt;

&lt;p&gt;But the principle is worth considering:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Memory should be managed deliberately, not casually destroyed.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  The browser companion is also a security boundary
&lt;/h1&gt;

&lt;p&gt;The moment a browser extension can write to your project files, security becomes important.&lt;/p&gt;

&lt;p&gt;A browser extension is not the same as a trusted terminal command.&lt;/p&gt;

&lt;p&gt;It runs in a different environment.&lt;/p&gt;

&lt;p&gt;It may interact with content from arbitrary websites.&lt;/p&gt;

&lt;p&gt;It needs a way to communicate with the local Attic server.&lt;/p&gt;

&lt;p&gt;That means the design has to answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which origins can connect?&lt;/li&gt;
&lt;li&gt;Which requests are allowed?&lt;/li&gt;
&lt;li&gt;How is the local service authenticated?&lt;/li&gt;
&lt;li&gt;Where can it write?&lt;/li&gt;
&lt;li&gt;What happens when a user clips sensitive information?&lt;/li&gt;
&lt;li&gt;Can arbitrary websites cause files to be written?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Attic's design notes identify several of these concerns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loopback communication.&lt;/li&gt;
&lt;li&gt;A token.&lt;/li&gt;
&lt;li&gt;A root allowlist.&lt;/li&gt;
&lt;li&gt;Origin checks.&lt;/li&gt;
&lt;li&gt;A credential scan for clips.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are important because a browser-to-local-file bridge should not behave like an unrestricted file-writing API.&lt;/p&gt;




&lt;h2&gt;
  
  
  Loopback: Keep communication local
&lt;/h2&gt;

&lt;p&gt;The companion communicates with a local server.&lt;/p&gt;

&lt;p&gt;The goal is to keep the interaction on the developer's machine rather than sending knowledge to a remote cloud service.&lt;/p&gt;

&lt;p&gt;The repository's design notes identify loopback communication as part of the implementation.&lt;/p&gt;

&lt;p&gt;This is aligned with the project's broader local-first approach.&lt;/p&gt;

&lt;p&gt;The knowledge is intended to live in the project's &lt;code&gt;.attic/&lt;/code&gt; directory.&lt;/p&gt;




&lt;h2&gt;
  
  
  Token authentication
&lt;/h2&gt;

&lt;p&gt;A local service still needs protection.&lt;/p&gt;

&lt;p&gt;Just because something runs on &lt;code&gt;localhost&lt;/code&gt; doesn't mean every request should be trusted.&lt;/p&gt;

&lt;p&gt;Attic's browser server uses a token as part of its request validation.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser extension
       │
       │ request + token
       ▼
Local Attic server
       │
       ▼
Validate request
       │
       ▼
Write knowledge item
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact request format is an implementation detail.&lt;/p&gt;

&lt;p&gt;The important point is that the server isn't designed as an unauthenticated arbitrary file-writing endpoint.&lt;/p&gt;




&lt;h2&gt;
  
  
  Root allowlist: Where can it write?
&lt;/h2&gt;

&lt;p&gt;This is another useful security concept.&lt;/p&gt;

&lt;p&gt;Suppose the browser companion could tell the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write this content to:

/Users/me/anything/on/my/computer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That would be dangerous.&lt;/p&gt;

&lt;p&gt;A project memory tool should not be allowed to write to arbitrary locations.&lt;/p&gt;

&lt;p&gt;Attic's design notes identify a root allowlist in the server.&lt;/p&gt;

&lt;p&gt;The intended principle is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Restrict file writes to approved project roots.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That limits the scope of what the companion can modify.&lt;/p&gt;




&lt;h2&gt;
  
  
  Credential scanning: Don't stash secrets
&lt;/h2&gt;

&lt;p&gt;This is particularly important for browser clipping.&lt;/p&gt;

&lt;p&gt;Imagine you are reading a page containing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API_KEY=super-secret-value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You click "Clip."&lt;/p&gt;

&lt;p&gt;Should that secret be saved to your project's memory?&lt;/p&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;Attic's design notes identify a credential scan that refuses a clip containing a credential.&lt;/p&gt;

&lt;p&gt;This is a practical safeguard.&lt;/p&gt;

&lt;p&gt;But it doesn't mean every secret will be detected.&lt;/p&gt;

&lt;p&gt;You should still avoid clipping:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API keys.&lt;/li&gt;
&lt;li&gt;Passwords.&lt;/li&gt;
&lt;li&gt;Session tokens.&lt;/li&gt;
&lt;li&gt;Private access tokens.&lt;/li&gt;
&lt;li&gt;Credentials.&lt;/li&gt;
&lt;li&gt;Personal secrets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A browser extension that can save content needs to treat sensitive information as a first-class concern.&lt;/p&gt;




&lt;h1&gt;
  
  
  The local-first philosophy
&lt;/h1&gt;

&lt;p&gt;One of the things I like about Attic is that its design stays close to ordinary developer tools.&lt;/p&gt;

&lt;p&gt;The knowledge is stored as Markdown.&lt;/p&gt;

&lt;p&gt;The project can inspect it.&lt;/p&gt;

&lt;p&gt;The files can be version-controlled.&lt;/p&gt;

&lt;p&gt;And the runtime is designed around local filesystem operations rather than a cloud memory service.&lt;/p&gt;

&lt;p&gt;The repository describes the runtime as using Node.js &lt;code&gt;fs&lt;/code&gt; and &lt;code&gt;path&lt;/code&gt;, with no network calls in the plugin runtime.&lt;/p&gt;

&lt;p&gt;That gives the project a straightforward mental model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your project
    │
    ├── Source code
    ├── Documentation
    ├── Tests
    └── .attic/
         ├── INDEX.md
         ├── DECISIONS.md
         └── items/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your agent's memory is another part of the repository.&lt;/p&gt;

&lt;p&gt;Not a mysterious remote database.&lt;/p&gt;

&lt;p&gt;Not a separate SaaS dashboard.&lt;/p&gt;

&lt;p&gt;Not a service you need to query over the internet every time the agent needs to remember something.&lt;/p&gt;




&lt;h2&gt;
  
  
  But should you commit &lt;code&gt;.attic/&lt;/code&gt; to Git?
&lt;/h2&gt;

&lt;p&gt;This is an important practical question.&lt;/p&gt;

&lt;p&gt;If the knowledge lives in your project, it can potentially be shared with the team.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer A
    │
    ▼
Saves an architectural discovery
    │
    ▼
Commits .attic/
    │
    ▼
Developer B pulls the changes
    │
    ▼
Agent can recall the discovery
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repository notes describe &lt;code&gt;.attic/&lt;/code&gt; as surviving a Git clone only if it is committed rather than ignored.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;If you want shared project memory, you need to decide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Should the knowledge be committed?&lt;/li&gt;
&lt;li&gt;Should some findings remain local?&lt;/li&gt;
&lt;li&gt;How should stale findings be managed?&lt;/li&gt;
&lt;li&gt;How should conflicting changes be merged?&lt;/li&gt;
&lt;li&gt;What information is appropriate for the whole team?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a team project, knowledge management becomes part of the repository workflow.&lt;/p&gt;




&lt;h1&gt;
  
  
  A complete example: From bug investigation to reusable knowledge
&lt;/h1&gt;

&lt;p&gt;Let's walk through a realistic workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Start a new investigation
&lt;/h2&gt;

&lt;p&gt;You ask Claude Code:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Investigate why the desktop sub-window sometimes appears before authentication."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent searches the codebase.&lt;/p&gt;

&lt;p&gt;It discovers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;packages/desktop/window.js
packages/auth/gate.js
packages/desktop/bootstrap.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It traces the execution path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: The agent finds the root cause
&lt;/h2&gt;

&lt;p&gt;The agent explains:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The window creation call happens before the authentication callback completes."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You fix the issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Save the discovery
&lt;/h2&gt;

&lt;p&gt;You stash the important knowledge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/attic-stash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The saved item contains something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Desktop window authentication lifecycle&lt;/span&gt;

The desktop window creation path can run
before the authentication callback completes.

When investigating window lifecycle issues,
check the auth gate before window creation.

Relevant areas:
&lt;span class="p"&gt;-&lt;/span&gt; packages/desktop/window.js
&lt;span class="p"&gt;-&lt;/span&gt; packages/auth/gate.js
&lt;span class="p"&gt;-&lt;/span&gt; packages/desktop/bootstrap.js

Tags:
&lt;span class="p"&gt;-&lt;/span&gt; desktop
&lt;span class="p"&gt;-&lt;/span&gt; authentication
&lt;span class="p"&gt;-&lt;/span&gt; lifecycle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Start a new session
&lt;/h2&gt;

&lt;p&gt;A few days later:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why is the desktop window lifecycle failing?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent can inspect the Attic index and recall relevant knowledge.&lt;/p&gt;

&lt;p&gt;Instead of immediately rediscovering the entire execution path, it has a useful starting point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Update the knowledge after the fix
&lt;/h2&gt;

&lt;p&gt;You discover a more precise explanation.&lt;/p&gt;

&lt;p&gt;You edit the existing item.&lt;/p&gt;

&lt;p&gt;Now the knowledge stays current.&lt;/p&gt;

&lt;p&gt;This is the lifecycle that matters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Investigate
    ↓
Discover
    ↓
Stash
    ↓
Recall
    ↓
Update
    ↓
Reuse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's not magic.&lt;/p&gt;

&lt;p&gt;It's a disciplined way to make discoveries persistent.&lt;/p&gt;




&lt;h1&gt;
  
  
  What Attic does not try to do
&lt;/h1&gt;

&lt;p&gt;It's worth being clear about the scope.&lt;/p&gt;

&lt;p&gt;Attic is not a replacement for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your source code.&lt;/li&gt;
&lt;li&gt;Your Git history.&lt;/li&gt;
&lt;li&gt;Your issue tracker.&lt;/li&gt;
&lt;li&gt;Your documentation.&lt;/li&gt;
&lt;li&gt;Your test suite.&lt;/li&gt;
&lt;li&gt;Your own engineering judgment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's a knowledge persistence layer for coding-agent workflows.&lt;/p&gt;

&lt;p&gt;It helps preserve discoveries and make them available again.&lt;/p&gt;

&lt;p&gt;It doesn't guarantee that the assistant will always recall the right item.&lt;/p&gt;

&lt;p&gt;It doesn't guarantee that every saved finding is correct.&lt;/p&gt;

&lt;p&gt;It doesn't eliminate the need to verify facts.&lt;/p&gt;

&lt;p&gt;And it doesn't mean the agent should blindly trust old notes.&lt;/p&gt;

&lt;p&gt;A stale memory can be just as dangerous as no memory.&lt;/p&gt;

&lt;p&gt;That's why editing, pruning, and archive workflows matter.&lt;/p&gt;




&lt;h1&gt;
  
  
  The bigger idea: Agents need a knowledge lifecycle
&lt;/h1&gt;

&lt;p&gt;When people talk about AI coding assistants, they often focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better models.&lt;/li&gt;
&lt;li&gt;Larger context windows.&lt;/li&gt;
&lt;li&gt;Faster inference.&lt;/li&gt;
&lt;li&gt;More tool calls.&lt;/li&gt;
&lt;li&gt;Better code generation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those things matter.&lt;/p&gt;

&lt;p&gt;But there is another problem:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens to the useful knowledge after the task ends?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A coding agent might discover:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The API client is initialized in a shared module.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That can be valuable.&lt;/p&gt;

&lt;p&gt;But if it exists only in the chat, the next session may have to rediscover it.&lt;/p&gt;

&lt;p&gt;The same is true for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why a dependency was chosen.&lt;/li&gt;
&lt;li&gt;Why a workaround exists.&lt;/li&gt;
&lt;li&gt;Why a particular file is important.&lt;/li&gt;
&lt;li&gt;Which approach failed.&lt;/li&gt;
&lt;li&gt;What assumption caused a bug.&lt;/li&gt;
&lt;li&gt;What the team should avoid repeating.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are not necessarily code changes.&lt;/p&gt;

&lt;p&gt;They are discoveries about the codebase.&lt;/p&gt;

&lt;p&gt;And they deserve a place to live.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why browser memory is a natural next step
&lt;/h1&gt;

&lt;p&gt;The browser extension expands the idea beyond terminal-based discovery.&lt;/p&gt;

&lt;p&gt;Developers constantly learn from external information.&lt;/p&gt;

&lt;p&gt;They read a blog post.&lt;/p&gt;

&lt;p&gt;Find a GitHub issue.&lt;/p&gt;

&lt;p&gt;Understand a framework quirk.&lt;/p&gt;

&lt;p&gt;Discover a workaround.&lt;/p&gt;

&lt;p&gt;Read a discussion about a bug.&lt;/p&gt;

&lt;p&gt;That knowledge is useful even if the AI agent didn't discover it itself.&lt;/p&gt;

&lt;p&gt;The browser companion makes it possible to capture useful information and bring it into the same local knowledge system.&lt;/p&gt;

&lt;p&gt;This creates a broader workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             ┌───────────────┐
             │   Terminal    │
             │ Claude/Codex  │
             └───────┬───────┘
                     │
                     ▼
              ┌────────────┐
              │   Attic    │
              │  Knowledge │
              └────────────┘
                     ▲
                     │
             ┌───────┴───────┐
             │               │
      ┌──────┴──────┐ ┌──────┴──────┐
      │ CLI stash   │ │ Browser     │
      │             │ │ clip        │
      └─────────────┘ └─────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One knowledge shelf.&lt;/p&gt;

&lt;p&gt;Different ways to add information.&lt;/p&gt;

&lt;p&gt;The same place to recall it.&lt;/p&gt;




&lt;h1&gt;
  
  
  Getting started
&lt;/h1&gt;

&lt;p&gt;You can explore Attic here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/NishikantaRay/Attic" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/Attic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project is designed for Claude Code and Codex CLI.&lt;/p&gt;

&lt;p&gt;A typical workflow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Install Attic
2. Initialize it in your project
3. Investigate a problem
4. Stash useful discoveries
5. Recall them in later sessions
6. Manage the knowledge as it evolves
7. Use the browser companion to capture useful research
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the exact installation and usage commands, follow the repository's current README and release documentation.&lt;/p&gt;




&lt;h1&gt;
  
  
  Final thoughts
&lt;/h1&gt;

&lt;p&gt;I think the most interesting thing about AI coding assistants isn't just how much code they can write.&lt;/p&gt;

&lt;p&gt;It's how much they can discover.&lt;/p&gt;

&lt;p&gt;An agent can investigate a codebase for ten minutes and uncover something that would take a developer much longer to understand.&lt;/p&gt;

&lt;p&gt;But if that discovery disappears when the session ends, you lose part of the value.&lt;/p&gt;

&lt;p&gt;Attic is built around a simple idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't make your AI coding assistant rediscover what it already learned.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Write the discovery to a file.&lt;/p&gt;

&lt;p&gt;Keep a compact index.&lt;/p&gt;

&lt;p&gt;Recall the details when needed.&lt;/p&gt;

&lt;p&gt;And now, when useful knowledge comes from your browser, clip it into the same shelf.&lt;/p&gt;

&lt;p&gt;The future of AI coding assistants may not just be about giving agents more context.&lt;/p&gt;

&lt;p&gt;It may also be about giving them better ways to remember.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try Attic
&lt;/h2&gt;

&lt;p&gt;If you use Claude Code or Codex CLI and you've ever thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I know we already solved this. Why is the agent investigating it again?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Attic is worth exploring.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/NishikantaRay/Attic" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/Attic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you try it, I'd be interested to hear how you manage your agent's knowledge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What would you want your coding assistant to remember permanently?&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Tags
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ai #claudecode #codex #opensource #developer-tools #codingagents #artificialintelligence #productivity
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>tooling</category>
      <category>programming</category>
    </item>
    <item>
      <title>AI Skills Are Not Just Prompts: A Practical Architecture for Building, Evaluating, Shipping, and Maintaining Agent Skills</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Thu, 03 Sep 2026 19:13:59 +0000</pubDate>
      <link>https://dev.to/nishikantaray/ai-skills-are-not-just-prompts-a-practical-architecture-for-building-evaluating-shipping-and-540h</link>
      <guid>https://dev.to/nishikantaray/ai-skills-are-not-just-prompts-a-practical-architecture-for-building-evaluating-shipping-and-540h</guid>
      <description>&lt;p&gt;The current generation of AI coding agents makes it surprisingly easy to create a "skill."&lt;/p&gt;

&lt;p&gt;Write a Markdown file. Add instructions. Give it a name. Put it inside &lt;code&gt;.claude/skills/&lt;/code&gt;. Done.&lt;/p&gt;

&lt;p&gt;Except it isn't.&lt;/p&gt;

&lt;p&gt;As soon as you build more than a handful of skills, a different set of problems appears:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which skill should activate?&lt;/li&gt;
&lt;li&gt;Why did two skills activate at the same time?&lt;/li&gt;
&lt;li&gt;Why did the agent ignore an important instruction?&lt;/li&gt;
&lt;li&gt;What belongs in a skill versus a rule, agent, hook, or script?&lt;/li&gt;
&lt;li&gt;How much context should the skill load?&lt;/li&gt;
&lt;li&gt;How do you test whether the skill actually works?&lt;/li&gt;
&lt;li&gt;What happens when the underlying framework changes?&lt;/li&gt;
&lt;li&gt;How do you distribute skills?&lt;/li&gt;
&lt;li&gt;How do you retire obsolete skills?&lt;/li&gt;
&lt;li&gt;How do you prevent dozens of skills from becoming an unmaintainable mess?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At that point, &lt;strong&gt;AI skills stop looking like prompts and start looking like software systems&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A production-grade AI skill is not merely a Markdown prompt. It is a versioned, testable, routable, enforceable software component with a defined lifecycle.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  1. The Skill Lifecycle
&lt;/h2&gt;

&lt;p&gt;A useful way to understand an AI skill is to look at its entire lifecycle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Runtime
   ↓
Scope / Fit
   ↓
Triggers
   ↓
Architecture
   ↓
Anatomy
   ↓
Content
   ↓
Enforcement
   ↓
Measurement
   ↓
Shipping
   ↓
Maintenance
   ↓
Portfolio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each stage answers a different question:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;Core question&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;How does the skill load and execute?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fit &amp;amp; scope&lt;/td&gt;
&lt;td&gt;Should this be a skill at all?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typing &amp;amp; triggers&lt;/td&gt;
&lt;td&gt;When should it activate?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture&lt;/td&gt;
&lt;td&gt;How should the workflow operate?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anatomy&lt;/td&gt;
&lt;td&gt;What files make up the skill?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content&lt;/td&gt;
&lt;td&gt;How should instructions be written?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enforcement&lt;/td&gt;
&lt;td&gt;What can be enforced mechanically?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Measurement&lt;/td&gt;
&lt;td&gt;How do we know it works?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shipping&lt;/td&gt;
&lt;td&gt;How do users receive it?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maintenance&lt;/td&gt;
&lt;td&gt;How does it survive change?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Portfolio&lt;/td&gt;
&lt;td&gt;How do many skills coexist?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The important insight is that &lt;strong&gt;skill engineering covers the entire lifecycle, not just the writing of &lt;code&gt;SKILL.md&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Chapter 00 — How Skills Load and Run
&lt;/h2&gt;

&lt;p&gt;Before designing a skill, understand the runtime.&lt;/p&gt;

&lt;p&gt;A skill may look simple on disk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.claude/
└── skills/
    └── code-review/
        └── SKILL.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But conceptually the runtime does something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User request
     ↓
Skill discovery
     ↓
Trigger evaluation
     ↓
Skill activation
     ↓
Instruction loading
     ↓
Reference/tool loading
     ↓
Agent execution
     ↓
Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What does the agent actually see, and when does it see it?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This matters because context is limited.&lt;/p&gt;

&lt;p&gt;A skill might contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SKILL.md
references/
    database.md
    security.md
    examples.md
    architecture.md
scripts/
    validate.js
    check.sh
templates/
    report.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You usually don't want every file loaded for every request.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request
   ↓
SKILL.md
   ↓
Determine relevant task
   ↓
Load relevant reference
   ↓
Execute required script
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is &lt;strong&gt;progressive context loading&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The main skill file acts as an entry point rather than a giant knowledge dump.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context Is a Resource
&lt;/h3&gt;

&lt;p&gt;One of the biggest mistakes in AI skill design is treating context as free.&lt;/p&gt;

&lt;p&gt;It isn't.&lt;/p&gt;

&lt;h4&gt;
  
  
  Design A — Everything in one file
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SKILL.md
──────────────
3000 lines
50 examples
20 rules
10 workflows
15 edge cases
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Design B — Layered knowledge
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SKILL.md
   ↓
Routing
   ↓
references/
   ├── workflow.md
   ├── security.md
   └── examples.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second design gives you more control over what enters the model's context.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Design skills around context boundaries, not just file boundaries.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. Chapter 01 — Fit and Scope
&lt;/h2&gt;

&lt;p&gt;The next question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Should this behavior be implemented as a skill?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI development environments often provide multiple primitives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Skill
Rule
Agent
Hook
Script
Plugin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They are not interchangeable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Skill
&lt;/h3&gt;

&lt;p&gt;A skill describes &lt;strong&gt;how to perform a class of task&lt;/strong&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;database-migration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It might define:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Inspect schema
2. Inspect migration history
3. Design migration
4. Implement migration
5. Validate migration
6. Test rollback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Rule
&lt;/h3&gt;

&lt;p&gt;A rule is a constraint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Never modify production data directly.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is policy, not a workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agent
&lt;/h3&gt;

&lt;p&gt;An agent is useful when you need a distinct reasoning or execution role:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Main Agent
   ├── Research Agent
   ├── Security Agent
   └── Testing Agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Hook
&lt;/h3&gt;

&lt;p&gt;A hook responds to an event:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before tool call
      ↓
Security check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;After file modification
      ↓
Formatter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Script
&lt;/h3&gt;

&lt;p&gt;A script performs deterministic computation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;validate-schema.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI may decide &lt;strong&gt;when&lt;/strong&gt; to run it. The script determines &lt;strong&gt;how&lt;/strong&gt; validation works.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. The Boundary Is More Important Than the Skill
&lt;/h2&gt;

&lt;p&gt;A good skill should explicitly state what it does not do.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;This skill handles:
&lt;span class="p"&gt;
-&lt;/span&gt; PostgreSQL schema migrations
&lt;span class="p"&gt;-&lt;/span&gt; Migration generation
&lt;span class="p"&gt;-&lt;/span&gt; Migration validation
&lt;span class="p"&gt;-&lt;/span&gt; Rollback testing

This skill does not handle:
&lt;span class="p"&gt;
-&lt;/span&gt; Application architecture
&lt;span class="p"&gt;-&lt;/span&gt; Production deployment
&lt;span class="p"&gt;-&lt;/span&gt; Database backups
&lt;span class="p"&gt;-&lt;/span&gt; Infrastructure provisioning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because skills tend to grow.&lt;/p&gt;

&lt;p&gt;A developer starts with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;database migration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then adds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;database design
query optimization
backup strategy
production deployment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eventually the skill becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;database-engineering-everything
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and becomes difficult to reason about.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Scope is a defense against skill inflation.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. Chapter 02 — Typing and Triggers
&lt;/h2&gt;

&lt;p&gt;Once you know what a skill does, you need to answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;When should it activate?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;frontend-review
backend-review
security-review
performance-review
database-review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Review my authentication API."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Multiple skills may be relevant.&lt;/p&gt;

&lt;p&gt;You now have a routing problem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 User request
                      │
        ┌─────────────┼─────────────┐
        ↓             ↓             ↓
    Backend       Security       Performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything activates, the system becomes noisy.&lt;/p&gt;

&lt;p&gt;If nothing activates, the skill is useless.&lt;/p&gt;

&lt;h3&gt;
  
  
  Activation Is a Classification Problem
&lt;/h3&gt;

&lt;p&gt;Think of activation as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User request
      ↓
Intent classification
      ↓
Skill candidates
      ↓
Relevance evaluation
      ↓
Activation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Request&lt;/th&gt;
&lt;th&gt;Expected skill&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Create a PostgreSQL migration"&lt;/td&gt;
&lt;td&gt;Database migration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Fix this React component"&lt;/td&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Audit authentication"&lt;/td&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Why is this query slow?"&lt;/td&gt;
&lt;td&gt;Database performance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Write a technical article"&lt;/td&gt;
&lt;td&gt;Documentation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A good skill therefore needs a clear &lt;strong&gt;activation signature&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  False Positives and False Negatives
&lt;/h3&gt;

&lt;h4&gt;
  
  
  False positive
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Write a blog about PostgreSQL"

→ security skill activates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  False negative
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Why is my PostgreSQL migration failing?"

→ database migration skill does not activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both are important.&lt;/p&gt;

&lt;p&gt;Therefore, evaluate &lt;strong&gt;activation separately from execution&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Chapter 03 — Shape and Architecture
&lt;/h2&gt;

&lt;p&gt;Once a skill activates, what does it actually do?&lt;/p&gt;

&lt;p&gt;There are several useful workflow shapes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Route
&lt;/h3&gt;

&lt;p&gt;A route chooses a path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Request
                    ↓
                 classify
              /     |                   /      |                  Bug    Feature   Refactor
            ↓        ↓         ↓
         Debug    Implement  Refactor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pipeline
&lt;/h3&gt;

&lt;p&gt;A pipeline is sequential:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Research
   ↓
Analyze
   ↓
Plan
   ↓
Implement
   ↓
Test
   ↓
Review
   ↓
Report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is particularly useful for engineering skills.&lt;/p&gt;

&lt;h3&gt;
  
  
  Loop
&lt;/h3&gt;

&lt;p&gt;A loop supports iteration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Implement
    ↓
Test
    ↓
Failed?
  /    Yes     No
 ↓       ↓
Fix    Complete
 ↓
Test again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For coding agents, this is natural:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write implementation
        ↓
Run tests
        ↓
Read failure
        ↓
Modify implementation
        ↓
Run tests again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Failure becomes an expected workflow state rather than an exceptional event.&lt;/p&gt;

&lt;h3&gt;
  
  
  Map
&lt;/h3&gt;

&lt;p&gt;A map splits a problem into independent pieces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Research repository
                        │
          ┌─────────────┼─────────────┐
          ↓             ↓             ↓
       Frontend      Backend       Database
          ↓             ↓             ↓
       Findings      Findings      Findings
          └─────────────┼─────────────┘
                        ↓
                     Synthesis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Combining Shapes
&lt;/h3&gt;

&lt;p&gt;Real skills often combine these patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Route
  ↓
Pipeline
  ↓
Map
  ↓
Loop
  ↓
Final report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where AI skills start looking like &lt;strong&gt;workflow engines rather than prompts&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Chapter 04 — Anatomy
&lt;/h2&gt;

&lt;p&gt;A mature skill might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;skills/
└── deep-research/
    │
    ├── SKILL.md
    │
    ├── references/
    │   ├── research-methodology.md
    │   ├── source-evaluation.md
    │   └── evidence.md
    │
    ├── scripts/
    │   ├── validate-sources.js
    │   └── generate-report.js
    │
    ├── templates/
    │   └── report.md
    │
    └── examples/
        ├── example-1.md
        └── example-2.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each part has a job.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;SKILL.md&lt;/code&gt; Is the Hub
&lt;/h3&gt;

&lt;p&gt;Think of &lt;code&gt;SKILL.md&lt;/code&gt; as the router and operating manual.&lt;/p&gt;

&lt;p&gt;It should explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What this skill does
When it activates
What it must accomplish
What references to load
What workflow to follow
What constraints apply
How to validate the result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should not necessarily contain every piece of knowledge.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hub-and-Spoke Architecture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                   SKILL.md
                  /   |                    /    |                    ↓     ↓     ↓
          References Scripts Templates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hub provides orchestration.&lt;/p&gt;

&lt;p&gt;The spokes provide specialized resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data vs Instructions vs Code
&lt;/h3&gt;

&lt;p&gt;Separate them:&lt;/p&gt;

&lt;h4&gt;
  
  
  Instructions
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SKILL.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tell the agent what to do.&lt;/p&gt;

&lt;h4&gt;
  
  
  Data
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;references/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Provide knowledge.&lt;/p&gt;

&lt;h4&gt;
  
  
  Code
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;scripts/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perform deterministic operations.&lt;/p&gt;

&lt;p&gt;This separation makes skills easier to maintain and test.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Chapter 05 — Writing the Content
&lt;/h2&gt;

&lt;p&gt;Now we reach the instruction layer.&lt;/p&gt;

&lt;p&gt;Compare:&lt;/p&gt;

&lt;h3&gt;
  
  
  Weak
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;You might want to check whether tests pass.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Strong
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Run the test suite before declaring the task complete.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Stronger
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Do not declare the task complete until the test suite passes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The difference is &lt;strong&gt;binding strength&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instructions Have Different Authority
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Preference
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prefer TypeScript.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Requirement
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use TypeScript for new files.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Hard constraint
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Do not create JavaScript files. New implementation files must use TypeScript.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important rules should be unambiguous.&lt;/p&gt;

&lt;h3&gt;
  
  
  Present-Tense Instructions
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The agent should inspect the repository.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Inspect the repository before making changes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The agent will run the tests after implementation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Run the tests after implementation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Direct instructions are easier to interpret.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't Overload the Skill With Philosophy
&lt;/h3&gt;

&lt;p&gt;Avoid thousands of words explaining philosophy.&lt;/p&gt;

&lt;p&gt;Prefer operational instructions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Inspect X.
2. Determine Y.
3. Run Z.
4. If Z fails, investigate.
5. Do not proceed until Y is verified.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The skill should be &lt;strong&gt;operational&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Chapter 06 — Enforcement
&lt;/h2&gt;

&lt;p&gt;This is one of the most important ideas.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't rely on the model to enforce something that software can enforce.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Suppose your skill says:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Always run Prettier.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent might comply.&lt;/p&gt;

&lt;p&gt;But it might also forget.&lt;/p&gt;

&lt;p&gt;A stronger design is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI modifies file
      ↓
Hook
      ↓
Prettier
      ↓
Formatted file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Formatting no longer depends entirely on model memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI Instructions vs Mechanical Enforcement
&lt;/h3&gt;

&lt;p&gt;Consider:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Never commit secrets.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A prompt can say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RULE:
Never commit API keys.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But a stronger architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent
  ↓
git commit
  ↓
secret scanner
  ↓
Secret found?
  ├── Yes → Block commit
  └── No  → Continue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Enforcement Hierarchy
&lt;/h3&gt;

&lt;p&gt;A useful model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Human judgment
      ↓
AI instruction
      ↓
Automated validation
      ↓
Mechanical enforcement
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The further down the stack you go, the less you rely on model compliance.&lt;/p&gt;

&lt;p&gt;Examples of good candidates for automation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Formatting
Linting
Type checking
Schema validation
Tests
Secret detection
File naming
Generated artifacts
SQL safety
Permission boundaries
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI should focus on tasks requiring judgment.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Chapter 07 — Measurement
&lt;/h2&gt;

&lt;p&gt;Now ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How do we know the skill works?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A skill should ideally be evaluated, not merely read and trusted.&lt;/p&gt;

&lt;p&gt;There are two major dimensions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Activation Evaluation
&lt;/h3&gt;

&lt;p&gt;Did the correct skill activate?&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prompt:
"Create a PostgreSQL migration for the users table."

Expected:
database-migration → activated
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can maintain an evaluation set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌────────────────────────────────────┐
│ Activation Evaluation              │
├────────────────────────────────────┤
│ Prompt                             │
│ Expected skill                     │
│ Should activate?                   │
│ Actual skill                       │
│ Result                             │
└────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Behavior Evaluation
&lt;/h3&gt;

&lt;p&gt;Once activated, did the skill behave correctly?&lt;/p&gt;

&lt;p&gt;Suppose the migration skill requires:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Inspect schema
Check migration history
Create migration
Validate SQL
Test migration
Test rollback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Behavior evaluation checks those requirements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    Skill
                      ↓
             ┌────────┴────────┐
             ↓                 ↓
       Activation          Behavior
             ↓                 ↓
        Correct skill?    Correct workflow?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A skill could have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;90% activation accuracy
40% behavior accuracy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and still be a poor skill.&lt;/p&gt;

&lt;h3&gt;
  
  
  Measuring Skills Like Software
&lt;/h3&gt;

&lt;p&gt;Useful metrics include:&lt;/p&gt;

&lt;h4&gt;
  
  
  Activation accuracy
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;correct activations / total activation tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  False positive rate
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;incorrect activations / total tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  False negative rate
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;missed activations / applicable tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Task success rate
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;successful executions / total executions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Rule compliance
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;required behaviors satisfied / required behaviors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Regression rate
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;previously passing cases now failing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This turns skill development into an engineering discipline.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Auditing Against Prior Art
&lt;/h2&gt;

&lt;p&gt;Another useful activity is comparing your skill against existing approaches.&lt;/p&gt;

&lt;p&gt;Suppose you create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deep-research
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before declaring it complete, ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What existing research workflows already exist?

What evaluation techniques do they use?

What source-quality rules are common?

What am I missing?

Which practices are unnecessarily complicated?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is &lt;strong&gt;prior-art auditing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You don't need to reinvent every workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. Chapter 08 — Shipping
&lt;/h2&gt;

&lt;p&gt;A skill isn't useful if nobody can install it.&lt;/p&gt;

&lt;p&gt;A typical flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Development
    ↓
Repository
    ↓
Package / Plugin
    ↓
Distribution
    ↓
Installation
    ↓
Skill available
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Plugin Binding
&lt;/h3&gt;

&lt;p&gt;A plugin can act as a distribution container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Plugin
│
├── Skills
│   ├── research
│   ├── testing
│   └── code-review
│
├── Hooks
├── Commands
└── Configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets users install a cohesive collection rather than manually copying individual files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Versioning
&lt;/h3&gt;

&lt;p&gt;Once users depend on a skill, versioning matters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;research-skill@1.0.0
research-skill@1.1.0
research-skill@2.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"prefer X"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"must use X"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can change agent behavior significantly.&lt;/p&gt;

&lt;p&gt;Therefore skill versions should be treated as meaningful behavioral versions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dormancy
&lt;/h3&gt;

&lt;p&gt;A skill may sit unused for months.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer
   ↓
invokes old skill
   ↓
framework changed
   ↓
skill behaves differently
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is &lt;strong&gt;skill dormancy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Skills need lifecycle states and maintenance expectations.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. Chapter 09 — Maintenance
&lt;/h2&gt;

&lt;p&gt;AI skills exist inside rapidly changing ecosystems.&lt;/p&gt;

&lt;p&gt;Things change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI models
Agent runtimes
APIs
CLI tools
Frameworks
Repository structures
Tool interfaces
Best practices
Security requirements
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefore:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A skill is software, and software drifts.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Drift
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tool v1
 ↓
Skill v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tool v2
 ↓
behavior changed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your skill still assumes the old behavior.&lt;/p&gt;

&lt;p&gt;That is drift.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vendored Knowledge
&lt;/h3&gt;

&lt;p&gt;Suppose your skill contains a copy of external documentation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;external methodology
       ↓
copy
       ↓
your skill
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The external source changes.&lt;/p&gt;

&lt;p&gt;Your copy doesn't.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Upstream
   ↓
Version 3

Your skill
   ↓
Version 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have a maintenance obligation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Review Gate
&lt;/h3&gt;

&lt;p&gt;A good update flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Upstream changes
       ↓
Detect change
       ↓
Review
       ↓
Update skill
       ↓
Run evaluation suite
       ↓
Check regressions
       ↓
Release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Upstream changed
       ↓
blindly copy everything
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  14. Chapter 10 — The Skill Portfolio
&lt;/h2&gt;

&lt;p&gt;One skill is easy.&lt;/p&gt;

&lt;p&gt;Two are manageable.&lt;/p&gt;

&lt;p&gt;Ten are interesting.&lt;/p&gt;

&lt;p&gt;Fifty become an architecture problem.&lt;/p&gt;

&lt;p&gt;You may eventually have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;skills/
├── research/
├── frontend/
├── backend/
├── database/
├── security/
├── testing/
├── performance/
├── deployment/
├── documentation/
├── architecture/
├── debugging/
└── code-review/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you need portfolio management.&lt;/p&gt;

&lt;h3&gt;
  
  
  Skill Collision
&lt;/h3&gt;

&lt;p&gt;Suppose the user says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Review my API."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Potential matches:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api-review
backend-review
security-review
performance-review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which one activates?&lt;/p&gt;

&lt;p&gt;This is a &lt;strong&gt;collision&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If multiple skills activate, their instructions may conflict.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Skill A:
"Keep the implementation minimal."

Skill B:
"Add extensive validation."

Skill C:
"Refactor the architecture."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A skill portfolio therefore needs routing and priority policies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Skill Granularity
&lt;/h3&gt;

&lt;p&gt;How large should a skill be?&lt;/p&gt;

&lt;p&gt;Too broad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;software-engineering
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with everything inside it.&lt;/p&gt;

&lt;p&gt;Too narrow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;read-file
write-file
check-import
check-variable
run-test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don't want hundreds of microscopic skills.&lt;/p&gt;

&lt;p&gt;A better structure might be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Engineering
│
├── Research
├── Implementation
├── Testing
├── Security
└── Deployment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each skill owns a meaningful capability.&lt;/p&gt;

&lt;h3&gt;
  
  
  Router Families
&lt;/h3&gt;

&lt;p&gt;A router can first identify the broad family:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                  User request
                       ↓
                  Main Router
                       ↓
       ┌───────────────┼───────────────┐
       ↓               ↓               ↓
   Research        Engineering      Operations
       ↓               ↓               ↓
   Research        Backend         Deployment
   skill           Security        Monitoring
                   Testing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;blockquote&gt;
&lt;p&gt;"Which of these 100 skills should run?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;you ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Which family?
     ↓
Which subcategory?
     ↓
Which skill?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Retirement
&lt;/h3&gt;

&lt;p&gt;A healthy portfolio needs a retirement policy.&lt;/p&gt;

&lt;p&gt;A skill may become obsolete because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the underlying tool disappeared&lt;/li&gt;
&lt;li&gt;the workflow became part of another skill&lt;/li&gt;
&lt;li&gt;the framework changed&lt;/li&gt;
&lt;li&gt;the skill is redundant&lt;/li&gt;
&lt;li&gt;another skill superseded it&lt;/li&gt;
&lt;li&gt;nobody uses it anymore&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A lifecycle might be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Experimental
     ↓
Active
     ↓
Stable
     ↓
Deprecated
     ↓
Retired
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents the skill directory from becoming a graveyard.&lt;/p&gt;




&lt;h2&gt;
  
  
  15. The Deeper Architecture: Instructions + Tools + Enforcement + Evaluation
&lt;/h2&gt;

&lt;p&gt;A mature skill can be viewed as four major layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────┐
│              SKILL                   │
│                                      │
│  ┌────────────────────────────────┐  │
│  │ Instructions                    │  │
│  │ What the agent should do       │  │
│  └────────────────────────────────┘  │
│                  ↓                   │
│  ┌────────────────────────────────┐  │
│  │ Workflow                       │  │
│  │ Route / Pipeline / Loop / Map │  │
│  └────────────────────────────────┘  │
│                  ↓                   │
│  ┌────────────────────────────────┐  │
│  │ Enforcement                    │  │
│  │ Hooks / Scripts / Tests       │  │
│  └────────────────────────────────┘  │
│                  ↓                   │
│  ┌────────────────────────────────┐  │
│  │ Evaluation                     │  │
│  │ Activation / Behavior / QA    │  │
│  └────────────────────────────────┘  │
└──────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the important shift in thinking.&lt;/p&gt;

&lt;p&gt;A skill is not merely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;prompt → answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;intent
  ↓
routing
  ↓
context
  ↓
workflow
  ↓
tools
  ↓
validation
  ↓
feedback
  ↓
result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  16. Example: Building a Deep Research Skill
&lt;/h2&gt;

&lt;p&gt;Suppose you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deep-research
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Its directory could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deep-research/
├── SKILL.md
├── references/
│   ├── research-methodology.md
│   ├── source-quality.md
│   ├── evidence-evaluation.md
│   └── synthesis.md
├── scripts/
│   ├── validate-sources.js
│   └── generate-report.js
├── templates/
│   └── research-report.md
└── evals/
    ├── activation.json
    └── behavior.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 1 — Define Scope
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This skill performs structured research.

It handles:
- multi-source research
- source evaluation
- evidence synthesis
- contradiction analysis
- structured reporting

It does not handle:
- software implementation
- deployment
- generic writing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2 — Define Activation
&lt;/h3&gt;

&lt;p&gt;Potential activation prompts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Research this topic deeply."

"Investigate the current state of..."

"Compare these technologies using external sources."

"Find evidence for and against this claim."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Non-activation examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Fix this React bug."

"Run the tests."

"Format this file."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3 — Define the Workflow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Understand question
       ↓
Decompose question
       ↓
Identify evidence requirements
       ↓
Search
       ↓
Evaluate sources
       ↓
Extract evidence
       ↓
Cross-check claims
       ↓
Synthesize
       ↓
Write report
       ↓
Validate citations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4 — Add a Loop
&lt;/h3&gt;

&lt;p&gt;If two sources disagree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source A → Claim X
Source B → Claim Y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Conflict detected
       ↓
Investigate
       ↓
Find additional sources
       ↓
Re-evaluate evidence
       ↓
Resolve / report uncertainty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the skill combines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pipeline + Loop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5 — Add Mechanical Validation
&lt;/h3&gt;

&lt;p&gt;Instead of only telling the AI:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Make sure every claim has a citation."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;build a validator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Report
  ↓
Citation validator
  ↓
Missing citation?
  ├── Yes → fail
  └── No  → pass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6 — Evaluate Activation
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prompt:
"Do a deep investigation into DuckDB vs PostgreSQL for analytics."

Expected:
deep-research → YES
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prompt:
"Fix the DuckDB connection bug."

Expected:
deep-research → NO
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 7 — Evaluate Behavior
&lt;/h3&gt;

&lt;p&gt;For a research request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✓ question decomposition
✓ multiple sources
✓ source quality assessment
✓ evidence extraction
✓ conflicting evidence analysis
✓ synthesis
✓ citations
✓ final report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now regressions can be detected.&lt;/p&gt;




&lt;h2&gt;
  
  
  17. Applying This to an AI Engineering Harness
&lt;/h2&gt;

&lt;p&gt;This model becomes especially interesting when building a larger AI development harness.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    AI HARNESS
                        │
                        ↓
                  Intent Router
                        │
        ┌───────────────┼───────────────┐
        ↓               ↓               ↓
     Research       Engineering      Operations
        │               │               │
        ↓               ↓               ↓
     Skills           Skills          Skills
        │               │               │
        └───────────────┼───────────────┘
                        ↓
                     Tools
                        ↓
                  Enforcement
                        ↓
                    Evaluation
                        ↓
                    Reporting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is much more powerful than simply having a folder full of Markdown files.&lt;/p&gt;




&lt;h2&gt;
  
  
  18. Skills as a Policy Execution Layer
&lt;/h2&gt;

&lt;p&gt;Traditional software:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Code
 ↓
Execution
 ↓
Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AI software:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Intent
 ↓
Skill
 ↓
Reasoning
 ↓
Tools
 ↓
Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But production AI systems need another layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Intent
 ↓
Skill
 ↓
Reasoning
 ↓
Tools
 ↓
Policy
 ↓
Validation
 ↓
Result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The skill becomes a bridge between &lt;strong&gt;natural-language intent and deterministic engineering systems&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  19. The Most Important Design Principle
&lt;/h2&gt;

&lt;p&gt;If there is one idea to take away from all of this, it is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Use AI for judgment. Use software for certainty.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let the model handle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Interpretation
Planning
Hypothesis generation
Trade-offs
Synthesis
Creative reasoning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let software handle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Formatting
Validation
Testing
Schema checking
Permissions
Secret detection
Deterministic calculations
Policy enforcement
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI:
"These three files probably need to change."

Software:
"Does the resulting code compile?"

AI:
"This migration should be safe."

Software:
"Does the migration actually execute successfully?"

AI:
"These sources support the conclusion."

Software:
"Are the required citations present?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That division produces more reliable systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  20. Why Skill Engineering Will Become Important
&lt;/h2&gt;

&lt;p&gt;As AI agents become more capable, the bottleneck increasingly shifts away from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can the model write code?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;toward:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can we reliably control how the model works?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a different engineering problem.&lt;/p&gt;

&lt;p&gt;We need to reason about:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Activation
Context
Permissions
Workflow
Tools
Memory
Policies
Evaluation
Regression
Versioning
Distribution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are systems problems.&lt;/p&gt;

&lt;p&gt;That is why skill engineering starts resembling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;software architecture
        +
prompt engineering
        +
workflow orchestration
        +
testing
        +
policy enforcement
        +
package management
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  21. Practical Checklist for Building a Skill
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scope
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Is this actually a skill?&lt;/li&gt;
&lt;li&gt;[ ] Could this be a rule?&lt;/li&gt;
&lt;li&gt;[ ] Could this be a hook?&lt;/li&gt;
&lt;li&gt;[ ] Could this be a script?&lt;/li&gt;
&lt;li&gt;[ ] What does the skill explicitly refuse to do?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Activation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] When should it activate?&lt;/li&gt;
&lt;li&gt;[ ] When should it not activate?&lt;/li&gt;
&lt;li&gt;[ ] What are the ambiguous prompts?&lt;/li&gt;
&lt;li&gt;[ ] Can it collide with another skill?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Is the workflow a route?&lt;/li&gt;
&lt;li&gt;[ ] Pipeline?&lt;/li&gt;
&lt;li&gt;[ ] Loop?&lt;/li&gt;
&lt;li&gt;[ ] Map?&lt;/li&gt;
&lt;li&gt;[ ] Combination of these?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Context
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Is &lt;code&gt;SKILL.md&lt;/code&gt; concise?&lt;/li&gt;
&lt;li&gt;[ ] Can supporting information be loaded progressively?&lt;/li&gt;
&lt;li&gt;[ ] Are references separated from instructions?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Enforcement
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Which rules can be automated?&lt;/li&gt;
&lt;li&gt;[ ] Which checks should be hooks?&lt;/li&gt;
&lt;li&gt;[ ] Which checks should be scripts?&lt;/li&gt;
&lt;li&gt;[ ] Which requirements belong in CI?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Evaluation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Does the skill activate correctly?&lt;/li&gt;
&lt;li&gt;[ ] Does it perform the correct workflow?&lt;/li&gt;
&lt;li&gt;[ ] Are there regression tests?&lt;/li&gt;
&lt;li&gt;[ ] Are failure cases tested?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Shipping
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Is the skill versioned?&lt;/li&gt;
&lt;li&gt;[ ] Can another developer install it?&lt;/li&gt;
&lt;li&gt;[ ] Is plugin/package integration defined?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Maintenance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] What external dependencies can drift?&lt;/li&gt;
&lt;li&gt;[ ] Are vendored references tracked?&lt;/li&gt;
&lt;li&gt;[ ] Is there a review process?&lt;/li&gt;
&lt;li&gt;[ ] Can the skill become deprecated?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Portfolio
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Does it overlap with another skill?&lt;/li&gt;
&lt;li&gt;[ ] Is the granularity appropriate?&lt;/li&gt;
&lt;li&gt;[ ] Does the router know where it belongs?&lt;/li&gt;
&lt;li&gt;[ ] What happens when the skill is obsolete?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  22. Final Architecture
&lt;/h2&gt;

&lt;p&gt;Putting everything together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         USER INTENT
                              │
                              ▼
                     ┌────────────────┐
                     │     ROUTER     │
                     └───────┬────────┘
                             │
                             ▼
                    ┌──────────────────┐
                    │      SKILL       │
                    │                  │
                    │ Scope            │
                    │ Instructions     │
                    │ Workflow         │
                    │ References       │
                    └────────┬─────────┘
                             │
                             ▼
                  ┌─────────────────────┐
                  │   AI REASONING      │
                  └──────────┬──────────┘
                             │
                  ┌──────────┴──────────┐
                  ↓                     ↓
             Tools / APIs          Scripts
                  │                     │
                  └──────────┬──────────┘
                             ↓
                    ┌─────────────────┐
                    │   ENFORCEMENT   │
                    │                 │
                    │ Hooks           │
                    │ Policies        │
                    │ Validators      │
                    └────────┬────────┘
                             ↓
                    ┌─────────────────┐
                    │   EVALUATION    │
                    │                 │
                    │ Activation      │
                    │ Behavior        │
                    │ Regression      │
                    └────────┬────────┘
                             ↓
                         RESULT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And around the whole system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          ┌───────────────────────────────────┐
          │           SKILL LIFECYCLE         │
          │                                   │
          │ Version → Ship → Observe →       │
          │ Maintain → Update → Deprecate    │
          │                                   │
          └───────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusion: From Prompt Files to AI Engineering
&lt;/h2&gt;

&lt;p&gt;The simplest way to build an AI skill is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write SKILL.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The professional way is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Define scope
     ↓
Define activation
     ↓
Design workflow
     ↓
Structure context
     ↓
Write instructions
     ↓
Add tools
     ↓
Mechanically enforce critical rules
     ↓
Evaluate activation
     ↓
Evaluate behavior
     ↓
Version
     ↓
Ship
     ↓
Monitor drift
     ↓
Maintain
     ↓
Retire when necessary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the fundamental shift.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI skills should be treated less like prompts and more like software components.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A prompt tells an AI what you would &lt;em&gt;like&lt;/em&gt; it to do.&lt;/p&gt;

&lt;p&gt;A well-engineered skill defines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;when&lt;/strong&gt; it should act,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;what&lt;/strong&gt; it should do,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;what context&lt;/strong&gt; it should consume,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;how&lt;/strong&gt; it should execute,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;which rules&lt;/strong&gt; are mandatory,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;what software can enforce&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;how success is measured&lt;/strong&gt;, and&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;how the component evolves over time&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you start thinking this way, &lt;code&gt;.claude/skills/&lt;/code&gt; stops being a collection of Markdown files.&lt;/p&gt;

&lt;p&gt;It becomes an &lt;strong&gt;AI-native software architecture layer&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The future of agent engineering is not just better prompts — it is better systems around prompts.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Your Computer Is Busy When You're Not: Building a Desktop Observability Tool with Electron</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sun, 23 Aug 2026 17:14:54 +0000</pubDate>
      <link>https://dev.to/nishikantaray/your-computer-is-busy-when-youre-not-building-a-desktop-observability-tool-with-electron-1m6k</link>
      <guid>https://dev.to/nishikantaray/your-computer-is-busy-when-youre-not-building-a-desktop-observability-tool-with-electron-1m6k</guid>
      <description>&lt;p&gt;You close your laptop.&lt;/p&gt;

&lt;p&gt;The screen goes dark.&lt;/p&gt;

&lt;p&gt;You assume everything stopped.&lt;/p&gt;

&lt;p&gt;But what if it didn't?&lt;/p&gt;

&lt;p&gt;Maybe Docker is still transferring data.&lt;/p&gt;

&lt;p&gt;Maybe Chrome is still downloading something.&lt;/p&gt;

&lt;p&gt;Maybe an application is consuming CPU in the background.&lt;/p&gt;

&lt;p&gt;Maybe your computer woke up at 3 AM, performed some background work, and went back to sleep.&lt;/p&gt;

&lt;p&gt;Most operating systems already expose pieces of this information.&lt;/p&gt;

&lt;p&gt;The interesting part is putting those pieces together.&lt;/p&gt;

&lt;p&gt;That's what I wanted to explore:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Can we build an observability layer for a desktop computer using Electron?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not another CPU/RAM widget.&lt;/p&gt;

&lt;p&gt;Something that answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What is my computer actually doing?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Idea
&lt;/h2&gt;

&lt;p&gt;Imagine opening your desktop monitoring application and seeing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TODAY
────────────────────────────────────

Computer active        7h 42m
Idle                   1h 13m
Sleep                  8h 05m

Network
↓ Download             6.8 GB
↑ Upload               1.2 GB

Top applications
────────────────────────────────────

VS Code                3h 42m
Chrome                 2h 18m
Docker                 1h 31m
Slack                  52m

Network-heavy apps
────────────────────────────────────

Docker                 2.4 GB
Chrome                 1.8 GB
VS Code                920 MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now imagine clicking &lt;strong&gt;"What happened while I was away?"&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;18:42  User became idle
18:51  Screen locked
18:53  Docker network activity
19:07  Background sync completed
19:14  System entered sleep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's much more interesting than a CPU percentage.&lt;/p&gt;




&lt;h2&gt;
  
  
  The npm Package That Makes This Easier
&lt;/h2&gt;

&lt;p&gt;Instead of writing native system integrations for everything ourselves, we can start with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;systeminformation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;systeminformation&lt;/code&gt; provides APIs for system information, CPU, memory, battery, filesystem, network, processes, Docker and more. It also supports Linux, macOS and Windows, although individual APIs have platform-specific support.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;si&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;systeminformation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getSystemStats&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;battery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nx"&gt;si&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;currentLoad&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nx"&gt;si&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nx"&gt;si&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;battery&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nx"&gt;si&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;networkStats&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="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentLoad&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;battery&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;battery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;percent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;network&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getSystemStats&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now our Electron main process can periodically collect system information.&lt;/p&gt;




&lt;h2&gt;
  
  
  Monitoring Network Activity
&lt;/h2&gt;

&lt;p&gt;One of the most useful APIs is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;si&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;networkStats&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It provides network statistics including received/transmitted bytes and calculated per-second rates. The package calculates rates based on differences between successive calls, so the first call doesn't provide a meaningful rate yet.&lt;/p&gt;

&lt;p&gt;A simple monitor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;si&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;systeminformation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;stats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;si&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;networkStats&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;for &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;network&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iface&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;download&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rx_sec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tx_sec&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Wi-Fi
Download: 2.4 MB/s
Upload:   180 KB/s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this is only the beginning.&lt;/p&gt;




&lt;h2&gt;
  
  
  Network Connections
&lt;/h2&gt;

&lt;p&gt;We can also inspect active network connections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;connections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;si&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;networkConnections&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives us information about active TCP/UDP connections.&lt;/p&gt;

&lt;p&gt;That means we can potentially build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Active Connections
────────────────────────────

TCP    443    api.example.com
TCP    443    github.com
TCP    443    google.com
UDP    53     DNS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the dashboard starts becoming useful for troubleshooting.&lt;/p&gt;




&lt;h2&gt;
  
  
  Which Application Is Active?
&lt;/h2&gt;

&lt;p&gt;Network traffic alone doesn't tell us &lt;strong&gt;who is responsible&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We also want to know which application the user is interacting with.&lt;/p&gt;

&lt;p&gt;One option is a native active-window module such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @jannchie/active-window
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The package exposes information about the currently selected window and user idle time on supported Windows, macOS and Linux/Xorg environments. Platform coverage isn't identical everywhere, so this should be treated as an OS-dependent component.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;activeWindow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@jannchie/active-window&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getActiveApp&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="nb"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;activeWindow&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getActiveWindow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;process&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;windowClass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;windowName&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;Then we can record:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10:32:14  VS Code
10:32:15  VS Code
10:32:16  VS Code
...
10:45:02  Chrome
10:45:03  Chrome
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of storing every second individually, we can aggregate this into sessions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VS Code
10:32 → 10:45
Duration: 13 minutes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Sleep and Wake
&lt;/h2&gt;

&lt;p&gt;This is where Electron itself becomes useful.&lt;/p&gt;

&lt;p&gt;Electron provides the &lt;code&gt;powerMonitor&lt;/code&gt; module for monitoring system power-state changes, including suspend/resume, AC/battery changes, idle state and lock/unlock events on supported platforms.&lt;/p&gt;

&lt;p&gt;In the Electron main process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;powerMonitor&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;electron&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;powerMonitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;suspend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;System is going to sleep&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;powerMonitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;resume&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;System woke up&lt;/span&gt;&lt;span class="dl"&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;We can turn those events into database records:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;recordEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;powerMonitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;suspend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;recordEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system_sleep&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;powerMonitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;resume&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;recordEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system_wake&lt;/span&gt;&lt;span class="dl"&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;Now our timeline knows when the machine slept.&lt;/p&gt;




&lt;h2&gt;
  
  
  Idle Detection
&lt;/h2&gt;

&lt;p&gt;Electron also provides:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;powerMonitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSystemIdleTime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;powerMonitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSystemIdleState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The latter can return states such as &lt;code&gt;active&lt;/code&gt;, &lt;code&gt;idle&lt;/code&gt;, or &lt;code&gt;locked&lt;/code&gt; on supported systems.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;powerMonitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSystemIdleState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&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;idleSeconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;powerMonitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSystemIdleTime&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;idleSeconds&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can therefore distinguish:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Active
   ↓
Idle
   ↓
Locked
   ↓
Sleep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's much more meaningful than simply measuring application runtime.&lt;/p&gt;




&lt;h2&gt;
  
  
  Putting Everything Together
&lt;/h2&gt;

&lt;p&gt;Now imagine collecting events from four sources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Electron App
                      │
       ┌──────────────┼──────────────┐
       │              │              │
  powerMonitor   systeminformation   active-window
       │              │              │
       │         CPU / RAM / Net     Active App
       │              │              │
       └──────────────┼──────────────┘
                      ▼
                Event Collector
                      │
                      ▼
                Local Database
                      │
                      ▼
              Activity Timeline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simple event model could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;network&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;docker&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;downloadBytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1824000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;uploadBytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;420000&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;power&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sleep&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Code&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;server.js - Visual Studio Code&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now everything becomes queryable.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Interesting Part: Correlation
&lt;/h2&gt;

&lt;p&gt;This is where a normal system monitor becomes a &lt;strong&gt;desktop observability tool&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Suppose we see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;18:20  User idle
18:23  CPU 65%
18:24  Network 18 MB/s
18:26  Docker active
18:31  420 MB downloaded
18:42  Screen locked
18:45  Network still active
19:02  System sleep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can generate an explanation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Docker continued running after the user became idle and transferred approximately 420 MB before the system entered sleep.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's an insight.&lt;/p&gt;

&lt;p&gt;Not just a metric.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Simple Collector
&lt;/h2&gt;

&lt;p&gt;We could start with something surprisingly small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;powerMonitor&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;electron&lt;/span&gt;&lt;span class="dl"&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;si&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;systeminformation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;collect&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nx"&gt;si&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;currentLoad&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nx"&gt;si&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nx"&gt;si&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;networkStats&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="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;

    &lt;span class="na"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;idle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;powerMonitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSystemIdleTime&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;idleState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;powerMonitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSystemIdleState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;battery&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;powerMonitor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isOnBatteryPower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentLoad&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iface&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;rxPerSecond&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rx_sec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;txPerSecond&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tx_sec&lt;/span&gt;
    &lt;span class="p"&gt;}))&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Five seconds later, we have the beginning of our own desktop telemetry system.&lt;/p&gt;




&lt;h2&gt;
  
  
  But Don't Collect Everything Every Second
&lt;/h2&gt;

&lt;p&gt;This is an important design decision.&lt;/p&gt;

&lt;p&gt;You don't necessarily want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Every 1 second
    ↓
Everything
    ↓
Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That can generate enormous amounts of useless data.&lt;/p&gt;

&lt;p&gt;Instead, use different collection intervals.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Power events        Event-driven
App changes         Event-driven
CPU                 5-10 seconds
Memory              10 seconds
Network             1-5 seconds
Connections         10-30 seconds
Daily aggregates    1 minute+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And store &lt;strong&gt;state changes&lt;/strong&gt; rather than repeated identical states.&lt;/p&gt;

&lt;p&gt;For example, don't write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10:00 VS Code
10:01 VS Code
10:02 VS Code
10:03 VS Code
10:04 VS Code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VS Code
10:00 → 10:04
Duration: 4 minutes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the database dramatically smaller.&lt;/p&gt;




&lt;h2&gt;
  
  
  What About Electron's Network Logging?
&lt;/h2&gt;

&lt;p&gt;If the thing you're monitoring is specifically &lt;strong&gt;your Electron application's own network traffic&lt;/strong&gt;, Electron has another useful tool: &lt;code&gt;netLog&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;netLog&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;electron&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;whenReady&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;netLog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startLogging&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/tmp/electron-network-log&lt;/span&gt;&lt;span class="dl"&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;Electron's &lt;code&gt;netLog&lt;/code&gt; records network events for a session and supports different capture modes. Be careful with &lt;code&gt;includeSensitive&lt;/code&gt; and &lt;code&gt;everything&lt;/code&gt;, because those modes can capture sensitive information or transferred bytes.&lt;/p&gt;

&lt;p&gt;This is different from &lt;code&gt;systeminformation&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;systeminformation
        ↓
Whole-system information

Electron netLog
        ↓
Your Electron application's network activity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That distinction is important.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Product I Would Build
&lt;/h2&gt;

&lt;p&gt;I wouldn't call this another "Task Manager."&lt;/p&gt;

&lt;p&gt;I'd call it something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Desktop Observability&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The dashboard could have four major views.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Activity
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VS Code       4h 12m
Chrome        2h 31m
Slack         58m
Docker        1h 42m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Network
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Download     8.4 GB
Upload       1.3 GB

Docker       3.1 GB
Chrome       2.7 GB
VS Code      1.2 GB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Power
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Active       8h 21m
Idle         1h 08m
Sleep        7h 42m

Battery used 34%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Timeline
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;09:02  Wake
09:05  VS Code
10:32  Chrome
12:14  Idle
12:31  Docker network activity
13:02  Active
18:42  Lock
19:01  Sleep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then the killer feature:&lt;/p&gt;

&lt;h3&gt;
  
  
  Ask the computer
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Why was my laptop slow today?&lt;/p&gt;

&lt;p&gt;What used the most bandwidth?&lt;/p&gt;

&lt;p&gt;What happened while I was away?&lt;/p&gt;

&lt;p&gt;Which applications are active in the background?&lt;/p&gt;

&lt;p&gt;Did anything continue running after I locked the computer?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;p&gt;A practical first version could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Electron
│
├── Main Process
│   │
│   ├── powerMonitor
│   ├── systeminformation
│   ├── active-window
│   └── netLog
│
├── Collector
│   │
│   ├── power events
│   ├── app sessions
│   ├── CPU/memory
│   └── network stats
│
├── SQLite
│
└── React Renderer
    │
    ├── Dashboard
    ├── Timeline
    ├── Applications
    ├── Network
    └── Power
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key design principle is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Collect locally. Correlate locally. Explain locally.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You don't need to send a user's entire computer activity to a cloud server just to tell them why their laptop was busy.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bigger Idea
&lt;/h2&gt;

&lt;p&gt;The interesting thing here isn't &lt;code&gt;systeminformation&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It isn't Electron's &lt;code&gt;powerMonitor&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It isn't network monitoring.&lt;/p&gt;

&lt;p&gt;It's the &lt;strong&gt;combination&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A computer is already generating thousands of signals:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Applications
Processes
CPU
Memory
Network
Power
Sleep
Wake
Idle
Lock
Unlock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Today, these signals are mostly presented independently.&lt;/p&gt;

&lt;p&gt;A desktop observability layer could connect them.&lt;/p&gt;

&lt;p&gt;And instead of asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What's my CPU usage?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;we can finally ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"What happened on my computer while I wasn't looking?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's a much more interesting monitoring problem.&lt;/p&gt;

</description>
      <category>electron</category>
      <category>desktopapps</category>
      <category>power</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Smashing the "Blind Spot" Bug: How We Integrated Sentry to Catch Regressions in Real-Time</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sat, 08 Aug 2026 20:38:12 +0000</pubDate>
      <link>https://dev.to/nishikantaray/smashing-the-blind-spot-bug-how-we-integrated-sentry-to-catch-regressions-in-real-time-29m0</link>
      <guid>https://dev.to/nishikantaray/smashing-the-blind-spot-bug-how-we-integrated-sentry-to-catch-regressions-in-real-time-29m0</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/bugsmash"&gt;DEV's Summer Bug Smash: Smash Stories&lt;/a&gt; powered by &lt;a href="https://sentry.io/" rel="noopener noreferrer"&gt;Sentry&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge: Flying Blind in Production
&lt;/h2&gt;

&lt;p&gt;Pull Request - &lt;a href="https://github.com/NishikantaRay/InsightTrack/commit/a70ca0a00c8cd169a93b300cfcb450b5ecbde7f8" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/InsightTrack/commit/a70ca0a00c8cd169a93b300cfcb450b5ecbde7f8&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgtdojsxlekuugysxbwc8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgtdojsxlekuugysxbwc8.png" alt="Insighttracks" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before this summer, our analytics platform, &lt;strong&gt;InsightTrack&lt;/strong&gt;, had a fundamental flaw in how it handled observability. We were tracking standard JavaScript errors via a basic &lt;code&gt;window.onerror&lt;/code&gt; handler, but it was just noise. We had no stack traces, no grouped fingerprints, and absolutely no release context. &lt;/p&gt;

&lt;p&gt;If a customer integrated 10 different sites into our platform, we couldn't accurately tell them if a specific spike in errors was a brand-new issue or a resurrected bug from three deployments ago. We were flying blind, and our users were feeling the pain of delayed bug resolutions. &lt;/p&gt;

&lt;p&gt;The ultimate "bug" wasn't a single line of broken code; &lt;strong&gt;it was our entire error observability pipeline.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F34twqm7muckncttlk480.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F34twqm7muckncttlk480.png" alt="ARCH" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: A Deep-Dive Sentry Integration
&lt;/h2&gt;

&lt;p&gt;We decided to smash this architectural bug by building a native, robust integration with &lt;strong&gt;Sentry&lt;/strong&gt;. We didn't just want to add a widget; we wanted to bring Sentry's rich context (fingerprinted grouping, permalinks, regression status, and user-impact counts) directly into the InsightTrack dashboard so traffic and bugs could be watched side-by-side.&lt;/p&gt;

&lt;h3&gt;
  
  
  How We Built It
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzuh2qyvl8m1ljsblia9p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzuh2qyvl8m1ljsblia9p.png" alt="How we built it" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make this work seamlessly at scale (where one customer might poll 10 independent Sentry projects simultaneously), we built a dual-path ingestion system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Polling Backstop:&lt;/strong&gt; We set up a bounded worker pool (to prevent slow projects from stalling the fleet) that polls the Sentry API every 5 minutes. To respect rate limits, we built an &lt;strong&gt;adaptive cadence&lt;/strong&gt;—active projects poll frequently, while quiet or erroring projects exponentially back off. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Near-Real-Time Webhook:&lt;/strong&gt; For instant visibility, we allowed users to point a Sentry Internal Integration webhook at our API. Using HMAC signatures verified in constant time against a stored secret, new or regressed issues hit our database in milliseconds.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Golden Rule of our Architecture:&lt;/strong&gt; &lt;br&gt;
All writes (polls and webhooks) go to &lt;strong&gt;PostgreSQL&lt;/strong&gt;. A background sync then pushes this data to &lt;strong&gt;DuckDB&lt;/strong&gt; every 60 seconds. All dashboard reads and analytics queries come &lt;em&gt;only&lt;/em&gt; from DuckDB for lightning-fast performance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The "Smash" Moment 🔨
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp8gps25cftdl75hvxgy4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp8gps25cftdl75hvxgy4.png" alt="Smash" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We deployed the Sentry integration to production on a Tuesday. On Wednesday morning, it paid off spectacularly. &lt;/p&gt;

&lt;p&gt;A customer pushed a massive UI update to their e-commerce site. Within three minutes, our newly built &lt;strong&gt;Error Spike Alerts&lt;/strong&gt;—which calculate a 2-sigma (2σ) z-score against a 7-day rolling mean of Sentry events—fired off an alarm in their dashboard. &lt;/p&gt;

&lt;p&gt;Because we were pulling in Sentry's &lt;code&gt;substatus&lt;/code&gt; API field, the issue surfaced with a glaring red &lt;strong&gt;Regressed&lt;/strong&gt; badge right in our UI. &lt;/p&gt;

&lt;p&gt;Instead of opening five different tabs to figure out what went wrong, the customer clicked the row in our dashboard. This triggered our &lt;strong&gt;Live Drill-Down&lt;/strong&gt; feature, which makes an on-demand, real-time fetch directly to Sentry's &lt;code&gt;/events/latest/&lt;/code&gt; endpoint. The stack trace, breadcrumbs, and tags populated instantly. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3qn05i1576zk9931vwl7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3qn05i1576zk9931vwl7.png" alt="an" width="800" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The bug? A deprecated checkout component that had been accidentally uncommented during a merge conflict. It was identified, patched, and deployed before most of their users even woke up.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm Proud Of
&lt;/h2&gt;

&lt;p&gt;I am incredibly proud of how resilient we made this system. By decoupling the write path (PostgreSQL) from the read path (DuckDB), the dashboard remains incredibly fast even if the polling workers are churning through thousands of Sentry pagination cursors in the background. &lt;/p&gt;

&lt;p&gt;I'm also proud of the &lt;strong&gt;AI Analyst (Pulse)&lt;/strong&gt; tools we built on top of this. Because the data is so cleanly structured in DuckDB, we exposed read-only MCP tools (&lt;code&gt;get_error_summary&lt;/code&gt; and &lt;code&gt;get_error_issues&lt;/code&gt;). Now, users can literally chat with their analytics dashboard and ask, &lt;em&gt;"Did yesterday's deploy cause any regressions?"&lt;/em&gt; and the AI will read the synced Sentry data to give them a perfect answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Handling external APIs requires defensive programming.&lt;/strong&gt; Assuming an API will always return what you expect is a recipe for disaster. Building in graceful degradation and adaptive backoffs (like dropping to a 6-hour poll cadence on a 401 Auth Fail) kept our system from DDOSing ourselves with bad tokens.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Webhooks + Polling = The perfect marriage.&lt;/strong&gt; Webhooks are great for speed, but polling is necessary for accurate counts and state reconciliation (e.g., soft-deleting issues that have aged out). Using both gives you the best of both worlds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks to Sentry and the DEV community for the motivation to finally smash this architectural bug!&lt;/p&gt;

&lt;p&gt;The ultimate "bug" wasn't a single line of broken code; it was our entire error observability pipeline.&lt;br&gt;
Github - &lt;a href="https://github.com/nishikantaray/InsightTrack" rel="noopener noreferrer"&gt;https://github.com/nishikantaray/InsightTrack&lt;/a&gt;&lt;br&gt;
Website - &lt;a href="https://insightstrack.dev" rel="noopener noreferrer"&gt;https://insightstrack.dev&lt;/a&gt;&lt;br&gt;
Pull Request - &lt;a href="https://github.com/NishikantaRay/InsightTrack/commit/a70ca0a00c8cd169a93b300cfcb450b5ecbde7f8" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/InsightTrack/commit/a70ca0a00c8cd169a93b300cfcb450b5ecbde7f8&lt;/a&gt;&lt;br&gt;
Portfolio - &lt;a href="https://nishikanta.in/" rel="noopener noreferrer"&gt;https://nishikanta.in/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>bugsmash</category>
    </item>
    <item>
      <title>Building an AI-native Second Brain with Multi-RAG, Knowledge Graphs, and MCP</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sat, 08 Aug 2026 02:38:21 +0000</pubDate>
      <link>https://dev.to/nishikantaray/building-an-ai-native-second-brain-with-multi-rag-knowledge-graphs-and-mcp-fmg</link>
      <guid>https://dev.to/nishikantaray/building-an-ai-native-second-brain-with-multi-rag-knowledge-graphs-and-mcp-fmg</guid>
      <description>&lt;p&gt;Claude is incredibly good at reasoning.&lt;/p&gt;

&lt;p&gt;But reasoning is only as useful as the context available to it.&lt;/p&gt;

&lt;p&gt;Your architecture might be in GitHub. Your notes might be in Obsidian. Your decisions might be buried in Slack. Your research might be in PDFs. Your project history might exist across hundreds of conversations.&lt;/p&gt;

&lt;p&gt;The information exists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem is that your AI doesn't have a unified way to understand it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I started thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if Claude had a persistent Second Brain?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not another chatbot. Not another vector database.&lt;/p&gt;

&lt;p&gt;A knowledge layer that Claude can query, learn from, and write back to.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is a Second Brain?
&lt;/h2&gt;

&lt;p&gt;A Second Brain is a personal knowledge management system that helps you capture, organize, connect, and retrieve information outside your biological memory.&lt;/p&gt;

&lt;p&gt;Tools like Obsidian made this idea powerful.&lt;/p&gt;

&lt;p&gt;You can write simple Markdown notes and connect them:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;InsightTrack
    │
    ├── [[DuckDB]]
    ├── [[PostgreSQL]]
    └── [[MCP]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Obsidian then creates a visual graph of those relationships.&lt;/p&gt;

&lt;p&gt;But there is a limitation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Obsidian knows the relationships you explicitly create.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI can take this much further.&lt;/p&gt;

&lt;p&gt;Imagine having:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;architecture.md
      │
      └── mentions DuckDB

GitHub PR #481
      │
      └── changes DuckDB queries

Slack discussion
      │
      └── explains why DuckDB was selected

benchmark.md
      │
      └── contains performance results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A human may never manually connect all four.&lt;/p&gt;

&lt;p&gt;An AI-native knowledge system can discover those relationships automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  From Second Brain to AI Brain
&lt;/h2&gt;

&lt;p&gt;A traditional Second Brain mainly answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Where did I save this?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An AI-native Second Brain should answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"What do we know about this, where did it come from, and how is it connected to everything else?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That requires more than vector search.&lt;/p&gt;

&lt;p&gt;It requires multiple retrieval strategies working together.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Traditional RAG Isn't Enough
&lt;/h2&gt;

&lt;p&gt;A typical RAG architecture looks like:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Documents
    ↓
Chunking
    ↓
Embeddings
    ↓
Vector Search
    ↓
LLM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This works extremely well for semantic similarity.&lt;/p&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What was the reasoning behind our analytics architecture?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vector search can find relevant discussions even if the exact wording is different.&lt;/p&gt;

&lt;p&gt;But now ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Where is SYNC_BATCH_SIZE defined?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's an exact identifier.&lt;/p&gt;

&lt;p&gt;Keyword search is better.&lt;/p&gt;

&lt;p&gt;Or ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What services depend on PostgreSQL?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's a relationship question.&lt;/p&gt;

&lt;p&gt;A knowledge graph is better.&lt;/p&gt;

&lt;p&gt;This is why I think a serious AI Second Brain needs &lt;strong&gt;Multi-RAG&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Multi-RAG: Different Questions Need Different Retrieval
&lt;/h2&gt;

&lt;p&gt;Instead of relying on one retrieval technique:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Semantic Search
       +
Full-Text Search
       +
Knowledge Graph
       +
Metadata Filtering
       +
Reranking
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Each method solves a different problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Semantic RAG
&lt;/h3&gt;

&lt;p&gt;Good for understanding concepts.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why did we choose DuckDB?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Keyword RAG
&lt;/h3&gt;

&lt;p&gt;Good for exact information.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Find references to SYNC_BATCH_SIZE."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Graph RAG
&lt;/h3&gt;

&lt;p&gt;Good for relationships.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which services depend on PostgreSQL?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Memory Retrieval
&lt;/h3&gt;

&lt;p&gt;Good for decisions and persistent context.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What did we decide about the analytics architecture?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Together, they provide much richer context than vector search alone.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;p&gt;The important idea isn't any individual component.&lt;/p&gt;

&lt;p&gt;It's how the components work together.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Obsidian / Documents / External Sources
                │
                ▼
           Event Queue
                │
                ▼
        Processing Workers
          │      │      │
          ▼      ▼      ▼
       Metadata Embedding Graph
          │      │      │
          └──────┼──────┘
                 ▼
          Knowledge Layer
                 │
      ┌──────────┼──────────┐
      ▼          ▼          ▼
   Vector      Search      Graph
   Search      Index       Store
      │          │          │
      └──────────┼──────────┘
                 ▼
          Retrieval Engine
                 │
                 ▼
              MCP / API
                 │
                 ▼
          Claude / GPT / AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  Obsidian Is the Human Interface
&lt;/h2&gt;

&lt;p&gt;I don't see Obsidian as the entire Second Brain.&lt;/p&gt;

&lt;p&gt;I see it as one of the best &lt;strong&gt;human-facing knowledge interfaces&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can continue writing naturally:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Analytics Architecture

InsightTrack uses [[DuckDB]] for analytical queries.

Data originates in [[PostgreSQL]].

See [[Pulse]] for the AI analytics layer.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Obsidian gives you human-readable notes and a native graph.&lt;/p&gt;

&lt;p&gt;The AI system adds another layer on top.&lt;/p&gt;




&lt;h2&gt;
  
  
  Two Graphs, Two Purposes
&lt;/h2&gt;

&lt;p&gt;This architecture can maintain two different graphs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Obsidian Graph
&lt;/h3&gt;

&lt;p&gt;Created from explicit links:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[[InsightTrack]]
       │
       ▼
   [[DuckDB]]
       │
       ▼
  [[Analytics]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is primarily useful for &lt;strong&gt;human navigation&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  System Entity Graph
&lt;/h3&gt;

&lt;p&gt;Automatically extracted from all available knowledge:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;InsightTrack
      │
     USES
      │
   DuckDB
   /    \
READS   SYNCED_FROM
 /          \
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Pulse      PostgreSQL&lt;/p&gt;

&lt;p&gt;The system graph can be built from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Markdown&lt;/li&gt;
&lt;li&gt;Source code&lt;/li&gt;
&lt;li&gt;Git commits&lt;/li&gt;
&lt;li&gt;Pull requests&lt;/li&gt;
&lt;li&gt;Database schemas&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;li&gt;Conversations&lt;/li&gt;
&lt;li&gt;Meeting notes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This graph isn't just for visualization.&lt;/p&gt;

&lt;p&gt;It becomes part of retrieval.&lt;/p&gt;




&lt;h2&gt;
  
  
  Knowledge Engineering + Graph Engineering
&lt;/h2&gt;

&lt;p&gt;This is where the architecture becomes more interesting than a normal RAG application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Knowledge Engineering&lt;/strong&gt; turns raw information into structured knowledge.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Meeting Transcript
        ↓
     Summary
        ↓
   Action Items
        ↓
Architecture Decision
        ↓
   Project Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Graph Engineering&lt;/strong&gt; connects the resulting entities.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Project
   ↓
Repository
   ↓
  API
   ↓
Database
   ↓
Developer
   ↓
Decision
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The result isn't just a collection of documents.&lt;/p&gt;

&lt;p&gt;It's a connected knowledge model.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Retrieval Engine
&lt;/h2&gt;

&lt;p&gt;The retrieval engine is arguably the most important part.&lt;/p&gt;

&lt;p&gt;Suppose you ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why did we move analytics queries from PostgreSQL to DuckDB?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The system might retrieve:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GitHub PR
      +
Architecture Note
      +
Benchmark
      +
Slack Discussion
      +
Decision Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then rerank and combine the results.&lt;/p&gt;

&lt;p&gt;Instead of giving Claude thousands of chunks, the system builds a focused context:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Decision:
Use DuckDB for analytical workloads.

Evidence:
- Benchmarks showed better aggregation performance.
- PostgreSQL remains the transactional source of truth.
- The architecture PR implemented the separation.
- The Slack discussion explains the operational trade-offs.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now Claude is reasoning over &lt;strong&gt;evidence + relationships + memory&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Long-Term Memory
&lt;/h2&gt;

&lt;p&gt;A Second Brain shouldn't remember everything.&lt;/p&gt;

&lt;p&gt;Otherwise, it becomes another giant database.&lt;/p&gt;

&lt;p&gt;It should remember what matters.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Decision
────────────────────
PostgreSQL remains the source of truth.

Decision
────────────────────
DuckDB handles analytical reads.

Reason
────────────────────
Better analytical performance and isolation.

Status
────────────────────
Implemented.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is much more valuable than storing thousands of raw conversations.&lt;/p&gt;

&lt;p&gt;The system should distinguish between:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Raw Data
   ↓
Information
   ↓
Knowledge
   ↓
Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That's an important part of making AI memory useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  MCP Connects the Second Brain to Claude
&lt;/h2&gt;

&lt;p&gt;This is where the architecture becomes AI-native.&lt;/p&gt;

&lt;p&gt;Instead of building a custom integration directly into Claude, expose the Second Brain through &lt;strong&gt;MCP&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;search()
retrieve()
remember()
ingest()
graph()
timeline()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Claude can ask:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;search(
  "Why did we choose DuckDB?"
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The Second Brain handles the complexity.&lt;/p&gt;

&lt;p&gt;Claude doesn't need to know whether the answer came from:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PostgreSQL
pgvector
Search Index
Knowledge Graph
Obsidian
GitHub
Slack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It simply receives useful context.&lt;/p&gt;




&lt;h2&gt;
  
  
  Claude Can Write Back
&lt;/h2&gt;

&lt;p&gt;This is where it becomes more than traditional RAG.&lt;/p&gt;

&lt;p&gt;The flow isn't only:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Knowledge → AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It becomes:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Knowledge ↔ AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Remember that we decided to keep PostgreSQL as the source of truth."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Claude calls:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;remember(...)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The system can then:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Extract Entities
       ↓
Extract Relationships
       ↓
   Create Memory
       ↓
Generate Embedding
       ↓
   Update Graph
       ↓
   Store Source
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The knowledge base becomes progressively richer.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Model Doesn't Own the Knowledge
&lt;/h2&gt;

&lt;p&gt;This is one of the most important ideas.&lt;/p&gt;

&lt;p&gt;Today:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Claude
   ↓
Claude Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Another AI:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GPT
   ↓
GPT Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Another:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Gemini
   ↓
Gemini Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Everything is isolated.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             Claude
                │
               GPT
                │
             Gemini
                │
              Cursor
                │
                ▼
         ┌───────────────┐
         │  Knowledge OS │
         └───────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The model can change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The knowledge stays.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bigger Idea
&lt;/h2&gt;

&lt;p&gt;I don't think the future is simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Give Claude more context."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think it's:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Build a persistent knowledge layer that every AI can use.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Obsidian can remain your human knowledge interface.&lt;/p&gt;

&lt;p&gt;GitHub can remain your source-code system.&lt;/p&gt;

&lt;p&gt;Slack can remain your communication system.&lt;/p&gt;

&lt;p&gt;Your databases can remain your data systems.&lt;/p&gt;

&lt;p&gt;Your AI assistants can remain your reasoning systems.&lt;/p&gt;

&lt;p&gt;The Knowledge OS connects them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Beyond the Second Brain
&lt;/h2&gt;

&lt;p&gt;A traditional Second Brain helps &lt;strong&gt;you remember&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An AI-native Second Brain helps &lt;strong&gt;AI understand&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It combines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge Engineering&lt;/strong&gt; — turning raw information into structured knowledge&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graph Engineering&lt;/strong&gt; — discovering entities and relationships&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hybrid Retrieval&lt;/strong&gt; — combining semantic, keyword, and graph search&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Long-Term Memory&lt;/strong&gt; — preserving decisions and important context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP&lt;/strong&gt; — making the knowledge available to AI agents and assistants&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is something larger than a note-taking application or a vector database.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;An AI-native Knowledge Operating System that combines Knowledge Engineering, Graph Engineering, Hybrid Retrieval, and Long-Term Memory into a unified platform accessible through MCP and APIs.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The LLM provides the reasoning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Knowledge OS provides the memory.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And MCP becomes the bridge between them.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>claude</category>
      <category>rag</category>
    </item>
    <item>
      <title>Mind Maps in MCP: A Powerful Feature or Just Eye Candy?</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sat, 01 Aug 2026 18:27:45 +0000</pubDate>
      <link>https://dev.to/nishikantaray/mind-maps-in-mcp-a-powerful-feature-or-just-eye-candy-2oh2</link>
      <guid>https://dev.to/nishikantaray/mind-maps-in-mcp-a-powerful-feature-or-just-eye-candy-2oh2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Mind maps are an excellent addition to an MCP ecosystem when they help users understand relationships between data, tools, and reasoning. They should complement—not replace—traditional dashboards, tables, and chat interfaces.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Large Language Models have become incredibly good at answering questions. Ask about your analytics, codebase, documentation, or infrastructure, and they'll generate a detailed response in seconds.&lt;/p&gt;

&lt;p&gt;But there's a problem.&lt;/p&gt;

&lt;p&gt;Most AI conversations are &lt;strong&gt;linear&lt;/strong&gt;, while the problems we're solving are &lt;strong&gt;non-linear&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why did traffic drop yesterday?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A traditional AI responds with several paragraphs of text.&lt;/p&gt;

&lt;p&gt;A mind map, however, immediately shows the relationships between traffic sources, landing pages, countries, devices, deployments, and JavaScript errors.&lt;/p&gt;

&lt;p&gt;Instead of reading hundreds of words, you understand the entire situation in seconds.&lt;/p&gt;

&lt;p&gt;This naturally raises an interesting question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Should every MCP server support mind maps?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After exploring different architectures and use cases, my conclusion is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yes—but only when they help users understand relationships rather than simply displaying information.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's explore why.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is a Mind Map in MCP?
&lt;/h2&gt;

&lt;p&gt;An MCP (Model Context Protocol) server exposes tools that AI models can use.&lt;/p&gt;

&lt;p&gt;Normally the workflow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
  │
  ▼
LLM
  │
  ▼
MCP Tool
  │
  ▼
Database
  │
  ▼
Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI collects data, summarizes it, and returns text.&lt;/p&gt;

&lt;p&gt;Now imagine adding a visualization layer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             User
               │
               ▼
          AI Planner
               │
      ┌────────┴────────┐
      ▼                 ▼
 Analytics Tool    Documentation Tool
      ▼                 ▼
 Error Tool        Code Search Tool
      ▼                 ▼
      └────────┬────────┘
               ▼
     Relationship Builder
               ▼
      Interactive Mind Map
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI still performs the same work.&lt;/p&gt;

&lt;p&gt;The difference is that users now see &lt;strong&gt;how everything connects&lt;/strong&gt; instead of reading a long explanation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Traditional AI Isn't Always Enough
&lt;/h2&gt;

&lt;p&gt;Humans naturally think in relationships.&lt;/p&gt;

&lt;p&gt;When someone asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why are conversions down?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They aren't thinking linearly.&lt;/p&gt;

&lt;p&gt;They're exploring multiple possibilities simultaneously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Conversions
│
├── Traffic
│
├── Checkout
│
├── Marketing
│
├── Performance
│
├── Returning Users
│
└── Errors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each branch creates another investigation.&lt;/p&gt;

&lt;p&gt;This is exactly how troubleshooting works.&lt;/p&gt;

&lt;p&gt;A mind map simply visualizes that thought process.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real Analytics Example
&lt;/h2&gt;

&lt;p&gt;Suppose an AI receives this question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why did yesterday's traffic decrease?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of returning paragraphs, it could generate something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traffic Drop
│
├── Organic Search ↓
│
├── Homepage ↓
│
├── India ↓
│
├── JavaScript Errors ↑
│
├── Core Web Vitals ↓
│
└── New Deployment ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within seconds the user understands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Organic search decreased&lt;/li&gt;
&lt;li&gt;Homepage was affected&lt;/li&gt;
&lt;li&gt;Most impact came from India&lt;/li&gt;
&lt;li&gt;JavaScript errors increased&lt;/li&gt;
&lt;li&gt;A deployment happened recently&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The graph immediately tells a story.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where Mind Maps Work Best
&lt;/h2&gt;

&lt;h2&gt;
  
  
  1. Analytics Investigation
&lt;/h2&gt;

&lt;p&gt;Traditional dashboards answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many visitors?&lt;/li&gt;
&lt;li&gt;Which country?&lt;/li&gt;
&lt;li&gt;Which browser?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mind maps answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why did traffic change?&lt;/li&gt;
&lt;li&gt;Which metrics influence each other?&lt;/li&gt;
&lt;li&gt;What caused this anomaly?&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traffic
│
├── Organic
│   ├── Landing Pages
│   ├── Keywords
│   └── Countries
│
├── Paid
│
├── Social
│
└── Referral
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This transforms disconnected metrics into connected insights.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Documentation Search
&lt;/h2&gt;

&lt;p&gt;Imagine asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Explain authentication.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of returning dozens of documents, the AI groups concepts together.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authentication
│
├── OAuth
├── JWT
├── API Keys
├── Sessions
└── Permissions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Users instantly understand the overall architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Codebase Exploration
&lt;/h2&gt;

&lt;p&gt;Large repositories can be overwhelming.&lt;/p&gt;

&lt;p&gt;Instead of thousands of files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Backend
│
├── API
│
├── Database
│   ├── PostgreSQL
│   └── Prisma
│
├── Authentication
│
└── Workers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Developers can navigate the repository visually.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. AI Agent Planning
&lt;/h2&gt;

&lt;p&gt;Most AI agents perform many hidden steps.&lt;/p&gt;

&lt;p&gt;A mind map exposes them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task
│
├── Research
│
├── Search
│
├── Compare
│
├── Generate
│
└── Validate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes debugging AI workflows dramatically easier.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Biggest Advantages
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Better Understanding
&lt;/h2&gt;

&lt;p&gt;Humans recognize patterns much faster than paragraphs.&lt;/p&gt;

&lt;p&gt;Instead of reading 800 words, users understand the entire structure in seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  Relationship Discovery
&lt;/h2&gt;

&lt;p&gt;Traditional dashboards display numbers.&lt;/p&gt;

&lt;p&gt;Mind maps display relationships.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deployment
      │
      ▼
JavaScript Errors
      │
      ▼
Checkout Failure
      │
      ▼
Revenue Drop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That chain is much harder to discover from charts alone.&lt;/p&gt;




&lt;h2&gt;
  
  
  Easier Navigation
&lt;/h2&gt;

&lt;p&gt;Users don't need every detail immediately.&lt;/p&gt;

&lt;p&gt;They can expand only the sections they care about.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traffic
  │
  ├── Organic
  │
  ├── Direct
  │
  └── Social
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps complex systems manageable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Better AI Transparency
&lt;/h2&gt;

&lt;p&gt;Instead of wondering why the AI reached a conclusion, users can inspect the reasoning path visually.&lt;/p&gt;

&lt;p&gt;This increases trust in AI-generated answers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where Mind Maps Fail
&lt;/h2&gt;

&lt;p&gt;Like every visualization, they have limitations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Everything Becomes a Graph
&lt;/h2&gt;

&lt;p&gt;One common mistake is trying to visualize every piece of information.&lt;/p&gt;

&lt;p&gt;Imagine this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Visitors
│
├── Countries
├── Browsers
├── Devices
├── Sessions
├── Events
├── Campaigns
├── Pages
├── Heatmaps
├── Errors
├── Funnels
├── Scroll Depth
├── UTM
├── Performance
└── ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a few hundred nodes, the graph becomes unreadable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tables Are Sometimes Better
&lt;/h2&gt;

&lt;p&gt;Suppose someone asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Show today's visitors.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They don't need a graph.&lt;/p&gt;

&lt;p&gt;They need this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hour&lt;/th&gt;
&lt;th&gt;Visitors&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;9 AM&lt;/td&gt;
&lt;td&gt;241&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10 AM&lt;/td&gt;
&lt;td&gt;318&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11 AM&lt;/td&gt;
&lt;td&gt;401&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Not every question benefits from visualization.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;Large graphs become expensive.&lt;/p&gt;

&lt;p&gt;Some challenges include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thousands of nodes&lt;/li&gt;
&lt;li&gt;Complex edge calculations&lt;/li&gt;
&lt;li&gt;Layout algorithms&lt;/li&gt;
&lt;li&gt;Browser memory usage&lt;/li&gt;
&lt;li&gt;Slow rendering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most graph libraries begin struggling once graphs become extremely large unless clustering or virtualization is implemented.&lt;/p&gt;




&lt;h2&gt;
  
  
  Additional Maintenance
&lt;/h2&gt;

&lt;p&gt;Relationships don't build themselves.&lt;/p&gt;

&lt;p&gt;Every new feature means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New node types&lt;/li&gt;
&lt;li&gt;New edge rules&lt;/li&gt;
&lt;li&gt;Updated layouts&lt;/li&gt;
&lt;li&gt;Better ranking algorithms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Graph maintenance quickly becomes its own subsystem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Mistakes
&lt;/h2&gt;

&lt;p&gt;Many developers build graphs that simply mirror database tables.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Country
   │
   ▼
India
   │
   ▼
Users
   │
   ▼
5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That provides almost no value.&lt;/p&gt;

&lt;p&gt;Instead, focus on &lt;strong&gt;relationships&lt;/strong&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traffic Drop
│
├── Homepage
├── Organic Search
├── India
└── JavaScript Errors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The graph explains &lt;em&gt;why&lt;/em&gt; something happened.&lt;/p&gt;




&lt;h2&gt;
  
  
  Should Every MCP Include Mind Maps?
&lt;/h2&gt;

&lt;p&gt;Not necessarily.&lt;/p&gt;

&lt;p&gt;Here's a simple rule.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Great Fit&lt;/th&gt;
&lt;th&gt;Poor Fit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Documentation&lt;/td&gt;
&lt;td&gt;Raw SQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI reasoning&lt;/td&gt;
&lt;td&gt;CSV exports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Research&lt;/td&gt;
&lt;td&gt;Tables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture&lt;/td&gt;
&lt;td&gt;Dashboards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent workflows&lt;/td&gt;
&lt;td&gt;Metric reports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Knowledge graphs&lt;/td&gt;
&lt;td&gt;Simple searches&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Mind maps are strongest when users need to understand &lt;strong&gt;connections&lt;/strong&gt;, not just retrieve information.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Better Architecture
&lt;/h2&gt;

&lt;p&gt;Rather than replacing the existing interface, add mind maps as an exploration mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dashboard
│
├── Visitors
├── Revenue
├── Funnels
├── Heatmaps
└── Errors

        │
        ▼

🧠 Explore Relationships

        │
        ▼

Traffic
│
├── Acquisition
├── Geography
├── Pages
├── Errors
└── Performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dashboard remains familiar.&lt;/p&gt;

&lt;p&gt;The graph becomes a discovery tool.&lt;/p&gt;

&lt;p&gt;This hybrid approach gives users the best of both worlds.&lt;/p&gt;




&lt;h2&gt;
  
  
  Recommended Libraries
&lt;/h2&gt;

&lt;p&gt;If you're planning to build interactive graph visualizations, these libraries are worth considering.&lt;/p&gt;

&lt;h3&gt;
  
  
  React Flow
&lt;/h3&gt;

&lt;p&gt;Perfect for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interactive editors&lt;/li&gt;
&lt;li&gt;Expandable nodes&lt;/li&gt;
&lt;li&gt;Workflow builders&lt;/li&gt;
&lt;li&gt;AI reasoning graphs&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Cytoscape.js
&lt;/h3&gt;

&lt;p&gt;Excellent for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large relationship graphs&lt;/li&gt;
&lt;li&gt;Knowledge visualization&lt;/li&gt;
&lt;li&gt;Network analysis&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  AntV G6
&lt;/h3&gt;

&lt;p&gt;Great for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enterprise dashboards&lt;/li&gt;
&lt;li&gt;Knowledge graphs&lt;/li&gt;
&lt;li&gt;Automatic layouts&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Sigma.js
&lt;/h3&gt;

&lt;p&gt;Designed for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very large graphs&lt;/li&gt;
&lt;li&gt;High-performance rendering&lt;/li&gt;
&lt;li&gt;Thousands of nodes&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  D3.js
&lt;/h3&gt;

&lt;p&gt;Ideal when you need complete customization and don't mind writing more code.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Recommendation
&lt;/h2&gt;

&lt;p&gt;If I were designing an MCP platform today, I wouldn't make the mind map the default interface.&lt;/p&gt;

&lt;p&gt;Instead, I'd treat it as an &lt;strong&gt;optional exploration layer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Users should still have access to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Traditional chat&lt;/li&gt;
&lt;li&gt;Tables&lt;/li&gt;
&lt;li&gt;Dashboards&lt;/li&gt;
&lt;li&gt;Charts&lt;/li&gt;
&lt;li&gt;SQL results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When they want to understand relationships, they can switch to the graph view.&lt;/p&gt;

&lt;p&gt;This keeps the interface simple while providing powerful visualization when it's genuinely useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Mind maps aren't valuable because they look impressive.&lt;/p&gt;

&lt;p&gt;They're valuable because they help users understand relationships that are difficult to see in text, tables, or dashboards.&lt;/p&gt;

&lt;p&gt;For MCP ecosystems, they're especially effective for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI reasoning&lt;/li&gt;
&lt;li&gt;Documentation discovery&lt;/li&gt;
&lt;li&gt;Codebase exploration&lt;/li&gt;
&lt;li&gt;Knowledge graphs&lt;/li&gt;
&lt;li&gt;Multi-agent workflows&lt;/li&gt;
&lt;li&gt;Analytics investigations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, they should never replace dashboards or structured data.&lt;/p&gt;

&lt;p&gt;The most effective MCP platforms will combine both approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chat for conversations&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dashboards for metrics&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mind maps for relationships&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use each interface where it excels.&lt;/p&gt;

&lt;p&gt;In the end, the goal isn't to make AI prettier—it's to make complex information easier to understand.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Running Hermes Agent with Kokoro TTS: A Local-First AI Assistant Setup</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sun, 26 Jul 2026 07:19:14 +0000</pubDate>
      <link>https://dev.to/nishikantaray/running-hermes-agent-with-kokoro-tts-a-local-first-ai-assistant-setup-523h</link>
      <guid>https://dev.to/nishikantaray/running-hermes-agent-with-kokoro-tts-a-local-first-ai-assistant-setup-523h</guid>
      <description>&lt;p&gt;Most AI agents today depend heavily on cloud APIs. They're fast, but every request costs money, depends on an internet connection, and sends your data to external providers.&lt;/p&gt;

&lt;p&gt;Over the weekend, I experimented with &lt;strong&gt;Hermes Agent&lt;/strong&gt; and &lt;strong&gt;Kokoro TTS&lt;/strong&gt;, building a completely local voice-enabled AI assistant. The result was surprisingly good—responses were generated locally, converted into natural speech, and even delivered through Telegram.&lt;/p&gt;

&lt;p&gt;It felt much closer to having a personal AI operating system than simply chatting with an LLM.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Hermes Agent?
&lt;/h2&gt;

&lt;p&gt;Hermes Agent is an open-source AI agent framework from Nous Research designed for long-running AI workflows. Unlike a traditional chatbot, Hermes can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execute tools&lt;/li&gt;
&lt;li&gt;Remember previous interactions&lt;/li&gt;
&lt;li&gt;Learn reusable skills&lt;/li&gt;
&lt;li&gt;Schedule recurring jobs&lt;/li&gt;
&lt;li&gt;Connect with messaging platforms like Telegram&lt;/li&gt;
&lt;li&gt;Work with both cloud and local models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also supports OpenAI-compatible endpoints, making it easy to swap between cloud providers and local inference engines.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why use Kokoro TTS?
&lt;/h2&gt;

&lt;p&gt;Kokoro is a lightweight text-to-speech engine that runs locally and produces surprisingly natural voices.&lt;/p&gt;

&lt;p&gt;Instead of sending text to cloud TTS providers, everything happens on your own machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Completely offline&lt;/li&gt;
&lt;li&gt;No API costs&lt;/li&gt;
&lt;li&gt;Low latency&lt;/li&gt;
&lt;li&gt;Privacy-friendly&lt;/li&gt;
&lt;li&gt;Easy integration with local AI workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For demos, assistants, and automation, it feels almost instant.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                User
                  │
          Telegram / CLI
                  │
          ┌───────────────┐
          │ Hermes Agent  │
          └──────┬────────┘
                 │
      ┌──────────┴──────────┐
      │                     │
 Local LLM             Tool Calls
(Qwen/Llama/etc.)      Browser/MCP/etc.
      │
      ▼
 Response Text
      │
      ▼
 Kokoro TTS
      │
      ▼
 Natural Voice
      │
      ▼
 Telegram Voice Message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same response can be delivered as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text&lt;/li&gt;
&lt;li&gt;Voice&lt;/li&gt;
&lt;li&gt;Or both simultaneously&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why run locally?
&lt;/h2&gt;

&lt;p&gt;A local-first setup offers several advantages:&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy
&lt;/h3&gt;

&lt;p&gt;Sensitive conversations never leave your machine unless you explicitly enable external tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Zero inference cost
&lt;/h3&gt;

&lt;p&gt;After downloading the models, you no longer pay per request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Faster iteration
&lt;/h3&gt;

&lt;p&gt;Developers can test prompts, agents, and automations without worrying about API limits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Offline capability
&lt;/h3&gt;

&lt;p&gt;Useful for demos, labs, or environments with limited internet access.&lt;/p&gt;




&lt;h2&gt;
  
  
  Typical Setup
&lt;/h2&gt;

&lt;p&gt;A common local stack looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hermes Agent&lt;/li&gt;
&lt;li&gt;Ollama or another OpenAI-compatible local model server&lt;/li&gt;
&lt;li&gt;Kokoro TTS&lt;/li&gt;
&lt;li&gt;Telegram Gateway (optional)&lt;/li&gt;
&lt;li&gt;MCP servers&lt;/li&gt;
&lt;li&gt;Local memory and skills&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hermes can connect to local model servers such as Ollama, LM Studio, vLLM, llama.cpp, and other OpenAI-compatible endpoints.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Personal AI Assistant
&lt;/h3&gt;

&lt;p&gt;Ask questions and receive spoken replies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coding Agent
&lt;/h3&gt;

&lt;p&gt;Read repositories, execute tools, and explain code aloud.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customer Support Bot
&lt;/h3&gt;

&lt;p&gt;Generate text and voice responses without cloud inference costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Home Automation
&lt;/h3&gt;

&lt;p&gt;Control local services with voice feedback.&lt;/p&gt;

&lt;h3&gt;
  
  
  Content Creation
&lt;/h3&gt;

&lt;p&gt;Generate narration for tutorials, demos, podcasts, and videos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Research Assistant
&lt;/h3&gt;

&lt;p&gt;Summarise documents and listen instead of reading long reports.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pros
&lt;/h2&gt;

&lt;p&gt;✅ Local inference&lt;/p&gt;

&lt;p&gt;✅ Better privacy&lt;/p&gt;

&lt;p&gt;✅ No recurring API costs&lt;/p&gt;

&lt;p&gt;✅ Natural voice responses&lt;/p&gt;

&lt;p&gt;✅ Works with existing OpenAI-compatible APIs&lt;/p&gt;

&lt;p&gt;✅ Flexible model switching&lt;/p&gt;

&lt;p&gt;✅ Extensible through tools and skills&lt;/p&gt;




&lt;h2&gt;
  
  
  Cons
&lt;/h2&gt;

&lt;p&gt;❌ Requires decent CPU/GPU resources&lt;/p&gt;

&lt;p&gt;❌ Initial model downloads can be large&lt;/p&gt;

&lt;p&gt;❌ Local models may be slower than premium cloud models&lt;/p&gt;

&lt;p&gt;❌ Voice quality depends on the selected TTS model&lt;/p&gt;

&lt;p&gt;❌ Some external tools (web search, browser automation, cloud speech) still require internet access if enabled.&lt;/p&gt;




&lt;h2&gt;
  
  
  Who should use this?
&lt;/h2&gt;

&lt;p&gt;This setup is ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI developers&lt;/li&gt;
&lt;li&gt;Open-source enthusiasts&lt;/li&gt;
&lt;li&gt;Privacy-conscious users&lt;/li&gt;
&lt;li&gt;Local LLM experimentation&lt;/li&gt;
&lt;li&gt;Voice assistant projects&lt;/li&gt;
&lt;li&gt;Internal enterprise tooling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're already using MCP servers or self-hosted AI infrastructure, Hermes integrates naturally into that workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Hermes Agent combined with Kokoro TTS creates a surprisingly capable local AI assistant. Instead of just generating text, the system can reason, use tools, remember context, and respond with natural speech—all while keeping inference largely on your own machine.&lt;/p&gt;

&lt;p&gt;For developers building AI assistants, coding agents, research tools, or voice-enabled applications, this local-first stack offers an excellent balance between privacy, flexibility, and cost.&lt;/p&gt;

&lt;p&gt;After experimenting with it over the weekend, it's easy to see why local AI workflows are becoming increasingly practical. Cloud models still have their place for the hardest reasoning tasks, but for many day-to-day workflows, a local setup is already more than capable.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>llm</category>
      <category>opensource</category>
    </item>
    <item>
      <title>InsightsTrack + Pulse: I taught Claude Desktop to read my web analytics (via MCP)</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sun, 12 Jul 2026 15:01:53 +0000</pubDate>
      <link>https://dev.to/nishikantaray/insightstrack-pulse-i-taught-claude-desktop-to-read-my-web-analytics-via-mcp-13bd</link>
      <guid>https://dev.to/nishikantaray/insightstrack-pulse-i-taught-claude-desktop-to-read-my-web-analytics-via-mcp-13bd</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/weekend-2026-07-09"&gt;Weekend Challenge: Passion Edition&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;InsightsTrack&lt;/strong&gt; is a self-hosted, privacy-first web analytics platform — the open-source alternative to Google Analytics. No cookies, no consent banner, no data selling. You run it on your own server and get real-time visitors, funnels, heatmaps, Core Web Vitals, and 17+ analytics views.&lt;/p&gt;

&lt;p&gt;But the part I'm passionate about — and the reason I'm submitting it here — is &lt;strong&gt;Pulse&lt;/strong&gt;: a built-in &lt;strong&gt;AI analyst&lt;/strong&gt; that turns your analytics into a conversation.&lt;/p&gt;

&lt;p&gt;Instead of hunting through dashboards, you just &lt;strong&gt;ask&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"What were my top pages last week?"&lt;/em&gt;&lt;br&gt;
&lt;em&gt;"Where is my traffic coming from?"&lt;/em&gt;&lt;br&gt;
&lt;em&gt;"Where are users dropping off in the funnel?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pulse answers in plain English, with &lt;strong&gt;real charts, tables, and CSV exports&lt;/strong&gt; — every number backed by a live tool call, never hallucinated.&lt;/p&gt;

&lt;p&gt;And here's the passion project twist: Pulse isn't locked inside the dashboard. The &lt;strong&gt;same analytics tools are exposed over MCP (Model Context Protocol)&lt;/strong&gt;, so I can open &lt;strong&gt;Claude Desktop, Cursor, or any MCP client&lt;/strong&gt; and ask &lt;em&gt;it&lt;/em&gt; about my website traffic — and it queries InsightsTrack directly.&lt;/p&gt;

&lt;p&gt;My goal: &lt;strong&gt;make your own analytics as easy to query as sending a text message — and make that capability portable to every AI tool you already use.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🔗 Live app:&lt;/strong&gt; &lt;code&gt;https://insightstrack.dev&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;▶️ Video walkthrough:&lt;/strong&gt;  &lt;code&gt;https://youtu.be/LGZw8temtPY&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to show in the demo:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the dashboard, click &lt;strong&gt;Ask Pulse&lt;/strong&gt;, type &lt;em&gt;"top pages last 7 days"&lt;/em&gt; → watch it stream an answer + render a table with a &lt;strong&gt;CSV&lt;/strong&gt; button and an &lt;strong&gt;Open pages →&lt;/strong&gt; deep link.&lt;/li&gt;
&lt;li&gt;Switch the same result between &lt;strong&gt;table / bar / line / donut&lt;/strong&gt; with one click.&lt;/li&gt;
&lt;li&gt;Open &lt;strong&gt;Claude Desktop&lt;/strong&gt; → ask &lt;em&gt;"which sites do I have in InsightsTrack, and what's my top traffic source this month?"&lt;/em&gt; → it calls the MCP tools and answers with live data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwgqolbojsrfgik6mx6jj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwgqolbojsrfgik6mx6jj.png" alt="insightstracks" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/NishikantaRay/InsightTrack" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/InsightTrack&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/NishikantaRay" rel="noopener noreferrer"&gt;
        NishikantaRay
      &lt;/a&gt; / &lt;a href="https://github.com/NishikantaRay/InsightTrack" rel="noopener noreferrer"&gt;
        InsightTrack
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Self-hosted, privacy-first web analytics — the open-source alternative to Google Analytics
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;📊 InsightsTrack&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Self-hosted, privacy-first web analytics — the open-source alternative to Google Analytics&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/NishikantaRay/InsightTrack/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f43a51a164cf5f983be3c12a2c0ae6d92e5681ab465291ee1451bee73924d627/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4f70656e253230536f757263652d4d49542d363336366631" alt="Open Source"&gt;&lt;/a&gt;
&lt;a href=""&gt;&lt;img src="https://camo.githubusercontent.com/7ad148220f3c4c917ac675fc5994ff877426e174f08cf70e4c29ddad1cfa861a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53656c662d2d486f737465642d2545322539432539332d313062393831" alt="Self-Hosted"&gt;&lt;/a&gt;
&lt;a href=""&gt;&lt;img src="https://camo.githubusercontent.com/be3fd7535ed16cf4d4fc507342a2b1f744fc69d66daccd304a31c7027b988aa0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6f6b6965732d302d656634343434" alt="No Cookies"&gt;&lt;/a&gt;
&lt;a href=""&gt;&lt;img src="https://camo.githubusercontent.com/38e45558ae5f1311ea0e03fc6cb86079939a31f9fd8fd1bdf5aca997fc50a64c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f526561637425323031382532302543322542372532304578707265737325323034253230254332254237253230506f737467726553514c2532302543322542372532304475636b44422d316131643237" alt="Stack"&gt;&lt;/a&gt;
&lt;a href="https://github.com/sponsors/NishikantaRay" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/05d8c2ed8cfde259492aa9dd3bff228814b32829af1a581cc12ec43ea6a62d08/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f25453225393925413525323053706f6e736f722d4e697368696b616e74615261792d6561346161613f6c6f676f3d67697468756273706f6e736f7273" alt="Sponsor"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Track visitors, pageviews, conversions, heatmaps, and Core Web Vitals — all on your own server.&lt;/strong&gt;
No cookies, no consent banners, no data selling. Deploy in under 15 minutes.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/NishikantaRay/InsightTrack#-live-demo" rel="noopener noreferrer"&gt;Live Demo&lt;/a&gt; · &lt;a href="https://github.com/NishikantaRay/InsightTrack#-quick-start" rel="noopener noreferrer"&gt;Quick Start&lt;/a&gt; · &lt;a href="https://github.com/NishikantaRay/InsightTrack#-feature-walkthrough" rel="noopener noreferrer"&gt;Features&lt;/a&gt; · &lt;a href="https://github.com/NishikantaRay/InsightTrack#-deploy-your-own" rel="noopener noreferrer"&gt;Deploy&lt;/a&gt; · &lt;a href="https://github.com/NishikantaRay/InsightTrack/docs/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/NishikantaRay/InsightTrack/screenshots/11-dashboard-full.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FNishikantaRay%2FInsightTrack%2FHEAD%2Fscreenshots%2F11-dashboard-full.png" alt="InsightsTrack Dashboard"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What is InsightsTrack?&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;InsightsTrack is a complete, production-grade web analytics platform you run yourself. It gives you the depth of Google Analytics 4 — real-time visitors, traffic sources, funnels, heatmaps, Web Vitals — without sending a single byte of your visitors' data to a third party.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why teams choose it:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🔒 &lt;strong&gt;Privacy by design&lt;/strong&gt; — no cookies, no fingerprinting, anonymous visitor IDs, GDPR-compliant, DNT/GPC honored.&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;Fast at any scale&lt;/strong&gt; — a dual-database design (PostgreSQL for writes, DuckDB for reads) answers 90-day queries in under 100 ms even over millions of events.&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;Everything in one place&lt;/strong&gt; —…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/NishikantaRay/InsightTrack" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The parts most relevant to this submission:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MCP tool registry&lt;/strong&gt; — &lt;code&gt;analytics-db/src/mcp/tools/registry.js&lt;/code&gt; (17 read-only tools)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP protocol handler&lt;/strong&gt; (JSON-RPC 2.0, remote Streamable-HTTP transport) — &lt;code&gt;analytics-db/src/mcp/protocol.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The stdio bridge&lt;/strong&gt; for local clients — &lt;code&gt;mcp-server/src/index.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The AI loop + BYO-key provider layer&lt;/strong&gt; (Anthropic / OpenAI / Gemini) — &lt;code&gt;analytics-db/src/routes/assistant.js&lt;/code&gt; and &lt;code&gt;analytics-db/src/mcp/llm/provider.js&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsml3uqpbp6xivv3j6n23.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsml3uqpbp6xivv3j6n23.png" alt="insightstracks" width="799" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The dual-database core
&lt;/h3&gt;

&lt;p&gt;InsightsTrack writes every tracking event to &lt;strong&gt;PostgreSQL&lt;/strong&gt; and streams it into &lt;strong&gt;DuckDB&lt;/strong&gt;, an embedded columnar engine. All analytics &lt;em&gt;reads&lt;/em&gt; hit DuckDB — 90-day queries answer in tens of milliseconds, in-process, with no separate query cluster. Writes go to Postgres, reads come from DuckDB. That separation is what makes it fast &lt;em&gt;and&lt;/em&gt; cheap to self-host.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pulse: one tool registry, two front doors
&lt;/h3&gt;

&lt;p&gt;The interesting decision was &lt;strong&gt;not&lt;/strong&gt; building the AI assistant and the MCP integration as two separate things. There's &lt;strong&gt;one registry of 17 read-only tools&lt;/strong&gt; (&lt;code&gt;get_kpi&lt;/code&gt;, &lt;code&gt;get_top_pages&lt;/code&gt;, &lt;code&gt;get_funnel&lt;/code&gt;, &lt;code&gt;get_realtime&lt;/code&gt;, &lt;code&gt;list_sites&lt;/code&gt;, …). That single registry powers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The in-dashboard Pulse panel&lt;/strong&gt; — a streaming chat loop that lets an LLM call the tools and renders each result as a chart/table/KPI card.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP&lt;/strong&gt; — the exact same tools, exposed to external clients.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because both surfaces share the registry, an answer is consistent everywhere and I only maintain the tools once.&lt;/p&gt;

&lt;h3&gt;
  
  
  MCP: two transports
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiue392cu12z7v4ckqmmn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiue392cu12z7v4ckqmmn.png" alt="insightstracks" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the connector heart of the project. I implemented &lt;strong&gt;both&lt;/strong&gt; MCP transports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Remote (Streamable-HTTP)&lt;/strong&gt; — &lt;code&gt;POST /api/mcp/http&lt;/code&gt; speaks JSON-RPC 2.0 (&lt;code&gt;initialize&lt;/code&gt; / &lt;code&gt;tools/list&lt;/code&gt; / &lt;code&gt;tools/call&lt;/code&gt;). Clients that support remote MCP connect with just a URL + a bearer connect token. Nothing to install.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local (stdio bridge)&lt;/strong&gt; — a tiny &lt;code&gt;mcp-server&lt;/code&gt; process (the only place the real &lt;code&gt;@modelcontextprotocol/sdk&lt;/code&gt; is used) runs next to the client, speaks stdio, and &lt;strong&gt;proxies every call over HTTP to the API&lt;/strong&gt;. It never touches the database — which keeps per-user site scoping and DuckDB's single-writer lock intact.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Connect tokens are scoped JWTs (&lt;code&gt;scope: 'mcp'&lt;/code&gt;, with &lt;code&gt;jti&lt;/code&gt; so they can be revoked one-by-one), so a leaked token from one laptop can be killed without affecting others. All tools are &lt;strong&gt;read-only&lt;/strong&gt; — the AI can query but can never change or delete data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bring-your-own-key, encrypted at rest
&lt;/h3&gt;

&lt;p&gt;Pulse runs on &lt;strong&gt;your&lt;/strong&gt; model key — &lt;strong&gt;Anthropic (Claude), OpenAI (GPT), or Google (Gemini)&lt;/strong&gt;. Keys are stored &lt;strong&gt;AES-256-GCM encrypted&lt;/strong&gt; (dependency-free &lt;code&gt;node:crypto&lt;/code&gt;, key derived from the server secret) and &lt;strong&gt;never leave your server&lt;/strong&gt;. Precedence is BYO-key first, server key as fallback — so a self-hoster can either let every user bring their own, or set one server key so it "just works."&lt;/p&gt;

&lt;h3&gt;
  
  
  Result cards that do real work
&lt;/h3&gt;

&lt;p&gt;Every tool returns a structured envelope — &lt;code&gt;{ summary, data, render, download, deepLink }&lt;/code&gt;. The dashboard turns that into a card with a &lt;strong&gt;CSV export&lt;/strong&gt;, a &lt;strong&gt;view switcher&lt;/strong&gt; (table ↔ bar ↔ line ↔ donut, client-side, no re-query), and a &lt;strong&gt;deep link&lt;/strong&gt; to the matching dashboard page. Over MCP, the same envelope ships as &lt;code&gt;structuredContent&lt;/code&gt; so agent clients get the data too.&lt;/p&gt;

&lt;h3&gt;
  
  
  The honest hard part
&lt;/h3&gt;

&lt;p&gt;Getting Gemini to work over its OpenAI-compatible endpoint surfaced a subtle streaming bug: OpenAI streams tool-call arguments as &lt;em&gt;fragments to concatenate&lt;/em&gt;, but Gemini sends the &lt;em&gt;complete&lt;/em&gt; arguments object per delta (and sometimes repeats it) — naive concatenation produced invalid JSON like &lt;code&gt;{}{}&lt;/code&gt; that Gemini then rejected on the next round. The fix: if an incoming fragment is already valid JSON, treat it as the whole value instead of appending. One provider quirk, but it's the difference between "Gemini works" and a mysterious &lt;code&gt;INVALID_ARGUMENT&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Use of Google AI&lt;/strong&gt; — Pulse supports &lt;strong&gt;Google Gemini&lt;/strong&gt; as a first-class model provider for the AI analyst. Bring a Gemini API key in Settings and every plain-English question about your analytics is answered by Gemini calling InsightsTrack's 17 read-only tools — in the dashboard &lt;em&gt;and&lt;/em&gt; over MCP from Claude Desktop / Cursor.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with ❤️ as an open-source project. Try it, self-host it, or connect it to your favorite AI client. Feedback and stars welcome → &lt;a href="https://github.com/NishikantaRay/InsightTrack" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/InsightTrack&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How I Finally Finished InsightTrack — My Abandoned Self-Hosted Analytics Platform</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sun, 24 May 2026 04:04:23 +0000</pubDate>
      <link>https://dev.to/nishikantaray/how-i-finally-finished-insighttrack-my-abandoned-self-hosted-analytics-platform-1k7l</link>
      <guid>https://dev.to/nishikantaray/how-i-finally-finished-insighttrack-my-abandoned-self-hosted-analytics-platform-1k7l</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Project Details
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Name&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;InsightTrack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/nishikantaray/insighttrack" rel="noopener noreferrer"&gt;github.com/nishikantaray/insighttrack&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stack&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;React 18 · Vite 5 · Tailwind CSS · Express 4 · Node.js 20 · PostgreSQL · DuckDB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8pqgknn1i3ts4cjhjoh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8pqgknn1i3ts4cjhjoh.png" alt="Demo1" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2y6xjgmfuskdoj8qtw15.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2y6xjgmfuskdoj8qtw15.png" alt="Demo 2" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9pepz87hmrjv6eqn44z4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9pepz87hmrjv6eqn44z4.png" alt="Demo 3" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;InsightTrack&lt;/strong&gt; is a self-hosted, privacy-first web analytics platform — my personal answer to the question &lt;em&gt;"Why do I have to send all my users' data to Google just to know how many people visited my site?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It tracks pageviews, sessions, conversions, user flows, and engagement — all on your own infrastructure, with no cookies and no third-party data sharing. The architecture uses &lt;strong&gt;PostgreSQL&lt;/strong&gt; for all writes and &lt;strong&gt;DuckDB&lt;/strong&gt; as an embedded columnar OLAP engine for analytics reads, achieving 10-100× the query speed of a traditional row-store setup.&lt;/p&gt;

&lt;p&gt;I started InsightTrack during a long weekend when I was frustrated with the privacy implications of Google Analytics and the price tags on alternatives like Plausible and Fathom. The idea was simple: build a clean, self-hostable dashboard that you could drop a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag into and be live in 5 minutes.&lt;/p&gt;

&lt;p&gt;I got a working v1 out. It had a dashboard, auth, an onboarding wizard, basic charts, funnels, and a Docker Compose file that actually ran. Then I stopped. The project sat in a local folder for months — &lt;em&gt;almost&lt;/em&gt; good enough, but not quite. The DuckDB sync was fragile. There was no dark mode on half the pages. Dozens of planned features were never built. Query performance fell apart past 30 days of data.&lt;/p&gt;

&lt;p&gt;The bones were good. I just never gave it the finish it deserved.&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your Website
  └── analytics.js (tracking script, ~2 KB)
        │  POST /api/track/event
        ▼
  Express API (Node.js)
        │  Writes
        ▼
  PostgreSQL ──── Incremental sync worker (every 5 min)
                        │
                        ▼
                    DuckDB (OLAP reads)
                        │
                        ▼
  React Dashboard ◀─── GET /api/analytics/*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write path&lt;/strong&gt;: The tracking script sends events via &lt;code&gt;navigator.sendBeacon&lt;/code&gt;. Express validates and inserts into PostgreSQL. Response is immediate — DuckDB is never in the write path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sync path&lt;/strong&gt;: A high-watermark worker copies new rows from PostgreSQL → DuckDB incrementally, never rebuilding from scratch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read path&lt;/strong&gt;: All 17 analytics endpoints read exclusively from DuckDB, running columnar aggregations 10-100× faster than a row-store query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auth&lt;/strong&gt;: JWT-based authentication. All analytics routes are protected. Only &lt;code&gt;/api/track/*&lt;/code&gt; and &lt;code&gt;/api/auth/*&lt;/code&gt; are public.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  PostgreSQL schema (source of truth)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Table&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;events&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Raw event log — pageviews, clicks, custom events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sessions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Session metadata — duration, page count, entry/exit pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sites&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Registered websites and their tracking keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;funnels&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Funnel definitions with ordered steps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;daily_stats&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pre-aggregated daily rollups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;users&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Dashboard user accounts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Landing Page
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Hero&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkw2t7vzkbtijhdwjvlsp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkw2t7vzkbtijhdwjvlsp.png" alt="Landing Hero" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features Grid&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8l21mcdvr4j7zi3ivfnx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8l21mcdvr4j7zi3ivfnx.png" alt="Features" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How It Works&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foap45iuqis6ujvlkasn9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foap45iuqis6ujvlkasn9.png" alt="How It Works" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tech Stack&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft52r01nh3mxbbuj4fmcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft52r01nh3mxbbuj4fmcw.png" alt="Tech Stack" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comparison Table vs Google Analytics&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwpy1ryy0a98816pxq5v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwpy1ryy0a98816pxq5v.png" alt="Comparison Table" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Footer &amp;amp; CTA&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fym3hceny1k0o934zqc73.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fym3hceny1k0o934zqc73.png" alt="Footer" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;


Full landing page

![Full Landing Page](https://raw.githubusercontent.com/nishikantaray/insighttrack/main/screenshots/01-landing-full.png)




&lt;h3&gt;
  
  
  Authentication &amp;amp; Onboarding
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Login&lt;/th&gt;
&lt;th&gt;Register&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0bu26ruxxaqusgvqedbt.png" alt="Login" width="800" height="450"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxvyr24iw0dp2e4lfp8x.png" alt="Register" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr46a7h84a2b2miz96f6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr46a7h84a2b2miz96f6w.png" alt="Onboarding" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Dashboard
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Light Mode&lt;/th&gt;
&lt;th&gt;Dark Mode&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7krkfhpva4t6z2yyjllc.png" alt="Dashboard" width="800" height="1148"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fer8ump5czl04v5ru5p5j.png" alt="Dark Mode" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;KPI Cards + Sparklines&lt;/th&gt;
&lt;th&gt;Traffic Charts&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr3770w02ywq42ujps9s1.png" alt="KPI Cards" width="800" height="450"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8kgkhailbka92mlsca7i.png" alt="Charts" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxy8djxp7lebozsrgscuc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxy8djxp7lebozsrgscuc.png" alt="Dashboard Bottom — Countries &amp;amp; Funnels" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Analytics Pages
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;User Flow (Sankey)&lt;/th&gt;
&lt;th&gt;Real-Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxi2hkddv2a78mnn3t7mz.png" alt="User Flow" width="800" height="510"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdf3a5cdo9lvcz86x5wnp.png" alt="Realtime" width="800" height="626"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Funnels&lt;/th&gt;
&lt;th&gt;Settings&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatqioo3sgl1el5zhntf1.png" alt="Funnels" width="800" height="450"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvkm26u5ky261199vc2at.png" alt="Settings" width="800" height="622"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Top Pages&lt;/th&gt;
&lt;th&gt;Profile&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Favicp4al1j02d6ikuom4.png" alt="Pages" width="800" height="450"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fthgyzr9j880zt4daq048.png" alt="Profile" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Documentation&lt;/th&gt;
&lt;th&gt;API Reference&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4tiquur19quffgr0jpo.png" alt="Docs" width="800" height="972"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhbqrdakspgsfoqvxx629.png" alt="API Reference" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Sidebar&lt;/th&gt;
&lt;th&gt;Dark Landing&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnxma2pzbl85es1feck72.png" alt="Sidebar" width="260" height="720"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ndzbg1xwpqyu56c33ff.png" alt="Dark Landing" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; React 18 + Vite 5 + Tailwind CSS 3 · Express 4 + Node.js 20 · PostgreSQL + DuckDB · Docker Compose&lt;/p&gt;


&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Where it was (v1)
&lt;/h3&gt;

&lt;p&gt;v1 had the core loop working: embed a tracking script → events land in PostgreSQL → a sync worker copies rows into a flat DuckDB table → the React dashboard reads from DuckDB. The fundamental architecture was sound.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What v1 shipped:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dashboard with 4 KPI cards (Visitors, Pageviews, Bounce Rate, Avg. Session)&lt;/li&gt;
&lt;li&gt;Traffic and pageview time-series charts (7d / 30d / 90d presets)&lt;/li&gt;
&lt;li&gt;Top pages table&lt;/li&gt;
&lt;li&gt;Basic conversion funnels&lt;/li&gt;
&lt;li&gt;Device and country breakdown&lt;/li&gt;
&lt;li&gt;JWT authentication, register/login, onboarding wizard with tracking snippet&lt;/li&gt;
&lt;li&gt;Docker Compose deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it had serious rough edges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance wall.&lt;/strong&gt; The DuckDB sync layer used a single flat table. On 90+ days of data, a KPI query scanned every row — ~620 ms on a local M1 machine. There was no partitioning, no archival strategy, and a crash meant rebuilding the entire table from scratch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Half-finished features.&lt;/strong&gt; There was a long list of planned but never-built ideas: UTM campaign tracking, comparison mode on charts, user flow analysis, a live visitor map on the Realtime page, engagement tracking, goal tracking, audience analytics, export to CSV/JSON — all unshipped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UX gaps.&lt;/strong&gt; The Settings page was a single form. The Documentation page was a placeholder. Half the pages lacked dark mode. There was no contextual help anywhere — a new user landing on the Funnels page had no idea what they were looking at.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No marketing story.&lt;/strong&gt; The project had no landing page, no comparison table, no "why this instead of Google Analytics" pitch. It existed but didn't explain itself.&lt;/p&gt;


&lt;h3&gt;
  
  
  What changed (v1 → v2)
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1. Hot+Cold Analytics Architecture
&lt;/h4&gt;

&lt;p&gt;This was the most technically significant change. I replaced the flat DuckDB sync with a &lt;strong&gt;two-tier data lake&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hot tier&lt;/strong&gt; — DuckDB in-memory tables holding the last 30 days of events and sessions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cold tier&lt;/strong&gt; — Hive-partitioned Parquet files on disk for historical data, organized by &lt;code&gt;site_id&lt;/code&gt; and &lt;code&gt;event_date&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data-lake/events/
  site_id=abc/
    event_date=2026-01-01/
      part-0001.parquet
    event_date=2026-01-02/
      part-0001.parquet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A &lt;strong&gt;transparent &lt;code&gt;UNION ALL&lt;/code&gt; view&lt;/strong&gt; sits on top of both tiers, so every existing dashboard query kept working without modification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt; &lt;span class="k"&gt;VIEW&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;events_hot&lt;/span&gt;
  &lt;span class="k"&gt;UNION&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;read_parquet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'data-lake/events/site_id=*/event_date=*/part-0001.parquet'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;hive_partitioning&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;strong&gt;dual-watermark incremental sync worker&lt;/strong&gt; runs every 5 minutes, fetching only new rows from PostgreSQL using high-water marks (&lt;code&gt;last_event_id&lt;/code&gt; for events, &lt;code&gt;last_synced&lt;/code&gt; timestamp for sessions), then routing them to the correct tier based on age.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result: 90-day queries dropped from ~620 ms → ~25 ms. A 25× speedup.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recovery after a crash now resumes from the watermark instead of rebuilding the entire table.&lt;/p&gt;




&lt;h4&gt;
  
  
  2. Tracking Script — what it captures automatically
&lt;/h4&gt;

&lt;p&gt;The auto-generated &lt;code&gt;analytics.js&lt;/code&gt; (~2 KB) handles everything without configuration:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Data Point&lt;/th&gt;
&lt;th&gt;How&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Page URL &amp;amp; path&lt;/td&gt;
&lt;td&gt;&lt;code&gt;window.location.href&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Referrer&lt;/td&gt;
&lt;td&gt;&lt;code&gt;document.referrer&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser, OS, device&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;navigator.userAgent&lt;/code&gt; + screen width heuristics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Country&lt;/td&gt;
&lt;td&gt;Timezone via &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session&lt;/td&gt;
&lt;td&gt;Auto UUID in &lt;code&gt;sessionStorage&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anonymous user ID&lt;/td&gt;
&lt;td&gt;Random UUID in &lt;code&gt;localStorage&lt;/code&gt; — no cookies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Outbound link clicks&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;click&lt;/code&gt; event listener&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scroll depth&lt;/td&gt;
&lt;td&gt;25/50/75/100% milestones on page unload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time on page&lt;/td&gt;
&lt;td&gt;Seconds per page sent on unload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heatmap clicks&lt;/td&gt;
&lt;td&gt;x/y coordinates + CSS selector of every click&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rage clicks&lt;/td&gt;
&lt;td&gt;3+ rapid clicks on same element within 1 second&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Core Web Vitals&lt;/td&gt;
&lt;td&gt;LCP, FID, CLS, INP, TTFB via &lt;code&gt;PerformanceObserver&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JS errors&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;window.onerror&lt;/code&gt; + &lt;code&gt;unhandledrejection&lt;/code&gt; capture&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Site search&lt;/td&gt;
&lt;td&gt;Form submit interception&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UTM parameters&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;utm_source&lt;/code&gt;, &lt;code&gt;utm_medium&lt;/code&gt;, &lt;code&gt;utm_campaign&lt;/code&gt;, &lt;code&gt;utm_term&lt;/code&gt;, &lt;code&gt;utm_content&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SPA navigation&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;popstate&lt;/code&gt; + &lt;code&gt;pushState&lt;/code&gt; / &lt;code&gt;replaceState&lt;/code&gt; listeners&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Privacy built-in: DNT (&lt;code&gt;navigator.doNotTrack&lt;/code&gt;) and GPC (&lt;code&gt;navigator.globalPrivacyControl&lt;/code&gt;) are respected — if either is set, no data is collected.&lt;/p&gt;

&lt;p&gt;Custom events are available via &lt;code&gt;window.analytics.track('event_name', { ...properties })&lt;/code&gt;.&lt;/p&gt;




&lt;h4&gt;
  
  
  3. Complete v2 feature set
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Core Dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The main dashboard now has comparison mode — every chart can overlay the current period against the previous period. All 4 KPI cards have sparkline mini-charts. Date picker supports custom ranges in addition to presets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-Time&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Active visitor count (users in last 5 minutes, with pulsing indicator)&lt;/li&gt;
&lt;li&gt;Interactive world map pinpointing active visitors by country&lt;/li&gt;
&lt;li&gt;Live event stream — feed of the last 50–100 events as they happen&lt;/li&gt;
&lt;li&gt;Active pages ranked by current visitor count&lt;/li&gt;
&lt;li&gt;Real-time device breakdown&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Engagement Analytics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Four metrics measured automatically by the tracking script:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;What it shows&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scroll Depth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per-page average scroll %; milestone table (25/50/75/100%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Click Heatmaps&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;x/y dot map per page, top clicked elements ranked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rage Click Detection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pages and elements triggering 3+ rapid clicks within 1 second&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Time on Page&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Average, median, min/max read time per page&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;User Flow &amp;amp; Funnels&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sankey diagram showing entry pages → transitions → exit pages with proportional path thickness&lt;/li&gt;
&lt;li&gt;Multi-step funnel builder (e.g., Landing → Signup → Checkout → Purchase) with per-stage drop-off and conversion rate&lt;/li&gt;
&lt;li&gt;Saved funnel definitions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Conversion &amp;amp; Goals&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Goal types: Pageview (URL match), Event (custom event), Duration (time on page), Scroll Depth (threshold)&lt;/li&gt;
&lt;li&gt;A/B test tracking — create experiments, assign variants, compare conversion rates&lt;/li&gt;
&lt;li&gt;Revenue attribution — attach dollar values to purchase events, see total revenue and average order value by traffic source&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Audience Analytics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New vs. returning visitors — pie/donut chart + daily trend&lt;/li&gt;
&lt;li&gt;Cohort analysis — heatmap grid of Day 1 / Day 7 / Day 30 retention by first-visit week&lt;/li&gt;
&lt;li&gt;Visitor segments — filter by device, browser, OS, country and compare KPIs side by side&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Content Analytics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entry pages — top landing pages ranked by visitor count and entry rate&lt;/li&gt;
&lt;li&gt;Exit pages — top departure pages ranked by exit count and exit rate&lt;/li&gt;
&lt;li&gt;Page flow — where visitors go after each page&lt;/li&gt;
&lt;li&gt;Site search — queries captured from form submit interception with frequency counts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Acquisition Analytics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full UTM campaign dashboard — source, medium, campaign, term, content breakdowns with visitor counts, bounce rates, and session duration&lt;/li&gt;
&lt;li&gt;Social media tab — automatic classification of Facebook, Twitter/X, LinkedIn, Instagram, YouTube, Reddit, Pinterest, TikTok traffic&lt;/li&gt;
&lt;li&gt;Search keyword tracking — organic and paid keywords driving traffic&lt;/li&gt;
&lt;li&gt;UTM link builder — generate tagged URLs directly in the dashboard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Performance Monitoring&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Core Web Vitals collected automatically:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Good&lt;/th&gt;
&lt;th&gt;Needs Improvement&lt;/th&gt;
&lt;th&gt;Poor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;LCP&lt;/strong&gt; (Largest Contentful Paint)&lt;/td&gt;
&lt;td&gt;≤ 2.5s&lt;/td&gt;
&lt;td&gt;≤ 4.0s&lt;/td&gt;
&lt;td&gt;&amp;gt; 4.0s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;FID&lt;/strong&gt; (First Input Delay)&lt;/td&gt;
&lt;td&gt;≤ 100ms&lt;/td&gt;
&lt;td&gt;≤ 300ms&lt;/td&gt;
&lt;td&gt;&amp;gt; 300ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;CLS&lt;/strong&gt; (Cumulative Layout Shift)&lt;/td&gt;
&lt;td&gt;≤ 0.1&lt;/td&gt;
&lt;td&gt;≤ 0.25&lt;/td&gt;
&lt;td&gt;&amp;gt; 0.25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;INP&lt;/strong&gt; (Interaction to Next Paint)&lt;/td&gt;
&lt;td&gt;≤ 200ms&lt;/td&gt;
&lt;td&gt;≤ 500ms&lt;/td&gt;
&lt;td&gt;&amp;gt; 500ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;TTFB&lt;/strong&gt; (Time to First Byte)&lt;/td&gt;
&lt;td&gt;≤ 800ms&lt;/td&gt;
&lt;td&gt;≤ 1800ms&lt;/td&gt;
&lt;td&gt;&amp;gt; 1800ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Color-coded metric cards (green/yellow/red) + per-page breakdown table.&lt;/p&gt;

&lt;p&gt;JavaScript error tracking: message, source file, line/column, stack trace, error trend chart over time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reporting &amp;amp; Export&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data export — JSON/CSV download for KPI, traffic, pages, sources data; PNG export for charts&lt;/li&gt;
&lt;li&gt;Annotations — pin notes to specific dates on charts (e.g., "launched new homepage") with category badges (deployment/marketing/incident)&lt;/li&gt;
&lt;li&gt;Scheduled reports — configure daily/weekly/monthly email delivery with recipient list&lt;/li&gt;
&lt;li&gt;Custom dashboards — save personalized widget layouts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Multi-Site Management&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add and manage unlimited websites under one account&lt;/li&gt;
&lt;li&gt;Per-site tracking snippets with one-click copy&lt;/li&gt;
&lt;li&gt;Per-site data retention policies (30/90/180/365 days)&lt;/li&gt;
&lt;li&gt;Automated cleanup of expired events and sessions&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  4. UX and documentation overhaul
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Settings page&lt;/strong&gt; rebuilt as a 4-tab layout: General, Notifications/Alerts, Site Manager, and Privacy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All 13 analytics pages&lt;/strong&gt; gained a collapsible &lt;code&gt;PageNote&lt;/code&gt; banner with a business explanation and a developer tip per page&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;InfoTooltip&lt;/code&gt;&lt;/strong&gt; on every &lt;code&gt;MetricCard&lt;/code&gt; and &lt;code&gt;ChartCard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation page&lt;/strong&gt; rebuilt with dual-audience tabs (Business Owner / Developer) and an interactive 4-view architecture diagram&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dark mode&lt;/strong&gt; enforced consistently across every page and component&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  5. Marketing landing page
&lt;/h4&gt;

&lt;p&gt;Hero, features grid, 3-step "How It Works", tech stack cards, and a side-by-side comparison table vs. Google Analytics across 9 dimensions.&lt;/p&gt;




&lt;h3&gt;
  
  
  Before vs. After
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;v1 (Before)&lt;/th&gt;
&lt;th&gt;v2 (After)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;90-day query time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~620 ms&lt;/td&gt;
&lt;td&gt;~25 ms (25×)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DuckDB architecture&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single flat table, full scan&lt;/td&gt;
&lt;td&gt;Hot (in-memory) + Cold (Parquet), UNION view&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sync on crash&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full table rebuild&lt;/td&gt;
&lt;td&gt;Resumes from dual watermark&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Analytics pages&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tracking data points&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Real-Time page&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Active count only&lt;/td&gt;
&lt;td&gt;Map + event stream + device breakdown&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Engagement tracking&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Scroll depth, heatmaps, rage clicks, time on page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Conversion &amp;amp; Goals&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Funnels only&lt;/td&gt;
&lt;td&gt;Goals, A/B testing, revenue attribution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Audience analytics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;New/returning, cohorts, segments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Content analytics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Top pages only&lt;/td&gt;
&lt;td&gt;Entry/exit pages, page flow, site search&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Acquisition analytics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;UTM campaigns, social, keywords, link builder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance monitoring&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Core Web Vitals + JS error tracking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reporting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Export, annotations, scheduled reports, custom dashboards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multi-site&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single site&lt;/td&gt;
&lt;td&gt;Unlimited sites with per-site settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Comparison mode&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Previous-period overlay on all charts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Export&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;CSV / JSON / PNG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Settings page&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single form&lt;/td&gt;
&lt;td&gt;4-tab layout with site manager&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Contextual help&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PageNote&lt;/code&gt; + &lt;code&gt;InfoTooltip&lt;/code&gt; on every page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dark mode coverage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Complete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Marketing landing page&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Full page with comparison table&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;I'll be direct: I would not have shipped v2 without GitHub Copilot. Not because the individual problems were too hard — but because there were &lt;em&gt;so many&lt;/em&gt; of them, and I was coming back to code I hadn't touched in months.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The architecture lift.&lt;/strong&gt; The Hot+Cold DuckDB design required a new sync worker, new schema migrations, new UNION views, and updates to every existing query file simultaneously. Copilot helped me work through design decisions conversationally — I'd describe the constraint ("crash recovery must resume from a watermark, not rebuild the whole table") and it would walk me through the dual-watermark pattern, flag edge cases I hadn't considered (what happens to a row that ages from hot to cold &lt;em&gt;between&lt;/em&gt; two sync cycles?), and generate the implementation that fit the existing codebase style.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The feature sweep.&lt;/strong&gt; Going from 8 tracked data points to 19, from 7 pages to 13, from basic funnels to engagement tracking, cohort analysis, Web Vitals, and revenue attribution is a context-switching marathon. Copilot compressed the ramp-up time on each feature dramatically. When I opened the Acquisition page for the first time in months, Copilot immediately understood the existing data model, knew which UTM fields were already being captured in the tracking script, and scaffolded the campaign dashboard components that matched the existing &lt;code&gt;useAnalytics&lt;/code&gt; hook pattern — not generic code, but code that fit &lt;em&gt;this&lt;/em&gt; project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The consistency work.&lt;/strong&gt; The &lt;code&gt;PageNote&lt;/code&gt; and &lt;code&gt;InfoTooltip&lt;/code&gt; additions touched 13 pages. Adding Core Web Vitals collection to the tracking script required coordinating between &lt;code&gt;analytics.js&lt;/code&gt;, the Express ingest route, the DuckDB schema, and the React performance page — four files that had to stay in sync. Copilot held the full context across all of them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The documentation.&lt;/strong&gt; Writing accurate technical docs for a system you know deeply is surprisingly tedious. Copilot drafted the architecture document for the hot/cold system from the actual code — referencing the real SQL, the real file paths, the real config variables — and I edited for clarity rather than writing from scratch.&lt;/p&gt;

&lt;p&gt;The interaction style that worked best wasn't "write this for me." It was: &lt;em&gt;here's the constraint, here's the existing pattern, here's where I'm confused.&lt;/em&gt; Copilot as a collaborator who has read your entire codebase is a genuinely different experience from Copilot as autocomplete. The finish-up phase of a project — juggling context across a dozen half-done things — is exactly where that kind of always-available, always-context-aware pair programmer pays off most.&lt;/p&gt;

&lt;p&gt;InsightTrack v2 is the project I always meant to ship. It just needed time, a clear plan, and a better way to work through the backlog.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;InsightTrack is open source — self-host your own privacy-first analytics in minutes.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
    </item>
    <item>
      <title>SwiftCut: AI-Powered Video Silence Remover Built with GitHub Copilot CLI</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Mon, 26 Jan 2026 16:46:06 +0000</pubDate>
      <link>https://dev.to/nishikantaray/swiftcut-ai-powered-video-silence-remover-built-with-github-copilot-cli-3dj7</link>
      <guid>https://dev.to/nishikantaray/swiftcut-ai-powered-video-silence-remover-built-with-github-copilot-cli-3dj7</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-01-21"&gt;GitHub Copilot CLI Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;SwiftCut&lt;/strong&gt; is a local-first desktop application that automates the "Rough Cut" phase of video editing. It uses AI-powered audio analysis to instantly detect and remove silent segments from videos — no cloud uploads, no subscriptions, complete privacy.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem I Solved
&lt;/h3&gt;

&lt;p&gt;As a content creator, I spent &lt;strong&gt;hours&lt;/strong&gt; manually cutting out silent pauses from my podcast recordings, tutorial videos, and vlogs. The workflow was:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Import video into heavy editing software&lt;/li&gt;
&lt;li&gt;Scrub through timeline looking for silence&lt;/li&gt;
&lt;li&gt;Manually mark and delete each silent segment&lt;/li&gt;
&lt;li&gt;Repeat 50+ times per video 😩&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;SwiftCut automates this entire process in seconds.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;p&gt;🎯 &lt;strong&gt;Smart Silence Detection&lt;/strong&gt; — FFmpeg-powered audio analysis with configurable thresholds&lt;/p&gt;

&lt;p&gt;⚡ &lt;strong&gt;Instant Results&lt;/strong&gt; — Process a 10-minute video in under 5 seconds&lt;/p&gt;

&lt;p&gt;🔒 &lt;strong&gt;100% Local &amp;amp; Private&lt;/strong&gt; — Your videos never leave your machine&lt;/p&gt;

&lt;p&gt;🎚️ &lt;strong&gt;Content Presets&lt;/strong&gt; — Optimized settings for Podcasts, Tutorials, Vlogs, and Interviews&lt;/p&gt;

&lt;p&gt;🤖 &lt;strong&gt;AI Natural Language Commands&lt;/strong&gt; — Tell it what to do: "Remove all silences" or "Make a 30-second clip"&lt;/p&gt;

&lt;p&gt;🎬 &lt;strong&gt;Reel Cutter&lt;/strong&gt; — Split long videos into Instagram Reels, TikTok, or YouTube Shorts&lt;/p&gt;

&lt;p&gt;🎙️ &lt;strong&gt;Voice Commands&lt;/strong&gt; — Speak your edits using Web Speech API&lt;/p&gt;

&lt;p&gt;↩️ &lt;strong&gt;Full Undo/Redo&lt;/strong&gt; — Never lose your work&lt;/p&gt;

&lt;h3&gt;
  
  
  Tech Stack
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Framework&lt;/td&gt;
&lt;td&gt;Tauri v2 (Rust + WebView)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;React 19 + TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Styling&lt;/td&gt;
&lt;td&gt;Tailwind CSS v4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;State&lt;/td&gt;
&lt;td&gt;Zustand&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Video Processing&lt;/td&gt;
&lt;td&gt;FFmpeg&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI&lt;/td&gt;
&lt;td&gt;Multi-provider (Local, Ollama, OpenAI, Copilot SDK)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🎥 Video Walkthrough
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://youtu.be/tXmQofWy3P0?si=X1xxPl8yD-OTNM1M" rel="noopener noreferrer"&gt;▶️ Watch SwiftCut in Action&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Landing Page — Clean, focused interface&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7p6sijgqlmb1um65tw1v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7p6sijgqlmb1um65tw1v.png" alt=" " width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Silence Detection — Visual timeline with detected segments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F12zoawijn8e79536ulow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F12zoawijn8e79536ulow.png" alt=" " width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI Commands — Natural language video editing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcd8gmq3asfv7sd48vk7i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcd8gmq3asfv7sd48vk7i.png" alt=" " width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0463o53wwnkhiceye3ht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0463o53wwnkhiceye3ht.png" alt=" " width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reel Cutter — Split videos for social media&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Floh6prfy1tckb2l8ko5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Floh6prfy1tckb2l8ko5z.png" alt=" " width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Try It Yourself
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone the repo&lt;/span&gt;
git clone https://github.com/yourusername/swiftcut.git
&lt;span class="nb"&gt;cd &lt;/span&gt;swiftcut

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Run in development&lt;/span&gt;
npm run tauri dev

&lt;span class="c"&gt;# Build for production&lt;/span&gt;
npm run tauri:build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt; Node.js 22+, Rust 1.93+, FFmpeg&lt;/p&gt;




&lt;h2&gt;
  
  
  My Experience with GitHub Copilot CLI
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How Copilot CLI Transformed My Development
&lt;/h3&gt;

&lt;p&gt;Building SwiftCut would have taken &lt;strong&gt;weeks&lt;/strong&gt; without GitHub Copilot CLI. Here's how I used it:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;FFmpeg Command Generation&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;FFmpeg has notoriously complex syntax. Instead of Googling for hours, I asked Copilot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"ffmpeg command to detect silence below -30dB lasting more than 0.5 seconds"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; input.mp4 &lt;span class="nt"&gt;-af&lt;/span&gt; &lt;span class="s2"&gt;"silencedetect=noise=-30dB:d=0.5"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; null -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This became the core of my silence detection algorithm.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Rust Backend Development&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;I'm primarily a TypeScript developer. Writing Rust for Tauri was daunting, but Copilot CLI helped:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot explain &lt;span class="s2"&gt;"how to parse FFmpeg stderr output in Rust and extract timestamps"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It gave me a complete regex pattern and parsing logic that I adapted for my &lt;code&gt;lib.rs&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Complex Filter Chains&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Building the export filter was tricky. I needed to keep non-silent segments and remove gaps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"ffmpeg select filter to keep multiple time ranges and close gaps"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;-vf&lt;/span&gt; &lt;span class="s2"&gt;"select='between(t,0,5)+between(t,8,20)',setpts=N/FRAME_RATE/TB"&lt;/span&gt;
&lt;span class="nt"&gt;-af&lt;/span&gt; &lt;span class="s2"&gt;"aselect='between(t,0,5)+between(t,8,20)',asetpts=N/SR/TB"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. &lt;strong&gt;AI Planner System Prompt&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;I used Copilot to help design the system prompt for my AI planner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"system prompt for an AI that converts natural language to FFmpeg commands"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helped me structure the &lt;code&gt;SWIFTCUT_SYSTEM_PROMPT&lt;/code&gt; that powers the natural language interface.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. &lt;strong&gt;Cross-Platform Build Configuration&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Setting up GitHub Actions for multi-platform builds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"github actions workflow to build tauri app for mac windows and linux"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Got a working CI/CD pipeline in minutes instead of hours.&lt;/p&gt;

&lt;h3&gt;
  
  
  Impact on Development Experience
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Without Copilot CLI&lt;/th&gt;
&lt;th&gt;With Copilot CLI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FFmpeg learning curve&lt;/td&gt;
&lt;td&gt;2-3 days&lt;/td&gt;
&lt;td&gt;2 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust backend&lt;/td&gt;
&lt;td&gt;1 week&lt;/td&gt;
&lt;td&gt;2 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total development time&lt;/td&gt;
&lt;td&gt;~3 weeks&lt;/td&gt;
&lt;td&gt;~5 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stack Overflow visits&lt;/td&gt;
&lt;td&gt;100+&lt;/td&gt;
&lt;td&gt;~10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The "Aha!" Moment
&lt;/h3&gt;

&lt;p&gt;The breakthrough came when I realized I could use Copilot CLI as a &lt;strong&gt;planning agent&lt;/strong&gt; within the app itself. The system prompt I developed with Copilot's help now powers SwiftCut's AI command interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "Remove all silences longer than 1 second"
     ↓
AI Planner (Copilot-inspired prompt)
     ↓
FFmpeg: select='between(t,0,5)+between(t,8,20)...'
     ↓
Exported video with silences removed!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What I'd Tell Other Developers
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Don't just ask for code&lt;/strong&gt; — Ask Copilot CLI to &lt;em&gt;explain&lt;/em&gt; concepts first&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;suggest&lt;/code&gt; for commands&lt;/strong&gt; — Especially for complex CLI tools like FFmpeg, Docker, Git&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iterate with &lt;code&gt;explain&lt;/code&gt;&lt;/strong&gt; — If the first suggestion isn't perfect, ask it to explain and refine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build your own prompts&lt;/strong&gt; — The system prompts Copilot uses are great templates for your AI features&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Technical Deep Dive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How Silence Detection Works
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ORIGINAL VIDEO (10 minutes)
▓▓▓▓▓░░░▓▓▓▓▓▓▓░░▓▓▓▓░░░░▓▓▓▓▓▓▓▓░░▓▓▓▓▓▓░░░▓▓▓▓▓
     ▲       ▲       ▲           ▲         ▲
  silence silence silence    silence   silence

                    ↓ FFmpeg silencedetect

EXPORTED VIDEO (7 minutes)  
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
(All silence removed — 30% shorter!)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  AI Provider Architecture
&lt;/h3&gt;

&lt;p&gt;SwiftCut supports multiple AI backends:&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AIProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;local&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;copilot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ollama&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;openai&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Switch providers in settings&lt;/span&gt;
&lt;span class="nf"&gt;setAIProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ollama&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:11434&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;modelName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;llama3.2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Local&lt;/td&gt;
&lt;td&gt;Offline, rule-based processing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ollama&lt;/td&gt;
&lt;td&gt;Privacy-focused local LLM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;Most capable, requires API key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copilot SDK&lt;/td&gt;
&lt;td&gt;Coming soon!&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Waveform visualization in timeline&lt;/li&gt;
&lt;li&gt;[ ] Transcript-based editing ("Find where I say 'demo'")&lt;/li&gt;
&lt;li&gt;[ ] Batch processing multiple videos&lt;/li&gt;
&lt;li&gt;[ ] Plugin system for custom filters&lt;/li&gt;
&lt;li&gt;[ ] Mobile companion app&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/NishikantaRay/swiftcut" rel="noopener noreferrer"&gt;github.com/NishikantaRay/swiftcut&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📺 &lt;strong&gt;Demo Video:&lt;/strong&gt; &lt;a href="https://youtu.be/tXmQofWy3P0" rel="noopener noreferrer"&gt;youtube.com/watch?v=tXmQofWy3P0&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Acknowledgments
&lt;/h2&gt;

&lt;p&gt;Built with ❤️ using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://tauri.app" rel="noopener noreferrer"&gt;Tauri&lt;/a&gt; — Amazing desktop framework&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ffmpeg.org" rel="noopener noreferrer"&gt;FFmpeg&lt;/a&gt; — The backbone of video processing&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://githubnext.com/projects/copilot-cli" rel="noopener noreferrer"&gt;GitHub Copilot CLI&lt;/a&gt; — My AI pair programmer&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;What editing task takes you the longest? Let me know in the comments — maybe SwiftCut can help!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>cli</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>From Static to Smart: Designing an AI-First Developer Portfolio with Renderer, Gemini &amp; MCP 🚀🚀</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Thu, 22 Jan 2026 18:16:15 +0000</pubDate>
      <link>https://dev.to/nishikantaray/from-static-to-smart-designing-an-ai-first-developer-portfolio-with-renderer-gemini-mcp-1kd1</link>
      <guid>https://dev.to/nishikantaray/from-static-to-smart-designing-an-ai-first-developer-portfolio-with-renderer-gemini-mcp-1kd1</guid>
      <description>&lt;p&gt;&lt;em&gt;Transforming portfolio creation with Google Gemini AI and Model Context Protocol&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F00jl8rfvdcgxhwhnodmn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F00jl8rfvdcgxhwhnodmn.png" alt="Home page of renderer" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=Txzplqg6oJo" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=Txzplqg6oJo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Executive Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Renderer&lt;/strong&gt; is an innovative portfolio framework that leverages &lt;strong&gt;Google Gemini&lt;/strong&gt; to revolutionize how developers create and manage their online presence. By combining a configuration-first architecture with AI assistance through Model Context Protocol (MCP), users can generate, validate, and customize complete portfolios using natural language.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Innovation
&lt;/h3&gt;

&lt;p&gt;Instead of wrestling with complex frameworks, users simply describe what they want, and Gemini handles the technical complexity—generating configurations, validating code, and providing instant guidance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fknhq0bnalvz3vzrited0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fknhq0bnalvz3vzrited0.png" alt="Renderer Docs Home page" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Live Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🌐 Live Portfolio: &lt;a href="https://nishikanta.in" rel="noopener noreferrer"&gt;https://nishikanta.in&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📚 Documentation: &lt;a href="https://renderer.nishikanta.in/docs" rel="noopener noreferrer"&gt;https://renderer.nishikanta.in/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 Framework: &lt;a href="https://github.com/NishikantaRay/renderer" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/renderer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🤖 MCP Server: &lt;a href="https://github.com/NishikantaRay/renderer-mcp-server" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/renderer-mcp-server&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎯 Problem &amp;amp; Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;Developers face critical pain points when building portfolios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚠️ &lt;strong&gt;Framework Overload&lt;/strong&gt; - Complex React/Vue setups with heavy build processes&lt;/li&gt;
&lt;li&gt;⏰ &lt;strong&gt;Time Investment&lt;/strong&gt; - Hours configuring, styling, and maintaining&lt;/li&gt;
&lt;li&gt;🔒 &lt;strong&gt;Limited Flexibility&lt;/strong&gt; - Templates that don't adapt to individual needs&lt;/li&gt;
&lt;li&gt;📚 &lt;strong&gt;Documentation Fatigue&lt;/strong&gt; - Searching through endless docs for simple changes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Our Solution
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;static, configuration-driven framework&lt;/strong&gt; enhanced by &lt;strong&gt;Google Gemini AI&lt;/strong&gt; that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Generates complete portfolio configurations from natural language&lt;/li&gt;
&lt;li&gt;✅ Validates TOML files and catches errors instantly&lt;/li&gt;
&lt;li&gt;✅ Provides contextual documentation and examples&lt;/li&gt;
&lt;li&gt;✅ Reduces setup time from hours to minutes&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Google Gemini Integration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dual-Layer AI Architecture
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Gemini AI Studio&lt;/strong&gt; (Ideation &amp;amp; Content Creation)
&lt;/h4&gt;

&lt;p&gt;Used during initial development for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📝 Outlining portfolio structure and sections&lt;/li&gt;
&lt;li&gt;✍️ Drafting About, Resume, and project descriptions&lt;/li&gt;
&lt;li&gt;🎨 Suggesting design patterns and layouts&lt;/li&gt;
&lt;li&gt;🔄 Converting raw notes into polished copy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why Gemini:&lt;/strong&gt; Its advanced reasoning capabilities helped transform technical achievements into compelling narratives.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Gemini CLI&lt;/strong&gt; (Development Workflow)
&lt;/h4&gt;

&lt;p&gt;Terminal-native AI for rapid development:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Generate configuration files&lt;/span&gt;
gemini &lt;span class="s2"&gt;"Create a resume.toml with experience and education sections"&lt;/span&gt;

&lt;span class="c"&gt;# Content refinement&lt;/span&gt;
gemini &lt;span class="s2"&gt;"Rewrite this Markdown to be more technical and concise"&lt;/span&gt;

&lt;span class="c"&gt;# Validation&lt;/span&gt;
gemini &lt;span class="s2"&gt;"Check this TOML file for schema errors"&lt;/span&gt;

&lt;span class="c"&gt;# Documentation&lt;/span&gt;
gemini &lt;span class="s2"&gt;"Explain how to add dark mode to my portfolio"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Advantage:&lt;/strong&gt; Seamlessly integrates with Git-based workflows and plain-text files.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Model Context Protocol (MCP) Server&lt;/strong&gt; (AI Assistant)
&lt;/h4&gt;

&lt;p&gt;Our breakthrough innovation—a persistent AI assistant that &lt;strong&gt;understands Renderer's architecture&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP Server Capabilities:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔍 &lt;strong&gt;Semantic Documentation Search&lt;/strong&gt; - Find answers in natural language&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Real-time TOML Validation&lt;/strong&gt; - Catch errors before deployment&lt;/li&gt;
&lt;li&gt;🎨 &lt;strong&gt;Template Generation&lt;/strong&gt; - Create complete configs from user input&lt;/li&gt;
&lt;li&gt;💡 &lt;strong&gt;Smart Examples&lt;/strong&gt; - Context-aware code snippets&lt;/li&gt;
&lt;li&gt;🗂️ &lt;strong&gt;Repository Navigation&lt;/strong&gt; - Browse and understand file structure&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏗️ Technical Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Core System
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Renderer Framework
├── Configuration Layer (TOML)      # Human &amp;amp; AI readable
├── Content Layer (Markdown)        # Plain text documents
├── Presentation Layer (HTML/CSS/JS) # Vanilla web tech
└── AI Layer (Gemini + MCP)        # Intelligent assistance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why This Stack Works
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Configuration-Driven Design:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TOML files are both human and AI readable&lt;/li&gt;
&lt;li&gt;No framework abstractions—pure data&lt;/li&gt;
&lt;li&gt;Version control friendly&lt;/li&gt;
&lt;li&gt;Deterministic output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Static-First Approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero build process&lt;/li&gt;
&lt;li&gt;Instant deployment&lt;/li&gt;
&lt;li&gt;Maximum performance&lt;/li&gt;
&lt;li&gt;No server dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;AI-Assistable Architecture:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every file is structured and parseable&lt;/li&gt;
&lt;li&gt;Clear separation of concerns&lt;/li&gt;
&lt;li&gt;Predictable patterns for AI reasoning&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxeu0bez8xorv59hg9k4o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxeu0bez8xorv59hg9k4o.png" alt="Resume Section" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2d4vpaoxylkfdv492hc0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2d4vpaoxylkfdv492hc0.png" alt="Projects Section" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🤖 MCP Server Deep Dive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Renderer&lt;/span&gt; &lt;span class="nx"&gt;MCP&lt;/span&gt; &lt;span class="nx"&gt;Server&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;GitHub&lt;/span&gt; &lt;span class="nx"&gt;Integration&lt;/span&gt;          &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Access&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;framework&lt;/span&gt; &lt;span class="nx"&gt;repository&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;Documentation&lt;/span&gt; &lt;span class="nx"&gt;Engine&lt;/span&gt;        &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Semantic&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt; &lt;span class="nx"&gt;across&lt;/span&gt; &lt;span class="nx"&gt;docs&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;TOML&lt;/span&gt; &lt;span class="nx"&gt;Validator&lt;/span&gt;             &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Schema&lt;/span&gt; &lt;span class="nx"&gt;validation&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt; &lt;span class="nx"&gt;Generator&lt;/span&gt;         &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Config&lt;/span&gt; &lt;span class="nx"&gt;creation&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;Example&lt;/span&gt; &lt;span class="nx"&gt;Provider&lt;/span&gt;           &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Contextual&lt;/span&gt; &lt;span class="nx"&gt;snippets&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;Feature&lt;/span&gt; &lt;span class="nx"&gt;Search&lt;/span&gt;             &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Capability&lt;/span&gt; &lt;span class="nx"&gt;discovery&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Available Tools
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;explore_renderer_docs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Natural language documentation queries&lt;/li&gt;
&lt;li&gt;Returns relevant sections with examples&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;validate_toml_config&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Schema validation&lt;/li&gt;
&lt;li&gt;Syntax checking&lt;/li&gt;
&lt;li&gt;Improvement suggestions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;generate_starter_template&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete project scaffolding&lt;/li&gt;
&lt;li&gt;Customized to user needs&lt;/li&gt;
&lt;li&gt;Ready-to-deploy configurations&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;get_config_example&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Annotated configuration samples&lt;/li&gt;
&lt;li&gt;Context-aware suggestions&lt;/li&gt;
&lt;li&gt;Best practices included&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;search_renderer_features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feature discovery&lt;/li&gt;
&lt;li&gt;Implementation guides&lt;/li&gt;
&lt;li&gt;Integration examples&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Setup &amp;amp; Usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install globally&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; renderer-mcp-server

&lt;span class="c"&gt;# Use with Gemini CLI for AI assistance&lt;/span&gt;
gemini &lt;span class="s2"&gt;"Generate a portfolio configuration for John Doe with projects, resume, and blog"&lt;/span&gt;

&lt;span class="c"&gt;# Or integrate with any MCP-compatible client&lt;/span&gt;
&lt;span class="c"&gt;# The MCP server works with Google AI Studio API and Gemini models&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  💡 Real-World Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Case 1: Rapid Portfolio Generation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; "I need a portfolio showcasing 5 projects, my resume, and a contact form"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemini + MCP Response:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generates complete &lt;code&gt;projects.toml&lt;/code&gt; with 5 project templates&lt;/li&gt;
&lt;li&gt;Creates &lt;code&gt;resume.toml&lt;/code&gt; with standard sections&lt;/li&gt;
&lt;li&gt;Configures &lt;code&gt;contact.html&lt;/code&gt; with form validation&lt;/li&gt;
&lt;li&gt;Provides deployment instructions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time saved:&lt;/strong&gt; 2-3 hours → 10 minutes&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Use Case 2: Configuration Validation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; Uploads existing &lt;code&gt;home.toml&lt;/code&gt; file&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP Server:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Validates syntax&lt;/li&gt;
&lt;li&gt;⚠️ Identifies missing required fields&lt;/li&gt;
&lt;li&gt;💡 Suggests improvements&lt;/li&gt;
&lt;li&gt;📚 Links to relevant documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Case 3: Feature Discovery
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; "How do I add analytics dashboard to my projects page?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemini Response:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[analytics]&lt;/span&gt;
&lt;span class="py"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Project Analytics"&lt;/span&gt;

&lt;span class="nn"&gt;[analytics.charts]&lt;/span&gt;
&lt;span class="py"&gt;weekly_activity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;project_distribution&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plus step-by-step integration guide.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Impact &amp;amp; Results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Quantifiable Improvements
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Setup Time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4-6 hours&lt;/td&gt;
&lt;td&gt;15-20 minutes&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;85% reduction&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Configuration Errors&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Common&lt;/td&gt;
&lt;td&gt;Prevented&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~90% reduction&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Documentation Search&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10-15 minutes&lt;/td&gt;
&lt;td&gt;Instant&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Near-instant&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Portfolio Updates&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;30-45 minutes&lt;/td&gt;
&lt;td&gt;5 minutes&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;83% faster&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  User Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🚀 &lt;strong&gt;Developers:&lt;/strong&gt; Focus on content, not configuration&lt;/li&gt;
&lt;li&gt;🎨 &lt;strong&gt;Designers:&lt;/strong&gt; Easy customization without code&lt;/li&gt;
&lt;li&gt;📚 &lt;strong&gt;Students:&lt;/strong&gt; Professional portfolios in minutes&lt;/li&gt;
&lt;li&gt;💼 &lt;strong&gt;Professionals:&lt;/strong&gt; Maintain portfolios effortlessly&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🌟 Key Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Portfolio Capabilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔧 &lt;strong&gt;Fully Configurable&lt;/strong&gt; - Every aspect controlled via TOML&lt;/li&gt;
&lt;li&gt;📄 &lt;strong&gt;Multi-Page Support&lt;/strong&gt; - Home, Projects, Blog, Resume, Contact, Docs&lt;/li&gt;
&lt;li&gt;🌙 &lt;strong&gt;Dark/Light Theme&lt;/strong&gt; - Automatic detection + manual toggle&lt;/li&gt;
&lt;li&gt;📱 &lt;strong&gt;Responsive Design&lt;/strong&gt; - Mobile-first approach&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;Performance&lt;/strong&gt; - Static files, instant loading&lt;/li&gt;
&lt;li&gt;♿ &lt;strong&gt;Accessibility&lt;/strong&gt; - Built-in ARIA support&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;SEO Optimized&lt;/strong&gt; - Semantic HTML, proper meta tags&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AI-Enhanced Workflows
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;💬 &lt;strong&gt;Natural Language Setup&lt;/strong&gt; - Describe, don't configure&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Instant Validation&lt;/strong&gt; - Real-time error checking&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;Auto-Generation&lt;/strong&gt; - Complete configs from prompts&lt;/li&gt;
&lt;li&gt;🎯 &lt;strong&gt;Context-Aware Help&lt;/strong&gt; - Relevant examples always&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;Iterative Refinement&lt;/strong&gt; - Easy modifications&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎓 Technical Implementation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Configuration Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# home.toml - Fully AI-generatable&lt;/span&gt;
&lt;span class="nn"&gt;[hero]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Nishikanta Ray"&lt;/span&gt;
&lt;span class="py"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Full-Stack Developer"&lt;/span&gt;
&lt;span class="py"&gt;intro&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s"&gt;"Building developer-first tools and AI-assisted workflows"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Specialized in static-first architectures and minimal frameworks"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[hero.actions]&lt;/span&gt;
&lt;span class="py"&gt;primary_text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"View Projects"&lt;/span&gt;
&lt;span class="py"&gt;primary_link&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"projects.html"&lt;/span&gt;
&lt;span class="py"&gt;secondary_text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Contact Me"&lt;/span&gt;
&lt;span class="py"&gt;secondary_link&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"contact.html"&lt;/span&gt;

&lt;span class="nn"&gt;[sections]&lt;/span&gt;
&lt;span class="py"&gt;enabled_sections&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"projects"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"skills"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"experience"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[theme]&lt;/span&gt;
&lt;span class="py"&gt;mode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"auto"&lt;/span&gt;  &lt;span class="c"&gt;# auto, light, or dark&lt;/span&gt;
&lt;span class="py"&gt;accent_color&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#3b82f6"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  MCP Tool Usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// User prompt: "Create a blog config for tech writing"&lt;/span&gt;

&lt;span class="c1"&gt;// MCP generates:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tech Blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Insights on web development&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your Name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;posts_per_page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;enable_comments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;enable_search&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;enable_categories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;starter-post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome to My Blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2026-01-22&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;introduction&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&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;h2&gt;
  
  
  🚀 Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Option 1: AI-Assisted Setup (Recommended)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Install MCP Server&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; renderer-mcp-server

&lt;span class="c"&gt;# 2. Use Gemini CLI for AI assistance:&lt;/span&gt;
gemini &lt;span class="s2"&gt;"Create a portfolio configuration for [Your Name] with projects and resume"&lt;/span&gt;

&lt;span class="c"&gt;# 3. Deploy to any static host&lt;/span&gt;
&lt;span class="c"&gt;# Netlify, Vercel, GitHub Pages, Cloudflare Pages&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Option 2: Manual Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone repository&lt;/span&gt;
git clone https://github.com/NishikantaRay/renderer.git

&lt;span class="c"&gt;# Serve locally&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; http.server 8000
&lt;span class="c"&gt;# or&lt;/span&gt;
npx serve &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Configure via TOML files in config/&lt;/span&gt;
&lt;span class="c"&gt;# Edit content in Markdown files&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📚 Resources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Documentation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;📖 &lt;a href="https://renderer.nishikanta.in/docs" rel="noopener noreferrer"&gt;Complete Docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🤖 &lt;a href="https://github.com/NishikantaRay/renderer-mcp-server/blob/main/README.md" rel="noopener noreferrer"&gt;MCP Setup Guide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🎓 &lt;a href="https://renderer.nishikanta.in/docs#guides" rel="noopener noreferrer"&gt;Configuration Guides&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Repositories
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🏗️ &lt;a href="https://github.com/NishikantaRay/renderer" rel="noopener noreferrer"&gt;Renderer Framework&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🤖 &lt;a href="https://github.com/NishikantaRay/renderer-mcp-server" rel="noopener noreferrer"&gt;MCP Server&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🌐 &lt;a href="https://nishikanta.in" rel="noopener noreferrer"&gt;Live Demo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quick Start Commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Try the MCP server&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; renderer-mcp-server

&lt;span class="c"&gt;# Clone and run locally&lt;/span&gt;
git clone https://github.com/NishikantaRay/renderer.git
&lt;span class="nb"&gt;cd &lt;/span&gt;renderer &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npx serve &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Generate portfolio with Gemini CLI&lt;/span&gt;
gemini &lt;span class="s2"&gt;"Create a complete portfolio configuration for me"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  👤 About the Creator
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Nishikanta Ray&lt;/strong&gt; - Full-Stack Developer specializing in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛠️ Developer experience and productivity tools&lt;/li&gt;
&lt;li&gt;🤖 AI-assisted workflows and automation&lt;/li&gt;
&lt;li&gt;🏗️ Minimal-framework, static-first architectures&lt;/li&gt;
&lt;li&gt;📚 Open source contributions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Connect:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌐 Portfolio: &lt;a href="https://nishikanta.in" rel="noopener noreferrer"&gt;https://nishikanta.in&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 GitHub: &lt;a href="https://github.com/NishikantaRay" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎉 Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Renderer&lt;/strong&gt; demonstrates the transformative potential of Google Gemini when applied to real-world developer workflows. By combining static-first architecture with intelligent AI assistance through MCP, we've created a system that:&lt;/p&gt;

&lt;p&gt;This project proves that AI isn't just for chatbots—it's a fundamental tool for reimagining how we build and maintain software.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Built with Google Gemini | Powered by MCP | Made for Developers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Start building your AI-assisted portfolio today at &lt;a href="https://renderer.nishikanta.in" rel="noopener noreferrer"&gt;renderer.nishikanta.in&lt;/a&gt;&lt;/em&gt; 🚀&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>googleaichallenge</category>
      <category>portfolio</category>
      <category>gemini</category>
    </item>
    <item>
      <title>Production-Grade Prompting with the Anthropic API</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sat, 17 Jan 2026 16:36:23 +0000</pubDate>
      <link>https://dev.to/nishikantaray/production-grade-prompting-with-the-anthropic-api-ag2</link>
      <guid>https://dev.to/nishikantaray/production-grade-prompting-with-the-anthropic-api-ag2</guid>
      <description>&lt;h2&gt;
  
  
  Concepts, Parameters, Streaming, Caching, and a Real Enterprise Example
&lt;/h2&gt;

&lt;p&gt;Prompting in Anthropic (Claude) is not just about writing good instructions.&lt;br&gt;&lt;br&gt;
In production systems, prompts behave more like &lt;strong&gt;specifications&lt;/strong&gt; than conversations.&lt;/p&gt;

&lt;p&gt;This article explains &lt;strong&gt;how prompting actually works in Anthropic&lt;/strong&gt;, how to design &lt;strong&gt;reliable and compliant prompts&lt;/strong&gt;, and how to use &lt;strong&gt;JavaScript&lt;/strong&gt; to build real systems—ending with a &lt;strong&gt;production-grade sentiment analysis prompt&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  1. How Anthropic Prompting Really Works
&lt;/h2&gt;

&lt;p&gt;Anthropic uses a &lt;strong&gt;message-based API&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Each request contains the &lt;strong&gt;entire conversation state&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Claude does &lt;strong&gt;not&lt;/strong&gt; remember anything between API calls.&lt;/p&gt;
&lt;h3&gt;
  
  
  Mental model
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;send&lt;/span&gt; &lt;span class="nx"&gt;full&lt;/span&gt; &lt;span class="nx"&gt;conversation&lt;/span&gt;
&lt;span class="nx"&gt;Claude&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;continues&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Every request must include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Who the assistant is&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What rules apply&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What the user just said&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Any images or documents&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  2. Messages and Roles (Core Concept)
&lt;/h2&gt;

&lt;p&gt;Anthropic uses three roles:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;system&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hard rules, behavior, constraints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;user&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Input data or tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;assistant&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Previous model replies (conversation priming)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello! Only speak Spanish.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;assistant&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hola!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;How are you?&lt;/span&gt;&lt;span class="dl"&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;Claude will answer &lt;strong&gt;in Spanish&lt;/strong&gt; because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Conversation history establishes the rule&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Claude prioritizes consistency&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Production rule
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Put non-negotiable rules in&lt;/strong&gt; &lt;code&gt;system&lt;/code&gt;, not in conversation history.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  3. System vs User Instructions (Why It Matters)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Instruction Type&lt;/th&gt;
&lt;th&gt;Reliability&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;System&lt;/td&gt;
&lt;td&gt;Strong, persistent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;Soft, overrideable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Assistant&lt;/td&gt;
&lt;td&gt;Priming only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Production-safe example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You must respond only in Spanish.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This survives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Long conversations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Truncated history&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User attempts to override&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  4. Temperature: Controlling Randomness
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Temperature controls how predictable Claude’s word choices are.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; control intelligence.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Temperature&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;th&gt;Use case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.0–0.2&lt;/td&gt;
&lt;td&gt;Deterministic&lt;/td&gt;
&lt;td&gt;JSON, analytics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.3–0.5&lt;/td&gt;
&lt;td&gt;Controlled&lt;/td&gt;
&lt;td&gt;Summaries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.6–0.8&lt;/td&gt;
&lt;td&gt;Creative&lt;/td&gt;
&lt;td&gt;Writing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.9+&lt;/td&gt;
&lt;td&gt;Unstable&lt;/td&gt;
&lt;td&gt;Rarely useful&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Use this when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Output must be parsed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compliance matters&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decisions depend on correctness&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  5. stop_sequences: When the Model Must Stop
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;stop_sequences&lt;/code&gt; tells Claude &lt;strong&gt;when to stop generating&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;stop_sequences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;User:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude stops &lt;strong&gt;immediately&lt;/strong&gt; when it reaches that string.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common uses
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Prevent role leakage&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;End JSON cleanly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stop agent loops&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key rule
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Stop sequences are &lt;strong&gt;guards&lt;/strong&gt;, not fixes for bad prompts.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6. Streaming Responses (Real-Time Output)
&lt;/h2&gt;

&lt;p&gt;Streaming lets Claude send text &lt;strong&gt;incrementally&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text_stream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why streaming exists
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Faster perceived response&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Better UX&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Long outputs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When NOT to stream
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;JSON APIs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tool calls&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Strict schema validation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Production pattern
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;for &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;chunk&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text_stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// buffer now contains the full response&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  7. Multimodal Prompting (Images + Text)
&lt;/h2&gt;

&lt;p&gt;Anthropic allows &lt;strong&gt;image + text together&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Count the containers.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&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;h3&gt;
  
  
  Rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;content&lt;/code&gt; must be an array&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Image first, instruction second&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Images only in &lt;code&gt;user&lt;/code&gt; role&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  8. Prompt Caching and &lt;code&gt;cache_control&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Anthropic optimizes performance by caching repeated prompt prefixes.&lt;/p&gt;

&lt;p&gt;This is good for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;System prompts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Templates&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Policies&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But dangerous for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;User data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Transcripts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Images&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PII&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  9. &lt;code&gt;cache_control: { type: "ephemeral" }&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cache_control&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ephemeral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Use this content once. Do not cache. Do not reuse. Do not persist.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  When to use it
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Data&lt;/th&gt;
&lt;th&gt;Ephemeral&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;User input&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Call transcripts&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Images&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customer feedback&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Why it matters
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Prevents data reuse&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improves compliance posture&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduces audit risk&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  10. JavaScript Example: Safe Prompt with Ephemeral Data
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Anthropic&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@anthropic-ai/sdk&lt;/span&gt;&lt;span class="dl"&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Anthropic&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ANTHROPIC_API_KEY&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;claude-3-5-sonnet-20240620&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;max_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You are a deterministic analysis engine.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The service was slow and frustrating.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;cache_control&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ephemeral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  11. What Makes a Prompt Production-Grade
&lt;/h2&gt;

&lt;p&gt;A production prompt has:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Clear role definition&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Explicit constraints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Defined output format&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fail-closed behavior&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Low temperature&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No exposed reasoning&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Safe handling of sensitive data&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Good prompts are specifications, not conversations.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  12. Production-Grade Sentiment Analysis Prompt
&lt;/h2&gt;

&lt;p&gt;This prompt follows &lt;strong&gt;all best practices discussed above&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Analyze&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;sentiment&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;following&lt;/span&gt; &lt;span class="nx"&gt;customer&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="nx"&gt;Rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;Classify&lt;/span&gt; &lt;span class="nx"&gt;sentiment&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;POSITIVE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NEGATIVE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;NEUTRAL&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;Do&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;include&lt;/span&gt; &lt;span class="nx"&gt;personal&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;Do&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;intent&lt;/span&gt; &lt;span class="nx"&gt;beyond&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;Limit&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt;

&lt;span class="nx"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="nx"&gt;Return&lt;/span&gt; &lt;span class="nx"&gt;ONLY&lt;/span&gt; &lt;span class="nx"&gt;valid&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="nx"&gt;explanations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="nx"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sentiment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POSITIVE | NEGATIVE | NEUTRAL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confidence&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;summary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;If&lt;/span&gt; &lt;span class="nx"&gt;sentiment&lt;/span&gt; &lt;span class="nx"&gt;cannot&lt;/span&gt; &lt;span class="nx"&gt;be&lt;/span&gt; &lt;span class="nx"&gt;determined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sentiment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NEUTRAL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confidence&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;summary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Insufficient data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  13. Sentiment Analysis: Full JavaScript Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;claude-3-5-sonnet-20240620&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;max_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You are a strict sentiment classification engine.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Support was slow and unhelpful.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;cache_control&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ephemeral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  14. Final Takeaway
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Anthropic prompting works best when you treat prompts like contracts: explicit, constrained, deterministic, and safe.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>javascript</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
