<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>LLM Apps on Narasimha Karthik J</title><link>https://jnk234.github.io/tags/llm-apps/</link><description>Recent content in LLM Apps on Narasimha Karthik J</description><generator>Hugo</generator><language>en</language><lastBuildDate>Wed, 01 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://jnk234.github.io/tags/llm-apps/index.xml" rel="self" type="application/rss+xml"/><item><title>whoblinked</title><link>https://jnk234.github.io/projects/whoblinked/</link><pubDate>Wed, 01 Jul 2026 00:00:00 +0000</pubDate><guid isPermaLink="false">https://jnk234.github.io/projects/whoblinked/#full</guid><description>&lt;p&gt;&lt;a href="https://whoblinked.com" target="_blank" rel="noreferrer"&gt;whoblinked.com&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="what-it-is" class="relative group"&gt;What it is &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#what-it-is" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;whoblinked watches your competitors&amp;rsquo; catalogues and tells you what they launched, discontinued and repriced. I co-founded it and have been CTO since July 2026. The code is private.&lt;/p&gt;
&lt;p&gt;I built it end to end, from the data model and API contracts to the React product. It is multi-tenant.&lt;/p&gt;
&lt;h2 id="how-it-works" class="relative group"&gt;How it works &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#how-it-works" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Extraction with fallbacks.&lt;/strong&gt; Each scan tries the store&amp;rsquo;s API first, then structured markup on the page, then a headless browser.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Block detection.&lt;/strong&gt; A scan that was blocked or failed is recognised as such, so it never shows up as a change in a competitor&amp;rsquo;s catalogue.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM features.&lt;/strong&gt; Competitor discovery, gap analysis and ownership research. Model output is checked against live search results before a user sees it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cost and release.&lt;/strong&gt; Every LLM call has its cost tracked, and an automated test-and-release pipeline gates deploys.&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>LockIn: Browser Focus Tracker</title><link>https://jnk234.github.io/projects/lockin-browser-focus-tracker/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><guid isPermaLink="false">https://jnk234.github.io/projects/lockin-browser-focus-tracker/#full</guid><description>&lt;p&gt;&lt;a href="https://github.com/JNK234/lockin" target="_blank" rel="noreferrer"&gt;Code on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="what-it-is" class="relative group"&gt;What it is &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#what-it-is" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;You start a session with a goal, such as &amp;ldquo;fix auth bug in login flow&amp;rdquo;. The extension records each page you open. An LLM labels each visit on-task, distraction or ambiguous relative to that goal. If you drift, an overlay nudges you and offers to take you back. When the session ends you get a focus report.&lt;/p&gt;
&lt;p&gt;






 
 
&lt;figure&gt;&lt;img src="https://raw.githubusercontent.com/JNK234/lockin/main/docs/images/report-dashboard.png" alt="Focus report dashboard" class="mx-auto my-0 rounded-md" /&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="how-it-works" class="relative group"&gt;How it works &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#how-it-works" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Extension (Manifest V3).&lt;/strong&gt; Sends each page load, with its URL, title and page text, to the backend, and polls a nudge endpoint every 60 seconds.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backend (FastAPI).&lt;/strong&gt; Stores the visit and returns at once. Classification runs as a background task, so browsing never waits on the model.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Classification.&lt;/strong&gt; A RocketRide pipeline sends GPT-4o the goal, URL, title and the first 2,000 characters of the page, and asks for a JSON label and reason.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Graph storage (Neo4j).&lt;/strong&gt; Sessions, tasks, visits, sites and nudges are nodes. Visits link in order with &lt;code&gt;NEXT&lt;/code&gt; edges, and sites link to tasks as &lt;code&gt;ON_TASK_FOR&lt;/code&gt; or &lt;code&gt;DISTRACTION_FROM&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Report and Q&amp;amp;A.&lt;/strong&gt; The report shows a focus score, a color-coded timeline, a per-site breakdown and LLM insights. A second pipeline answers plain-language questions about past sessions by querying the graph.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Neo4j runs in Docker Compose, and a seed script loads a demo session.&lt;/p&gt;</description></item><item><title>Zettelkasten Automation</title><link>https://jnk234.github.io/projects/zettelkasten-automation/</link><pubDate>Fri, 16 Jan 2026 00:00:00 +0000</pubDate><guid isPermaLink="false">https://jnk234.github.io/projects/zettelkasten-automation/#full</guid><description>&lt;p&gt;&lt;a href="https://github.com/JNK234/zettelkasten-auto" target="_blank" rel="noreferrer"&gt;Code on GitHub&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="what-it-is" class="relative group"&gt;What it is &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#what-it-is" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;A command-line tool for an Obsidian vault. It reads long source notes (decoded papers, articles), pulls out the reusable ideas as atomic notes, links them, and keeps a local semantic index. It can then gather the notes around a source or a note into one bundle to hand to a model or read in one place.&lt;/p&gt;
&lt;p&gt;It never deletes a source. A processed source gets a &lt;code&gt;Status: #processed&lt;/code&gt; marker.&lt;/p&gt;
&lt;h2 id="how-it-works" class="relative group"&gt;How it works &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#how-it-works" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;zettel process&lt;/code&gt; handles each unprocessed source:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Skips notes that are already processed or too short.&lt;/li&gt;
&lt;li&gt;Splits long sources by heading, then by paragraph.&lt;/li&gt;
&lt;li&gt;Runs structured extraction per chunk and validates the output.&lt;/li&gt;
&lt;li&gt;Drops candidate concepts that duplicate an existing note, by normalized title or by embedding distance.&lt;/li&gt;
&lt;li&gt;Writes new notes from the vault template with &lt;code&gt;Tags&lt;/code&gt;, &lt;code&gt;See Also&lt;/code&gt; (semantic neighbours) and &lt;code&gt;References&lt;/code&gt; (the source).&lt;/li&gt;
&lt;li&gt;Indexes the notes in ChromaDB.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Each source ends with a named outcome, such as &lt;code&gt;processed&lt;/code&gt;, &lt;code&gt;too_short&lt;/code&gt;, &lt;code&gt;provider_error&lt;/code&gt; or &lt;code&gt;invalid_output&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;zettel bundle&lt;/code&gt; collects the notes from a source or around one note, following tag links to a set depth. A dry run refuses to use a stale index rather than return wrong neighbours.&lt;/p&gt;
&lt;h2 id="details" class="relative group"&gt;Details &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#details" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;LLM providers: OpenAI, Anthropic, Gemini and Ollama. Embeddings: OpenAI or a local sentence-transformer. The index is scoped to the embedding provider and model, so switching models does not mix vectors.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--dry-run&lt;/code&gt; on every command that writes.&lt;/li&gt;
&lt;li&gt;The research-vault skills in 
 
 &lt;a href="https://jnk234.github.io/projects/claude-kit/"&gt;claude-kit&lt;/a&gt; use it for semantic search over zettels.&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>