<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged obsidian</title>
<link>https://coderlegion.com/tag/obsidian</link>
<description>Powered by Question2Answer</description>
<item>
<title>Obsidian Plugin Error Logging Without Telemetry</title>
<link>https://coderlegion.com/31519/obsidian-plugin-error-logging-without-telemetry</link>
<description>&lt;p&gt;Crash reporting feels like a solved problem until your distribution platform says the obvious solution is not allowed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Quick solution:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;type ErrorRecord = {
  timestamp: string;
  level: &quot;error&quot; | &quot;warning&quot;;
  source: string;
  message: string;
  stack?: string;
};

const MAX_RECORDS = 50;

function appendRecord(
  records: ErrorRecord[],
  next: ErrorRecord
): ErrorRecord[] {
  return [...records, next].slice(-MAX_RECORDS);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Check the current &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.obsidian.md/community-directory/developer-policies&quot;&gt;Obsidian community-plugin developer policies&lt;/a&gt; before adding any reporting path; this design keeps capture local until the user chooses to share it.&lt;/p&gt;
&lt;p&gt;For &lt;a rel=&quot;nofollow&quot; href=&quot;https://raylabs.app/articles/publish-obsidian-community-plugin/&quot;&gt;Obsidian community&lt;/a&gt; plugins, that boundary is explicit. The current developer policies state that community plugins must not include client-side telemetry. Network use and &lt;a rel=&quot;nofollow&quot; href=&quot;https://raylabs.app/articles/monitoring-server-side-fcm-notifications-effectively/&quot;&gt;server-side&lt;/a&gt; telemetry also require disclosure.&lt;/p&gt;
&lt;p&gt;That rules out the usual &quot;just add a crash SDK&quot; answer for a plugin intended for the official directory.&lt;/p&gt;
&lt;p&gt;You still need production diagnostics, especially for startup and mobile failures. The solution is to separate &lt;strong&gt;capture&lt;/strong&gt; from &lt;strong&gt;transmission&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Capture locally. Redact aggressively. Let the user decide whether anything leaves the device.&lt;/p&gt;
&lt;h3 id=&quot;start-with-the-policy-boundary&quot;&gt;Start with the policy boundary&lt;/h3&gt;
&lt;p&gt;The goal is not to imitate a remote crash service secretly.&lt;/p&gt;
&lt;p&gt;The goal is to preserve enough local evidence that a user can report a reproducible failure.&lt;/p&gt;
&lt;p&gt;A compliant design should have these properties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;no automatic error upload;&lt;/li&gt;
&lt;li&gt;no hidden analytics endpoint;&lt;/li&gt;
&lt;li&gt;no third-party crash SDK;&lt;/li&gt;
&lt;li&gt;bounded local storage;&lt;/li&gt;
&lt;li&gt;explicit secret redaction;&lt;/li&gt;
&lt;li&gt;user-visible controls to inspect, copy, clear, or report;&lt;/li&gt;
&lt;li&gt;network transmission only after a deliberate user action.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are publishing to the Obsidian community directory, read the current developer policies before designing observability.&lt;/p&gt;
&lt;h3 id=&quot;use-a-bounded-local-ring-buffer&quot;&gt;Use a bounded local ring buffer&lt;/h3&gt;
&lt;p&gt;A log that grows forever becomes its own reliability problem.&lt;/p&gt;
&lt;p&gt;For a plugin, the useful window is usually recent failures, not months of historical console noise.&lt;/p&gt;
&lt;p&gt;Store the log in the plugin's own configuration area rather than scattering debug files through user notes.&lt;/p&gt;
&lt;h3 id=&quot;serialize-writes&quot;&gt;Serialize writes&lt;/h3&gt;
&lt;p&gt;Mobile and startup errors often happen close together. Multiple asynchronous writes can race and overwrite each other.&lt;/p&gt;
&lt;p&gt;A tiny write queue is enough:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;let writeChain = Promise.resolve();

function persist(records: ErrorRecord[]) {
  writeChain = writeChain.then(() =&amp;gt;
    savePluginData({ errorLog: records })
  );
  return writeChain;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is not a database. It simply makes &quot;append error A, then error B&quot; deterministic.&lt;/p&gt;
&lt;p&gt;On startup:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;load the existing local log;&lt;/li&gt;
&lt;li&gt;append any new error;&lt;/li&gt;
&lt;li&gt;cap it;&lt;/li&gt;
&lt;li&gt;persist the new snapshot.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A restart should not destroy the exact failure you are trying to diagnose.&lt;/p&gt;
&lt;h3 id=&quot;redact-before-storage-not-before-upload&quot;&gt;Redact before storage, not before upload&lt;/h3&gt;
&lt;p&gt;If the log is supposed to stay local, it may be tempting to postpone redaction until the user presses Report.&lt;/p&gt;
&lt;p&gt;That leaves secrets sitting unmasked on disk.&lt;/p&gt;
&lt;p&gt;Redact &lt;strong&gt;before the record enters the buffer&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Your redactor should cover values your plugin knows about and common credential shapes:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;function redact(input: string, secrets: string[]): string {
  let output = input;

  for (const secret of secrets) {
    if (secret) output = output.split(secret).join(&quot;[REDACTED]&quot;);
  }

  output = output.replace(
    /Bearer\s+[A-Za-z0-9._~+/=-]+/gi,
    &quot;Bearer [REDACTED]&quot;
  );

  output = output.replace(
    /github_pat_[A-Za-z0-9_]+/g,
    &quot;[REDACTED_GITHUB_TOKEN]&quot;
  );

  return output;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do not log note bodies, full sync payloads, or arbitrary request content just because they are available.&lt;/p&gt;
&lt;p&gt;The safest diagnostic is usually structural:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;operation name;&lt;/li&gt;
&lt;li&gt;error class;&lt;/li&gt;
&lt;li&gt;status code;&lt;/li&gt;
&lt;li&gt;sanitized message;&lt;/li&gt;
&lt;li&gt;timestamp;&lt;/li&gt;
&lt;li&gt;plugin version;&lt;/li&gt;
&lt;li&gt;platform category.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;test-the-redactor-like-a-security-boundary&quot;&gt;Test the redactor like a security boundary&lt;/h3&gt;
&lt;p&gt;An untested redactor is a promise, not a control.&lt;/p&gt;
&lt;p&gt;Write tests for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;exact known secret values;&lt;/li&gt;
&lt;li&gt;Authorization headers;&lt;/li&gt;
&lt;li&gt;token-like patterns;&lt;/li&gt;
&lt;li&gt;stack traces containing query parameters;&lt;/li&gt;
&lt;li&gt;multiline messages;&lt;/li&gt;
&lt;li&gt;empty strings;&lt;/li&gt;
&lt;li&gt;already redacted values.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also test that ordinary technical context survives. A redactor that turns every path, SHA, and URL into &quot;[REDACTED]&quot; produces a safe but useless report.&lt;/p&gt;
&lt;p&gt;Aim for &lt;strong&gt;minimum useful evidence&lt;/strong&gt;, not maximum logging.&lt;/p&gt;
&lt;h3 id=&quot;capture-global-errors-carefully&quot;&gt;Capture global errors carefully&lt;/h3&gt;
&lt;p&gt;Plugin-specific try/catch blocks are valuable, but some failures escape them.&lt;/p&gt;
&lt;p&gt;Where the host lifecycle allows it, register handlers for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;error;&lt;/li&gt;
&lt;li&gt;unhandledrejection.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Normalize those events into the same ErrorRecord shape.&lt;/p&gt;
&lt;p&gt;Just as important: unregister or bind them through the plugin lifecycle so hot reloads and plugin disable/enable cycles do not create duplicate listeners.&lt;/p&gt;
&lt;p&gt;The global hook is a safety net, not a replacement for contextual error handling. A caught sync error can say &quot;failed while fetching remote tree&quot;; a global rejection may only know that a promise failed.&lt;/p&gt;
&lt;h3 id=&quot;give-the-user-inspection-controls&quot;&gt;Give the user inspection controls&lt;/h3&gt;
&lt;p&gt;A local log becomes trustworthy when the user can see and erase it.&lt;/p&gt;
&lt;p&gt;A small settings section can provide:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;View recent errors;&lt;/li&gt;
&lt;li&gt;Copy sanitized report;&lt;/li&gt;
&lt;li&gt;Clear log;&lt;/li&gt;
&lt;li&gt;Report issue.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Make the retention policy visible. If you keep 50 entries, say so.&lt;/p&gt;
&lt;p&gt;This is especially important for privacy-oriented tools. Users should not have to reverse engineer where diagnostic data lives.&lt;/p&gt;
&lt;h3 id=&quot;reporting-should-be-user-initiated&quot;&gt;Reporting should be user initiated&lt;/h3&gt;
&lt;p&gt;A practical reporting flow can open a prefilled GitHub issue URL after letting the user preview the sanitized text locally:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;const params = new URLSearchParams({
  title: &quot;Bug report&quot;,
  body: buildSanitizedReport(records),
});

window.open(
  &quot;https://github.com/example/project/issues/new?&quot; + params.toString()
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The plugin has not submitted anything at this point. It opened a browser page.&lt;/p&gt;
&lt;p&gt;The user can:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;review the text;&lt;/li&gt;
&lt;li&gt;delete anything they do not want to share;&lt;/li&gt;
&lt;li&gt;add reproduction details;&lt;/li&gt;
&lt;li&gt;press Submit.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That human-in-the-loop boundary is fundamentally different from background telemetry.&lt;/p&gt;
&lt;h3 id=&quot;be-honest-about-blind-spots&quot;&gt;Be honest about blind spots&lt;/h3&gt;
&lt;p&gt;A local logger cannot capture everything.&lt;/p&gt;
&lt;p&gt;If the plugin fails before its code initializes, its own global handlers may never run. A corrupted manifest or syntax error during loading can occur outside the logger's lifetime.&lt;/p&gt;
&lt;p&gt;Document that limitation.&lt;/p&gt;
&lt;p&gt;Useful fallback guidance can tell advanced users how to capture the Obsidian developer console when the plugin does not load far enough to show its own report UI.&lt;/p&gt;
&lt;p&gt;Reliability improves when a system has a known boundary rather than claiming parity with a full remote crash platform.&lt;/p&gt;
&lt;h3 id=&quot;keep-network-behavior-separate-from-diagnostics&quot;&gt;Keep network behavior separate from diagnostics&lt;/h3&gt;
&lt;p&gt;A plugin may legitimately use the network for its main feature. That does not mean diagnostics should piggyback on those requests.&lt;/p&gt;
&lt;p&gt;Keep these concerns separate:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;feature network request
    !=
error reporting transport
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the plugin syncs files, calls an API, or uses an AI service, disclose that according to platform rules. The local error buffer should not silently convert those connections into a telemetry channel.&lt;/p&gt;
&lt;p&gt;The same privacy principle matters for richer workflows: users need to understand when data stays local and when a feature intentionally sends it elsewhere.&lt;/p&gt;
&lt;h3 id=&quot;verification-and-execution-checklist&quot;&gt;Verification and execution checklist&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Read the current directory policy to ensure compliance with telemetry rules.&lt;/li&gt;
&lt;li&gt;Store errors locally only without automatic upload paths.&lt;/li&gt;
&lt;li&gt;Cap the buffer and serialize writes to prevent race conditions during startup.&lt;/li&gt;
&lt;li&gt;Redact secrets before persistence and test the redactor against credentials.&lt;/li&gt;
&lt;li&gt;Verify that issue reporting requires explicit user interaction and review.&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/31519/obsidian-plugin-error-logging-without-telemetry</guid>
<pubDate>Sat, 17 Oct 2026 16:43:33 +0000</pubDate>
</item>
<item>
<title>Turning YouTube Videos Into Obsidian Notes — and What Shipping the Plugin Taught Me</title>
<link>https://coderlegion.com/27564/turning-youtube-videos-into-obsidian-notes-and-what-shipping-the-plugin-taught-me</link>
<description>&lt;p&gt;Every so often I'd watch a 90-minute conference talk, close the tab, and realise the only trace it left in my vault was a URL in a list called &quot;watch later (again)&quot;.&lt;/p&gt;
&lt;p&gt;So I built an Obsidian plugin that turns a video into an actual note. It's been in the community directory since September and is on 0.3.0 now. This is what it does, and — more usefully — the handful of decisions and review rules I'd want to know before building another one.&lt;/p&gt;
&lt;h3 id=&quot;what-lands-in-the-vault&quot;&gt;What lands in the vault&lt;/h3&gt;
&lt;p&gt;One command, one link, and you get a note:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://summarizevideototext.com/obsidian-plugin/note.png&quot; alt=&quot;A video note in Obsidian: embedded player, TL;DR callout and key insights&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a TL;DR callout and key insights&lt;/li&gt;
&lt;li&gt;an embedded player at the top — timestamps seek it in place, without leaving the note&lt;/li&gt;
&lt;li&gt;chapters as timestamped bullets&lt;/li&gt;
&lt;li&gt;optional summary (several templates), quiz, and full transcript in a collapsed callout&lt;/li&gt;
&lt;li&gt;frontmatter with title, source, channel, language and tags, shaped for Dataview&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://summarizevideototext.com/obsidian-plugin/chapters.png&quot; alt=&quot;Key insights and chapters with timestamp links&quot;&gt;&lt;/p&gt;
&lt;p&gt;Plus a right-sidebar chat panel scoped to the note you're reading, and a command that turns the quiz into &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/st3v3nmw/obsidian-spaced-repetition&quot;&gt;Spaced Repetition&lt;/a&gt; cards.&lt;/p&gt;
&lt;p&gt;Now the parts that were actually decisions.&lt;/p&gt;
&lt;h3 id=&quot;the-plugin-holds-no-model-keys&quot;&gt;The plugin holds no model keys&lt;/h3&gt;
&lt;p&gt;An Obsidian plugin runs on the user's machine. You can't ship an API key in it, and asking every user to paste their own is both friction and a support queue you will personally staff forever.&lt;/p&gt;
&lt;p&gt;So the plugin generates nothing. It sends a video link and an account token to a server, and writes down what comes back. That's the whole client.&lt;/p&gt;
&lt;p&gt;The honest trade-off: this means the plugin needs an account, which is a real cost to the user and something I put in the README under a &lt;strong&gt;Before you install&lt;/strong&gt; heading rather than burying. A plugin that silently requires a signup is a plugin that gets one-starred.&lt;/p&gt;
&lt;h3 id=&quot;the-connect-handshake-and-the-one-line-that-makes-it-safe&quot;&gt;The connect handshake, and the one line that makes it safe&lt;/h3&gt;
&lt;p&gt;Settings → &lt;strong&gt;Connect&lt;/strong&gt; opens the browser at &lt;code&gt;/connect/obsidian?state=…&amp;amp;vault=…&lt;/code&gt;. You sign in, the server mints a token, and the page bounces you back via &lt;code&gt;obsidian://svt-connect?token=…&amp;amp;state=…&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;state&lt;/code&gt; is generated by the plugin and checked when the redirect comes home. Without that check, &lt;strong&gt;any web page could deep-link a token into your vault&lt;/strong&gt; — the &lt;code&gt;obsidian://&lt;/code&gt; scheme is open to anyone. It's four lines of code and it's the difference between a handshake and a hole.&lt;/p&gt;
&lt;p&gt;Server side the token is stored as a sha256 hash. Client side it lands in &lt;code&gt;.obsidian/plugins/&amp;lt;id&amp;gt;/data.json&lt;/code&gt;, which is worth saying out loud in your docs: if the user syncs their vault, that file goes with it.&lt;/p&gt;
&lt;h3 id=&quot;one-note-format-two-producers&quot;&gt;One note format, two producers&lt;/h3&gt;
&lt;p&gt;The website also has an &lt;em&gt;Export → Obsidian&lt;/em&gt; button. That's two code paths producing &quot;the same&quot; Markdown, which in my experience drift apart within about a week.&lt;/p&gt;
&lt;p&gt;So the Markdown is assembled in exactly one place — a server endpoint — and the plugin writes whatever it receives verbatim. The website button and the plugin produce identical notes because they are, literally, the same function call.&lt;/p&gt;
&lt;h3 id=&quot;re-running-a-command-must-not-eat-the-user-s-writing&quot;&gt;Re-running a command must not eat the user's writing&lt;/h3&gt;
&lt;p&gt;People add their own notes under the generated stuff. Refreshing a note has to be non-destructive or nobody will ever press it twice.&lt;/p&gt;
&lt;p&gt;The generated region is fenced:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;%% svt:start %%
…everything the server produced…
%% svt:end %%

## My notes
whatever you wrote, untouched
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Refresh replaces only what's between the markers. Frontmatter is the subtler half: the server returns an &lt;code&gt;ownedKeys&lt;/code&gt; list alongside the note, so the plugin overwrites the keys it owns and leaves every key you added alone. Writes go through &lt;code&gt;vault.process&lt;/code&gt; rather than read-then-write, which is also what the community review expects.&lt;/p&gt;
&lt;h3 id=&quot;requesturl-doesn-t-stream&quot;&gt;&lt;code&gt;requestUrl&lt;/code&gt; doesn't stream&lt;/h3&gt;
&lt;p&gt;Obsidian's &lt;code&gt;requestUrl&lt;/code&gt; sidesteps CORS, which you want, because your plugin isn't an origin anyone will whitelist. What it doesn't do is stream.&lt;/p&gt;
&lt;p&gt;My summary endpoint is server-sent events. So the plugin waits for the whole response and parses the event stream after the fact. You lose the progressive typewriter effect; you keep mobile support and never fight a preflight. Worth knowing before you architect around a stream that won't arrive.&lt;/p&gt;
&lt;h3 id=&quot;flashcards-and-only-appending&quot;&gt;Flashcards, and only appending&lt;/h3&gt;
&lt;p&gt;0.3.0 turns the quiz into a card note: multi-line format, the right answer and its explanation on the back, and a timestamp link to the moment the question came from.&lt;/p&gt;
&lt;p&gt;Run it again after new questions appear and only the missing cards are appended. Existing cards, their &lt;code&gt;&amp;lt;!--SR:…--&amp;gt;&lt;/code&gt; review schedules, and any cards you wrote yourself are never touched. Rewriting a review schedule is the fastest way to lose a user who has been reviewing for six months.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://summarizevideototext.com/obsidian-plugin/flashcards.png&quot; alt=&quot;A card note ready for the Spaced Repetition plugin&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;what-the-community-directory-review-actually-checks&quot;&gt;What the community directory review actually checks&lt;/h3&gt;
&lt;p&gt;Submitting is no longer a PR against &lt;code&gt;obsidian-releases&lt;/code&gt;. You log in at &lt;a rel=&quot;nofollow&quot; href=&quot;https://community.obsidian.md&quot;&gt;community.obsidian.md&lt;/a&gt;, link GitHub, and an automated reviewer runs. Mine came back with a list. The useful items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No inline styles.&lt;/strong&gt; Anything you'd reach for as &lt;code&gt;el.style.foo = bar&lt;/code&gt; belongs in &lt;code&gt;styles.css&lt;/code&gt;. My auto-growing textarea became the CSS &lt;code&gt;field-sizing: content&lt;/code&gt; instead of a resize handler, which is a better implementation anyway.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Settings must use the declarative 1.13 API&lt;/strong&gt; (&lt;code&gt;getSettingDefinitions()&lt;/code&gt; with groups, &lt;code&gt;getControlValue&lt;/code&gt; / &lt;code&gt;setControlValue&lt;/code&gt;). That forced &lt;code&gt;minAppVersion&lt;/code&gt; up to &lt;code&gt;1.13.0&lt;/code&gt;, because the &lt;em&gt;no-unsupported-api&lt;/em&gt; rule rejects 1.13 APIs while you claim to support older versions. Pick a lane; you can't straddle.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Attest your build.&lt;/strong&gt; &lt;code&gt;actions/attest-build-provenance&lt;/code&gt; in the release workflow, with &lt;code&gt;id-token&lt;/code&gt; and &lt;code&gt;attestations&lt;/code&gt; write permissions. &lt;code&gt;gh attestation verify main.js --owner &amp;lt;you&amp;gt;&lt;/code&gt; exiting 0 with no output is what success looks like.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The tag must match the manifest version&lt;/strong&gt;, and &lt;code&gt;npm version&lt;/code&gt; writes tags with a &lt;code&gt;v&lt;/code&gt; prefix that Obsidian doesn't want. &lt;code&gt;git tag -d v0.2.2 &amp;amp;&amp;amp; git tag 0.2.2&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One false alarm worth pre-empting: right after I re-cut a release, the checker insisted &quot;No release matches your manifest version.&quot; It had scanned during the draft window and cached that. Re-scan, it passes. Don't go rewriting your workflow like I nearly did.&lt;/p&gt;
&lt;h3 id=&quot;three-obsidian-css-facts-that-cost-me-an-evening&quot;&gt;Three Obsidian CSS facts that cost me an evening&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.view-content&lt;/code&gt; ships with &lt;code&gt;padding: 12px 12px 32px&lt;/code&gt;. If your custom view's layout looks mysteriously inset, that's why. Zero it with a same-specificity selector: &lt;code&gt;.workspace-leaf-content[data-type=&quot;…&quot;] .view-content.your-class&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;On desktop the status bar is &lt;code&gt;position: fixed&lt;/code&gt;, 27px tall, and floats &lt;strong&gt;over&lt;/strong&gt; the bottom of the right sidebar. Leave it room or your input box is permanently half-covered.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;button:not(.clickable-icon)&lt;/code&gt; picks up Obsidian's background and shadow. For a text link, use an &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;links&quot;&gt;Links&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Plugin: &lt;a rel=&quot;nofollow&quot; href=&quot;https://community.obsidian.md/plugins/summarize-video-to-text&quot;&gt;community.obsidian.md/plugins/summarize-video-to-text&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Source (MIT): &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/diaozxin007/obsidian-summarize-video-to-text&quot;&gt;github.com/diaozxin007/obsidian-summarize-video-to-text&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Setup walkthrough: &lt;a rel=&quot;nofollow&quot; href=&quot;https://summarizevideototext.com/obsidian-plugin&quot;&gt;summarizevideototext.com/obsidian-plugin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you're building something that writes into other people's vaults, the markers-and-&lt;code&gt;ownedKeys&lt;/code&gt; pattern is the piece I'd steal. Everything else was replaceable; that one is what makes a destructive command safe to press twice.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/27564/turning-youtube-videos-into-obsidian-notes-and-what-shipping-the-plugin-taught-me</guid>
<pubDate>Fri, 18 Sep 2026 01:29:36 +0000</pubDate>
</item>
<item>
<title>Your AI second brain has a security problem</title>
<link>https://coderlegion.com/21510/your-ai-second-brain-has-a-security-problem</link>
<description>&lt;p&gt;Everyone is connecting Obsidian to Claude via MCP. Nobody is asking what's actually in their vault.&lt;/p&gt;
&lt;p&gt;API keys in old notes. Connection strings. Client names. Tokens saved &quot;temporarily.&quot; All of it now accessible in a single AI conversation.&lt;/p&gt;
&lt;p&gt;The risk is indirect prompt injection. A web clip with hidden text, a shared markdown file with embedded instructions, a template from GitHub with poisoned metadata. Your AI reads it, follows the instruction, surfaces your credentials.&lt;/p&gt;
&lt;p&gt;This isn't theoretical - Unit 42 documented these attacks in production in March 2026.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Before connecting:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;grep -r &quot;sk&lt;em&gt;|aws&lt;/em&gt;|ghp_|Bearer |password:&quot; /path/to/vault/&lt;/li&gt;
&lt;li&gt;Set read-only MCP access&lt;/li&gt;
&lt;li&gt;Check web clips in a plain text editor for content you didn't write&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Building on RAG beyond personal use? Test against real attacks first &lt;a rel=&quot;nofollow&quot; href=&quot;https://sec-ra.com/simulate?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=second-brain&quot;&gt;Secra Simulate&lt;/a&gt; 64 adversarial prompts, 10 categories, free.&lt;/p&gt;
&lt;p&gt;Build the second brain. Just audit it first.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21510/your-ai-second-brain-has-a-security-problem</guid>
<pubDate>Mon, 29 Jun 2026 08:45:00 +0000</pubDate>
</item>
<item>
<title>AI Coding Tip 020 - Create a Second Brain</title>
<link>https://coderlegion.com/18160/ai-coding-tip-020-create-a-second-brain</link>
<description>&lt;p&gt;&lt;em&gt;Build a Persistent Memory Layer Your AI Can Actually Use&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;TL;DR: Use Obsidian with Markdown notes, YAML metadata, and direct AI file access to build a Second Brain with LLMs that gives your tools persistent project context.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;common-mistake-&quot;&gt;Common Mistake ❌&lt;/h2&gt;
&lt;p&gt;You paste a snippet of code or a problem description into an AI chat, get a good answer, and close the tab.&lt;/p&gt;
&lt;p&gt;The next week you face the same problem again.&lt;/p&gt;
&lt;p&gt;You search your chat history, find nothing useful, and paste the same snippet again.&lt;/p&gt;
&lt;p&gt;Your AI starts fresh every session with zero memory of what you built, decided, or debugged before.&lt;/p&gt;
&lt;h2 id=&quot;problems-addressed&quot;&gt;Problems Addressed&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;You repeat yourself constantly because context resets between sessions and your AI remembers nothing.&lt;/li&gt;
&lt;li&gt;You lose architectural decisions, debugging notes, meeting commitments, and design rationale after each conversation ends.&lt;/li&gt;
&lt;li&gt;Your AI gives generic answers because it lacks the specific context of your project and past decisions.&lt;/li&gt;
&lt;li&gt;Mental load accumulates as you juggle multiple projects, notifications, and context switches simultaneously.&lt;/li&gt;
&lt;li&gt;You lose track of decisions made weeks ago without a structured retrieval system.&lt;/li&gt;
&lt;li&gt;As you age or face cognitive overload, you forget context between sessions, repeat past mistakes, and lose the thread of long-running projects.&lt;/li&gt;
&lt;li&gt;Notification fatigue builds when every system demands your attention in real time instead of on your schedule and you forget what you were searching for.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;how-to-do-it-&quot;&gt;How to Do It ️&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Choose a local Markdown tool like &lt;a rel=&quot;nofollow&quot; href=&quot;https://obsidian.md&quot;&gt;Obsidian&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; href=&quot;https://logseq.com&quot;&gt;Logseq&lt;/a&gt;, &lt;a rel=&quot;nofollow&quot; href=&quot;https://foambubble.github.io/foam/&quot;&gt;Foam&lt;/a&gt;, or &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/refactoringhq/tolaria&quot;&gt;Tolaria&lt;/a&gt; to store all your knowledge as plain &lt;code&gt;.md&lt;/code&gt; files you own and control.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Organize your vault using the PARA system: Projects (active work with deadlines), Areas (ongoing responsibilities), Resources (reference material), and Archives (inactive items).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write atomic &lt;a rel=&quot;nofollow&quot; href=&quot;https://zettelkasten.de/introduction/&quot;&gt;Zettelkasten&lt;/a&gt; notes: one idea per file, with a unique identifier and explicit links that explain &lt;em&gt;why&lt;/em&gt; two concepts relate, not just what they are.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add YAML &lt;a rel=&quot;nofollow&quot; href=&quot;https://en.wikipedia.org/wiki/Book_design#Front_matter&quot;&gt;front matter&lt;/a&gt; to every note so your AI gets searchable, structured metadata it can query and filter:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;---
title: &quot;JWT Authentication Design&quot;
type: architecture-decision
status: approved
component: auth-service
tags: [security, backend]
created: 2018-12-09
related: [&quot;OAuth Flow&quot;, &quot;Session Management&quot;]
---
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Use Dataview or Obsidian Bases to query your vault like a database and surface all tasks due today, pending decisions, or notes grouped by component with a single dynamic query; every note is a record with metadata and legible text.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Give your AI direct access to &lt;a rel=&quot;nofollow&quot; href=&quot;https://coderlegion.com/12537/ai-coding-tip-010-access-all-your-code&quot;&gt;all your vault&lt;/a&gt; as local files so Claude, Devin, and Codex can read your entire codebase and notes simultaneously.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;code&gt;AGENTS.md&lt;/code&gt; in each sub-project that points to the relevant vault sections, following the nested agents pattern from &lt;a rel=&quot;nofollow&quot; href=&quot;https://coderlegion.com/14016/ai-coding-tip-014-use-nested-agents-md-files&quot;&gt;AI Coding Tip 014&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dictate notes on the go using &lt;a rel=&quot;nofollow&quot; href=&quot;https://coderlegion.com/16461/ai-coding-tip-018-use-voice-driven-development&quot;&gt;voice input&lt;/a&gt; and paste the transcript into your vault to capture context in real time without interrupting your flow.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sync your vault to mobile and tablet using Obsidian Sync, Dropbox, OneDrive, or Syncthing so your Second Brain travels with you everywhere.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set up &lt;a rel=&quot;nofollow&quot; href=&quot;https://openclaw.ai/&quot;&gt;OpenClaw&lt;/a&gt; or a local LLM (Ollama or LM Studio) to index your vault and answer questions via Telegram or WhatsApp, as a private assistant that never sends your data to the cloud.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ask your AI to scan your vault periodically for orphaned notes, missing connections, and hidden patterns, acting as a tireless librarian that reorganizes your knowledge network over time without falling into vault-design paralysis.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://coderlegion.com/13150/ai-coding-tip-011-initialize-agents-md&quot;&gt;Bootstrap your vault&lt;/a&gt; from your existing knowledge: ask ChatGPT, Claude, Grok, or Gemini to summarize and export your most relevant past conversations as Markdown notes, since you already have a Second Brain scattered across chat history waiting to be harvested.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;benefits&quot;&gt;Benefits&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Persistent Context:&lt;/strong&gt; Your AI starts every session knowing your architecture, past decisions, and current priorities instead of starting blank.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pattern Discovery:&lt;/strong&gt; The LLM finds connections between notes you wrote months apart and surfaces forgotten solutions to current problems.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Focus Protection:&lt;/strong&gt; You capture every interruption into your inbox and process it on your schedule, eliminating notification fatigue.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory Extension:&lt;/strong&gt; You can retrieve exact decisions and reasoning from months ago without relying on biological memory alone, making it especially valuable for senior developers, people with attention challenges, or anyone whose cognitive load has grown beyond what one brain can hold.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Privacy by Default:&lt;/strong&gt; When you use local models like Ollama with OpenClaw, your notes, code, and queries never leave your machine.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compounding Knowledge:&lt;/strong&gt; Every note you add makes your Second Brain denser: the more you use it, the more valuable it becomes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mobile Access:&lt;/strong&gt; You can query and update your knowledge base from any device, making your Second Brain available wherever you work.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Distraction-Free Writing:&lt;/strong&gt; You work in plain text files with minimal formatting, much like &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.urbandictionary.com/define.php?term=zenware&quot;&gt;zenware&lt;/a&gt;, so you stay focused on ideas instead of tools.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Visual Graph:&lt;/strong&gt; You can open Obsidian's Graph View to see all your notes as a visual network where nodes are notes and edges are links, revealing clusters, hub concepts, and hidden connections at a glance.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;context&quot;&gt;Context&lt;/h2&gt;
&lt;p&gt;Tiago Forte's &quot;Building a Second Brain&quot; methodology introduced the CODE framework: Capture, Organize, Distill, Express.&lt;/p&gt;
&lt;p&gt;For developers, this maps directly to how you learn, document, and reuse knowledge across projects.&lt;/p&gt;
&lt;p&gt;Niklas Luhmann, a sociologist who wrote over 50 books, developed the &lt;a rel=&quot;nofollow&quot; href=&quot;https://es.wikipedia.org/wiki/Zettelkasten&quot;&gt;Zettelkasten method&lt;/a&gt; using a physical slip box of interconnected atomic notes.&lt;/p&gt;
&lt;p&gt;Your Obsidian vault is that slip box, and your AI can search, analyze, and extend it at any time.&lt;/p&gt;
&lt;p&gt;LLMs have three types of memory: parametric (knowledge encoded during training), working (the current context window), and external (your files on disk).&lt;/p&gt;
&lt;p&gt;Your Second Brain fills the external memory layer and gives the AI permanent access to your project-specific knowledge that survives every session reset.&lt;/p&gt;
&lt;p&gt;Just as neural networks in LLMs store patterns in weights, your Second Brain stores patterns in linked Markdown files, extending the model's memory with your lived experience as a developer.&lt;/p&gt;
&lt;p&gt;Andrej Karpathy &lt;a rel=&quot;nofollow&quot; href=&quot;https://x.com/karpathy/status/2039805659525644595&quot;&gt;captured this architecture&lt;/a&gt; in one sentence: &quot;Obsidian is the IDE; the LLM is the programmer; the wiki is the codebase.&quot;&lt;/p&gt;
&lt;p&gt;The front matter you add to each note acts as structured metadata that significantly improves how AI retrieves and ranks relevant information.&lt;/p&gt;
&lt;p&gt;RAG (Retrieval-Augmented Generation) pipelines embed your notes as vectors and return the most semantically similar ones when you ask a question, injecting them directly into the AI's context window.&lt;/p&gt;
&lt;p&gt;I borrowed &lt;a rel=&quot;nofollow&quot; href=&quot;https://ernestokiszkurno.blogspot.com/2021/08/second-brain.html&quot;&gt;this idea&lt;/a&gt; many years ago from @Ernesto Kiszkurno and have written more than 500 technical articles since then.&lt;/p&gt;
&lt;h3 id=&quot;prompt-reference&quot;&gt;Prompt Reference&lt;/h3&gt;
&lt;h3 id=&quot;bad-article&quot;&gt;Bad Article&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Create a note about the movie
&quot;Howl's Moving Castle&quot;.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;good-article&quot;&gt;Good Article&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;---
title: &quot;Howl's Moving Castle&quot;
type: movie-note
status: draft
director: Hayao Miyazaki
year: 2004
genre: [fantasy, animation, anti-war]
rating: 9/10
tags: [ghibli, miyazaki, adaptation]
related: [&quot;Studio Ghibli&quot;, &quot;Diana Wynne Jones&quot;]
created: 2026-05-16
expected publish date: 2026-06-12
---

## Poster
_ _ _
IMPORT IMAGE Howls-moving-castleposter.jpg
_ _ _

## Summary
Two or three lines describing the plot without
spoiling the ending.

## Themes to Explore
Bullet list of ideas: anti-war message,
identity and transformation, Sophie's arc,
Miyazaki's pacifism compared to the novel.

## Characters
Use wikilinks: [Howl], [Sophie Hatter],
[Calcifer], [The Witch of the Waste].

## Article Ideas
Numbered list of angles for a critical article:
compare Miyazaki's changes from the Diana Wynne
Jones novel, analyze the anti-war allegory,
explore the feminist reading of Sophie's curse.

## Related Notes
[Studio Ghibli filmography]
[Diana Wynne Jones bibliography]
[War themes in animation]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;considerations-&quot;&gt;Considerations ⚠️&lt;/h2&gt;
&lt;p&gt;Keep your notes in plain Markdown files, not HTML (despite current trends) or proprietary formats.&lt;/p&gt;
&lt;p&gt;Markdown is readable by both humans and LLMs, diffs cleanly in Git, and works with every static site generator.&lt;/p&gt;
&lt;p&gt;Don't use MCP connectors or remote APIs to give your AI access to your vault. &lt;/p&gt;
&lt;p&gt;Point it directly at local files instead.&lt;/p&gt;
&lt;p&gt;Direct file access is faster, cheaper, and requires no extra infrastructure.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;AGENTS.md&lt;/code&gt; files you create per project are part of your Second Brain, not separate from it.&lt;/p&gt;
&lt;p&gt;If you have privacy concerns about cloud AI providers reading your notes, run a local model with Ollama or LM Studio through OpenClaw.&lt;/p&gt;
&lt;p&gt;Your data never leaves your machine or private cloud.&lt;/p&gt;
&lt;p&gt;Mind maps and Canvas diagrams in Obsidian help you visualize codebase architecture and sprint planning spatially, while the linked Markdown notes behind each node stay searchable by your AI.&lt;/p&gt;
&lt;p&gt;Your files are local.&lt;/p&gt;
&lt;p&gt;Nobody can see them, nobody can index them, and you can open any note with the simplest text editor in the world.&lt;/p&gt;
&lt;p&gt;If you use a cloud AI model instead of a local one, you can add a guardrail to restrict what files the AI can read, so sensitive notes never leave your control.&lt;/p&gt;
&lt;h2 id=&quot;type&quot;&gt;Type&lt;/h2&gt;
&lt;p&gt;[X] Semi-Automatic&lt;/p&gt;
&lt;h2 id=&quot;limitations-&quot;&gt;Limitations ⚠️&lt;/h2&gt;
&lt;p&gt;Large vaults with thousands of notes can slow down semantic search and local LLM indexing on low-end hardware.&lt;/p&gt;
&lt;p&gt;Front matter requires discipline to maintain consistently: inconsistent metadata reduces query quality over time.&lt;/p&gt;
&lt;p&gt;Local LLMs powerful enough to reason over a large vault require significant RAM (16 GB minimum, 32 GB recommended).&lt;/p&gt;
&lt;h2 id=&quot;tags-&quot;&gt;Tags ️&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Knowledge Management&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;level&quot;&gt;Level&lt;/h2&gt;
&lt;p&gt;[X] Intermediate&lt;/p&gt;
&lt;h2 id=&quot;related-tips&quot;&gt;Related Tips&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://coderlegion.com/12537/ai-coding-tip-010-access-all-your-code&quot;&gt;https://coderlegion.com/12537/ai-coding-tip-010-access-all-your-code&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://coderlegion.com/14016/ai-coding-tip-014-use-nested-agents-md-files&quot;&gt;https://coderlegion.com/14016/ai-coding-tip-014-use-nested-agents-md-files&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://coderlegion.com/16461/ai-coding-tip-018-use-voice-driven-development&quot;&gt;https://coderlegion.com/16461/ai-coding-tip-018-use-voice-driven-development&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Your biological brain is for having ideas, not storing them.&lt;/p&gt;
&lt;p&gt;Build a Second Brain from local Markdown files and give your AI direct access to it.&lt;/p&gt;
&lt;p&gt;You get persistent context, pattern discovery, and a knowledge base that compounds every time you use it. &lt;/p&gt;
&lt;h2 id=&quot;more-information-&quot;&gt;More Information ℹ️&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://zettelkasten.de/introduction/&quot;&gt;https://zettelkasten.de/introduction/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://obsidian.md&quot;&gt;https://obsidian.md&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://x.com/2039805659525644595&quot;&gt;https://x.com/2039805659525644595&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://en.wikipedia.org/wiki/Book_design#Front_matter&quot;&gt;https://en.wikipedia.org/wiki/Book_design#Front_matter&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://blacksmithgu.github.io/obsidian-dataview/&quot;&gt;https://blacksmithgu.github.io/obsidian-dataview/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f&quot;&gt;https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://foambubble.github.io/foam/&quot;&gt;https://foambubble.github.io/foam/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.buildingasecondbrain.com/&quot;&gt;https://www.buildingasecondbrain.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://ernestokiszkurno.blogspot.com/2021/08/second-brain.html&quot;&gt;https://ernestokiszkurno.blogspot.com/2021/08/second-brain.html&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;also-known-as&quot;&gt;Also Known As&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Personal-Knowledge-Management&lt;/li&gt;
&lt;li&gt;AI-Memory-Extension&lt;/li&gt;
&lt;li&gt;Developer-Second-Brain&lt;/li&gt;
&lt;li&gt;Local-Knowledge-Base&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;tools&quot;&gt;Tools&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://obsidian.md&quot;&gt;Obsidian&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://logseq.com&quot;&gt;Logseq&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://foambubble.github.io/foam/&quot;&gt;Foam&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/refactoringhq/tolaria&quot;&gt;Tolaria&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://blacksmithgu.github.io/obsidian-dataview/&quot;&gt;Dataview Plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://openclaw.ai/&quot;&gt;OpenClaw&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://ollama.com&quot;&gt;Ollama&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://lmstudio.ai&quot;&gt;LM Studio&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;disclaimer&quot;&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;The views expressed here are my own.&lt;/p&gt;
&lt;p&gt;I am a human who writes as best as possible for other humans. &lt;/p&gt;
&lt;p&gt;I use AI proofreading tools to improve some texts.&lt;/p&gt;
&lt;p&gt;I welcome constructive criticism and dialogue.&lt;/p&gt;
&lt;p&gt;I shape these insights through 30 years in the software industry, 25 years of teaching, and writing over 500 articles and a book.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;This article is part of the &lt;em&gt;AI Coding Tip&lt;/em&gt; series.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://coderlegion.com/12469/ai-coding-tips&quot;&gt;https://coderlegion.com/12469/ai-coding-tips&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/18160/ai-coding-tip-020-create-a-second-brain</guid>
<pubDate>Sun, 17 May 2026 14:35:33 +0000</pubDate>
</item>
<item>
<title>Jules AI - The (Currently) Free Coding Assistant That Can't Follow Directions But Gets Shit Done</title>
<link>https://coderlegion.com/4045/jules-the-currently-free-coding-assistant-that-cant-follow-directions-but-gets-shit-done</link>
<description>&lt;p&gt;&lt;img src=&quot;https://www.stephanmiller.com/images/2025/jules-ai-coding.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Jules is currently free, so I figured it was worth a try. Of course, I had to find out what I could break.&lt;/p&gt;
&lt;p&gt;Each user gets these default limits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;5 concurrent tasks&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;60 total tasks per day&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;5 codecasts per day&lt;/strong&gt; (still not sure what this means)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sixty tasks a day for free? That’s really generous and it meant I didn’t have to worry about reading documentation or instructions the first time.&lt;/p&gt;
&lt;h3 id=&quot;i-jumped-in-feet-first&quot;&gt;I Jumped in Feet First&lt;/h3&gt;
&lt;p&gt;My Obsidian plugin worked well enough for me to use it, but there were issues. Issues that I’d been ignoring because the damn thing worked and I had other shit to do. But I finally added issues to my GitHub repo.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.stephanmiller.com/images/2025/obsidian-plugin-github-issues.png&quot; alt=&quot;obsidian-plugin-github-issues&quot;&gt;&lt;/p&gt;
&lt;p&gt;Four issues. Nothing too crazy. Should be straightforward for an AI that can supposedly code.&lt;/p&gt;
&lt;p&gt;I gave Jules access to the repo and told it: “I want you to work on the issues in this repository and create a feature branch for each fix. Start with the first one.”&lt;/p&gt;
&lt;p&gt;Simple enough, right?&lt;/p&gt;
&lt;h3 id=&quot;jules-decides-to-ignore-my-instructions&quot;&gt;Jules Decides to Ignore My Instructions&lt;/h3&gt;
&lt;p&gt;Jules fetched the repo, cloned it into a VM, and read the README file. But then it discovered the “Future Enhancements” section I’d added to the README and decided that’s what it wanted to work on instead.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.stephanmiller.com/images/2025/obsidian-plugin-future-enhancements.png&quot; alt=&quot;obsidian-plugin-future-enhancements&quot;&gt;&lt;/p&gt;
&lt;p&gt;It completely ignored my instruction to work on the issues, the same issues that are listed right above the “Future Enhancements” section, and decided it would work on the “Interactive book selection dialog” instead.&lt;/p&gt;
&lt;p&gt;Jules then asked me to approve the plan, but I didn’t see any way to reject it. It was going to auto-approve in about a minute anyway. I thought maybe clicking “Approve” would launch a modal where I could say “no, you illiterate AI, work on the issues I told you to work on.”&lt;/p&gt;
&lt;p&gt;It did not.&lt;/p&gt;
&lt;p&gt;So it started working on the wrong thing. I messaged “stop” and it replied: “I have stopped the current task. Is there something specific you would like me to do instead, or a different issue you’d like me to focus on from the README?”&lt;/p&gt;
&lt;p&gt;It paused for a few seconds and then continued doing exactly what it was doing before.&lt;/p&gt;
&lt;p&gt;Currently, as far as I can tell, the only way to reject a plan is to let it start, pause it manually, and then delete the entire task. User experience design at its finest.&lt;/p&gt;
&lt;p&gt;Jules finished the feature and gave me the option to click a button to create a feature branch. So now I had a new feature to test before I could fix the actual issues I wanted fixed.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.stephanmiller.com/images/2025/jules-obsidian-plugin-branch.png&quot; alt=&quot;jules-obsidian-plugin-branch&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;testing-the-feature-that-jules-built-while-ignoring-my-prompt&quot;&gt;Testing the Feature that Jules Built While Ignoring My Prompt&lt;/h3&gt;
&lt;p&gt;So I pulled the branch down to the Obsidian vault I use for testing, the one with all the plugins I’m developing loaded up. There was one error in the code, in unit tests I never asked Jules to add:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tests/main.test.ts:160:35 - error TS2554: Expected 0 arguments, but got 1.
sortAnnotationsByCFI: jest.fn((ann: Annotation[]) =&amp;gt; ann), // Simple pass-through
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I just deleted the broken test.&lt;/p&gt;
&lt;p&gt;It took me a while to figure out that the selection modal didn’t launch via the sidebar button like I expected. I had to hit Command+P and find the command to launch it. But you know what? It actually worked.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.stephanmiller.com/images/2025/ebook-selection-modal.png&quot; alt=&quot;ebook-selection-modal&quot;&gt;&lt;/p&gt;
&lt;p&gt;Since the feature worked, I merged the change and created a new release. Then I did some reading to figure out how to prevent Jules from going off on another tangent.&lt;/p&gt;
&lt;h3 id=&quot;back-to-fixing-bugs-this-time-with-feeling-&quot;&gt;Back to Fixing Bugs (This Time With Feeling)&lt;/h3&gt;
&lt;p&gt;I thought maybe I should be more descriptive, but there wasn’t much to be descriptive about. There are issues. I added them to the repo. They’re also in the README that I know Jules can access. Most of the &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/google-labs-code/jules-awesome-list&quot;&gt;example prompts&lt;/a&gt; are very short, shorter than what I’d already tried.&lt;/p&gt;
&lt;p&gt;So I tried again: “This github repo has 4 issues listed here: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/eristoddle/apple-books-annotation-import/issues&quot;&gt;https://github.com/eristoddle/apple-books-annotation-import/issues&lt;/a&gt;. Give me a plan for fixing the first issue. If you have no access to these, let me know. Do not do anything else.”&lt;/p&gt;
&lt;p&gt;This time it worked.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.stephanmiller.com/images/2025/jule-web-interface.png&quot; alt=&quot;jule-web-interface&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.stephanmiller.com/images/2025/jules-cover-fix-plan.png&quot; alt=&quot;jules-cover-fix-plan&quot;&gt;&lt;/p&gt;
&lt;p&gt;Both the accidental feature and the bug fix took very little time. I was actually surprised by the speed. But Jules created broken unit tests again. I figured maybe it was because I didn’t have my npm and node versions in the package.json, so I added those and deleted them again.&lt;/p&gt;
&lt;p&gt;It actually fixed the bug and at least doubled the number of book covers I was getting.&lt;/p&gt;
&lt;h3 id=&quot;the-great-color-mapping-mystery&quot;&gt;The Great Color Mapping Mystery&lt;/h3&gt;
&lt;p&gt;The second issue was about finding annotation colors.&lt;/p&gt;
&lt;p&gt;Me: “Fix this feature in the repo: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/eristoddle/apple-books-annotation-import/issues/5&quot;&gt;https://github.com/eristoddle/apple-books-annotation-import/issues/5&lt;/a&gt;. Do not do anything else.”&lt;/p&gt;
&lt;p&gt;I think “Do not do anything else” will be part of my prompt from now on.&lt;/p&gt;
&lt;p&gt;Jules said: “The code changes have been reviewed for syntactical correctness and logical soundness. Direct testing with an Apple Books database is not possible, so final validation will be up to the user.”&lt;/p&gt;
&lt;p&gt;Translation: “I changed some code and it compiles. Good luck!”&lt;/p&gt;
&lt;p&gt;After testing, I told Jules: “Now it seems like there are no annotation color indicators at all in the md files. Before they were all just purple. Now they are just not there at all.”&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.stephanmiller.com/images/2025/jules-annotation-color-message-two.png&quot; alt=&quot;jules-annotation-color-message-two&quot;&gt;&lt;/p&gt;
&lt;p&gt;The second attempt produced different colors, but they didn’t match the highlight colors in the Books app.&lt;/p&gt;
&lt;p&gt;I mapped the colors Jules gave me to the actual colors and told it about the differences: “The color images are back and there are a variety of them, but they do not match the colors in the Books app. Here is how they differ (Books app color → markdown color): underline → both yellow and underline, purple → no icon at all, pink → red, yellow → purple, blue → blue, green → green.”&lt;/p&gt;
&lt;p&gt;I even included the log showing the distinct annotation style values from my test database. So this bug took three interactions, but Jules finally got the color mapping right.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.stephanmiller.com/images/2025/obsidian-annotation-colors.png&quot; alt=&quot;obsidian-annotation-colors&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;taking-it-to-the-big-leagues&quot;&gt;Taking It to the Big Leagues&lt;/h3&gt;
&lt;p&gt;My main Apple Books account has 4000 books and over 60 books with highlights. When I first worked on this plugin, the database structure was different, so I wanted to make sure everything worked in the wild before calling it done.&lt;/p&gt;
&lt;p&gt;The plugin handled the larger database just fine. All the covers loaded correctly, and the color annotations matched what I saw in the Books app.&lt;/p&gt;
&lt;h3 id=&quot;everything-i-fixed-in-this-change&quot;&gt;Everything I Fixed In This Change&lt;/h3&gt;
&lt;p&gt;It took about two hours total, not counting the issue Jules couldn’t fix. I let it code while I took notes for this article, worked on Obsidian cleanup, and checked out Reddit for a while.&lt;/p&gt;
&lt;p&gt;Here’s what got implemented:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✅ New interactive ebook selection dialog:&lt;/strong&gt; By accident when I was asking Jules to fix issues, but I’m counting it as a win.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✅ Fixed finding ebook covers:&lt;/strong&gt; This was the original first issue. Jules doubled the number of covers the plugin could find.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✅ Fixed annotation color icons:&lt;/strong&gt; Took three tries and some detailed feedback, but now the colors match what’s in the Books app.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;✅ Fixed missing annotation dates:&lt;/strong&gt; This needed a second attempt. I had to tell Jules: “I have include dates set to true and include citations set to false. There are no dates in the markdown files though.” But it got it right the second time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;❌ Did not fix gibberish in epub chapter names:&lt;/strong&gt; This one turned into a nightmare. The TypeScript build error migrated from the tests that never worked. I tried to get Jules to fix it once and it failed. The second time it was thinking forever, so I tried Copilot in VS Code, and that fixed the build.&lt;/p&gt;
&lt;p&gt;But then there was a runtime error I’d run into before when Claude Code tried to use a Node.js ebook parsing package. Something about not being able to access the file system in Electron. I went round and round with Jules on this one and finally gave up.&lt;/p&gt;
&lt;p&gt;One thing I realized is that I could tell Jules to build the app to test the build and fix issues, but I had to make it a command. When I asked “Did you build the app to test it?” it said that wasn’t possible. But when I just told it to build the project, it did it.&lt;/p&gt;
&lt;p&gt;So I let it churn through fixing the build errors for 30 minutes. When I tested the result, the chapters still weren’t fixed. But I didn’t expect this one to be easy without doing some research first.&lt;/p&gt;
&lt;p&gt;I used 5 of my available 60 free tasks for the day.&lt;/p&gt;
&lt;h3 id=&quot;jules-fast-confused-but-generally-useful&quot;&gt;Jules: Fast, Confused, but Generally Useful&lt;/h3&gt;
&lt;p&gt;Jules is fast. That surprised me. At least until there’s back and forth on changes, then the conversation slows down.&lt;/p&gt;
&lt;p&gt;It was done with the next fix before I finished testing the previous one. I added one feature I didn’t plan on and fixed four issues in a little over an hour.&lt;/p&gt;
&lt;p&gt;But Jules went off on a weird tangent when I gave it what I thought were specific instructions. There seems to be no real interaction other than the first message and accepting the plan. I was worried about fixing issues in a branch it created if something didn’t work.&lt;/p&gt;
&lt;p&gt;Using a task like it was a chat and trying to fix more than one issue per task got confusing. Then I figured out I needed a different workflow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 chat per branch, but can do multiple related things&lt;/li&gt;
&lt;li&gt;1 chat can be as big as 1 feature&lt;/li&gt;
&lt;li&gt;Code review each branch&lt;/li&gt;
&lt;li&gt;If there are issues, go back to the chat and have Jules fix them&lt;/li&gt;
&lt;li&gt;If there are build errors, tell Jules specifically to build the app again, test, and fix any errors.&lt;/li&gt;
&lt;li&gt;Pull and test again&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I was used to my Claude Code process where everything happened in the branch I was on locally. The “Publish Branch” button in Jules seemed scary at first, but the second time I used it, it just pushed modifications to the existing branch. I was expecting merge conflicts or some other drama.&lt;/p&gt;
&lt;p&gt;Most things I asked Jules to do worked well, except for the chapter names issue. I also didn’t ask it to create unit tests, but it kept creating broken ones anyway. It each branch it created, I ran them once and if they failed, I deleted them. They mainly failed because of TypeScript type issues.&lt;/p&gt;
&lt;h3 id=&quot;the-future-of-lazy-coding&quot;&gt;The Future of Lazy Coding&lt;/h3&gt;
&lt;p&gt;Sixty tasks a day for free is generous. I’m planning to move everything I have to GitHub that isn’t already there and create issues for any feature ideas or bugs I encounter.&lt;/p&gt;
&lt;p&gt;I could envision a process where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A user puts in a support request&lt;/li&gt;
&lt;li&gt;An issue gets created on the repo&lt;/li&gt;
&lt;li&gt;I tell Jules to fix it&lt;/li&gt;
&lt;li&gt;Jules fixes it, creates a custom build, and the user tests it (don’t know about this, but I can dream)&lt;/li&gt;
&lt;li&gt;If the fix works, I merge it and create a new release&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’m not sure exactly how this process would work in practice, but the potential is there.&lt;/p&gt;
&lt;h3 id=&quot;verdict-worth-the-price-of-free&quot;&gt;Verdict: Worth the Price of Free&lt;/h3&gt;
&lt;p&gt;Jules isn’t perfect. It ignored my initial instructions, created broken unit tests, and couldn’t fix the most complex issue I threw at it. But it’s fast, it’s free for now, and it actually solved most of the problems I needed solved.&lt;/p&gt;
&lt;p&gt;In two hours, I got a new feature and fixed three out of four issues that had been sitting in my backlog. The fourth issue would have taken me some research into ePub structure even doing it manually.&lt;/p&gt;
&lt;p&gt;I’m definitely planning to shift more of my “vibe coding” projects to Jules. At 60 free tasks per day, I can afford to let it work on the boring stuff while I focus on the interesting problems. In fact, to use 60 tasks a day, I might have to try running concurrent tasks and I can do 5 of those.&lt;/p&gt;
&lt;p&gt;And if it goes off on another tangent and builds something I didn’t ask for? Well, sometimes the best features are the ones you never knew you needed.&lt;/p&gt;
</description>
<category>Java</category>
<guid isPermaLink="true">https://coderlegion.com/4045/jules-the-currently-free-coding-assistant-that-cant-follow-directions-but-gets-shit-done</guid>
<pubDate>Tue, 15 Jul 2025 17:40:55 +0000</pubDate>
</item>
<item>
<title>️ Obsidian: Restaurant's rating</title>
<link>https://coderlegion.com/1222/obsidian-restaurants-rating</link>
<description>&lt;h2 id=&quot;obsidian-restaurant-s-ratings&quot;&gt;Obsidian: Restaurant's Ratings&lt;/h2&gt;
&lt;p&gt;I have a very &lt;em&gt;bad memory&lt;/em&gt;, which is why I am so obsessed with having &lt;em&gt;systems&lt;/em&gt; that make it easier for me to &lt;em&gt;search&lt;/em&gt; for information. Many times, if I don't structure it very well, I won't &lt;em&gt;remember&lt;/em&gt; how I saved it and will end up &lt;em&gt;losing&lt;/em&gt; it anyway. This is a big part of why I like &lt;strong&gt;Obsidian&lt;/strong&gt; so much as a tool; it allows me to &lt;em&gt;structure&lt;/em&gt; things in a way very &lt;em&gt;similar&lt;/em&gt; to how I do it mentally, meaning in &lt;em&gt;relationships&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Due to this same lack of memory, I have encountered situations where, for example, I am someone who does not tolerate &lt;em&gt;spicy food&lt;/em&gt; very well. So, when I go to a &lt;em&gt;restaurant&lt;/em&gt; and want to order &lt;em&gt;chilaquiles&lt;/em&gt;, I don't remember if last time I ordered the &lt;em&gt;green&lt;/em&gt; ones and they were too spicy, or if they were fine, or if the &lt;em&gt;red&lt;/em&gt; ones were better, etc. To &lt;em&gt;solve&lt;/em&gt; this, as in many other &lt;em&gt;areas&lt;/em&gt; of my life, I have a system that helps me &lt;em&gt;organize&lt;/em&gt; this information so that I can &lt;em&gt;revisit&lt;/em&gt; it easily the next time I go to the restaurant. This way, I can see if I liked something, what &lt;em&gt;details&lt;/em&gt; it had, how much I liked it, etc.&lt;/p&gt;
&lt;h3 id=&quot;parts&quot;&gt;Parts&lt;/h3&gt;
&lt;p&gt;My system consists of 3 parts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Restaurant&lt;/strong&gt;: The establishment or &lt;em&gt;chain&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dish&lt;/strong&gt;: The specific dish I am going to &lt;em&gt;rate&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Journal&lt;/strong&gt;: This is usually &lt;em&gt;linked&lt;/em&gt; thanks to the fact that in my &lt;a rel=&quot;nofollow&quot; href=&quot;https://oscarlp6.dev/en/blogs/nutrition-system-obsidian/&quot;&gt;Journal&lt;/a&gt; I log my &lt;em&gt;meals&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;the-restaurant&quot;&gt;The Restaurant&lt;/h4&gt;
&lt;p&gt;I create a &lt;em&gt;note&lt;/em&gt; for the &lt;em&gt;restaurant&lt;/em&gt; because this will be the note I &lt;em&gt;visit&lt;/em&gt; when I return to that place. Additionally, I use this note so that, when creating a new &lt;em&gt;dish&lt;/em&gt;, it can be &lt;em&gt;linked&lt;/em&gt; to the &lt;strong&gt;restaurant&lt;/strong&gt; it &lt;em&gt;belongs to&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The structure is very &lt;em&gt;simple&lt;/em&gt;. For this example, I will use my &lt;em&gt;note&lt;/em&gt; about &lt;em&gt;McDonald's&lt;/em&gt;.&lt;/p&gt;
&lt;h5 id=&quot;general-structure&quot;&gt;General Structure&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;---
tags: 
- place 
- restaurant
---

#  McDonald's
## ⭐ Recommendations 

```dataview 
TABLE 
calificacion as &quot;Rating&quot; 
FROM [[]] 
WHERE calificacion 
```

##  Last Visit 
```dataview
LIST WITHOUT ID link(dateformat(file.cday, &quot;dd-MM-yyyy&quot;)) 
FROM [[]] 
SORT file.cday DESC 
LIMIT 1
```
&lt;/code&gt;&lt;/pre&gt;
&lt;h5 id=&quot;example-note&quot;&gt;Example Note&lt;/h5&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=4731947285665240848&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Now let's &lt;em&gt;break down&lt;/em&gt; each part of the note.&lt;/p&gt;
&lt;h5 id=&quot;tags&quot;&gt;Tags&lt;/h5&gt;
&lt;p&gt;The &lt;em&gt;restaurant&lt;/em&gt; notes have the following &lt;em&gt;tags&lt;/em&gt;: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Place&lt;/li&gt;
&lt;li&gt;Restaurant&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because my system includes various types of places, such as &lt;em&gt;companies&lt;/em&gt;, it is necessary to make the &lt;em&gt;distinction&lt;/em&gt; that it is a &lt;em&gt;restaurant&lt;/em&gt;.&lt;/p&gt;
&lt;h5 id=&quot;-recommendations&quot;&gt;⭐ Recommendations&lt;/h5&gt;
&lt;p&gt;The recommendations are nothing more than a &lt;a rel=&quot;nofollow&quot; href=&quot;https://oscarlp6.dev/blogs/obsidian-introduction/#-community&quot;&gt;Dataview&lt;/a&gt; view that &lt;em&gt;compiles&lt;/em&gt; all &lt;strong&gt;Dish&lt;/strong&gt; notes, which we will see later, and displays them along with the &lt;em&gt;rating&lt;/em&gt; I assigned. As shown in the image, I am a big &lt;em&gt;fan&lt;/em&gt; of &lt;strong&gt;McDonald's&lt;/strong&gt;.&lt;/p&gt;
&lt;h5 id=&quot;last-visit&quot;&gt;Last Visit&lt;/h5&gt;
&lt;p&gt;Finally, this section simply &lt;em&gt;searches&lt;/em&gt; for the most &lt;em&gt;recent&lt;/em&gt; entry that &lt;em&gt;references&lt;/em&gt; the &lt;em&gt;establishment&lt;/em&gt; and shows me the &lt;em&gt;corresponding&lt;/em&gt; note for that date.&lt;br&gt;
This is one of the parts I like the least because it &lt;em&gt;requires&lt;/em&gt; me to &lt;em&gt;explicitly&lt;/em&gt; mention the &lt;em&gt;establishment&lt;/em&gt; in my &lt;a rel=&quot;nofollow&quot; href=&quot;https://oscarlp6.dev/blogs/obsidian-journaling/&quot;&gt;Journal&lt;/a&gt; note. I want to improve the &lt;em&gt;query&lt;/em&gt; so that it &lt;em&gt;detects&lt;/em&gt; when I reference a dish linked to the establishment, but I haven't had time to do so.&lt;/p&gt;
&lt;h4 id=&quot;the-dish&quot;&gt;The Dish&lt;/h4&gt;
&lt;p&gt;This note refers to the &lt;em&gt;dish&lt;/em&gt; itself. I use this note from the &lt;em&gt;restaurant&lt;/em&gt;, &lt;em&gt;linking&lt;/em&gt; the note to the &lt;em&gt;restaurant&lt;/em&gt; in the title to later retrieve the &lt;em&gt;rating&lt;/em&gt;, but also to store nutritional information about the dish. This is more related to the &lt;em&gt;nutrition&lt;/em&gt; aspect, so I won’t cover it here.&lt;/p&gt;
&lt;h5 id=&quot;general-structure-1&quot;&gt;General Structure&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;---
calificacion: 5
tags:
  - dish
---

#  McMuffin Regular from [[McDonald's]]

My opinion on the food. Any *detail* I should remember.

##  Nutritional Information 
[Calories:: 310 kcal] 
[Proteins:: 12 g] 
[Fats:: 13 g] 
[Carbohydrates:: 20 g] 
[Fiber:: 2 g] 
[Sugars:: 2 g]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The dish has the &lt;em&gt;tag&lt;/em&gt; &lt;code&gt;dish&lt;/code&gt; to make it easier to &lt;em&gt;filter&lt;/em&gt; in &lt;em&gt;queries&lt;/em&gt;. Additionally, I include the &lt;em&gt;rating&lt;/em&gt; in the &lt;em&gt;metadata&lt;/em&gt; on a &lt;em&gt;scale&lt;/em&gt; from &lt;em&gt;1 to 5&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In the body of the note, I can &lt;em&gt;include&lt;/em&gt; any &lt;em&gt;relevant information&lt;/em&gt;, such as whether the food was too &lt;em&gt;spicy&lt;/em&gt;, if I should order it without &lt;em&gt;tomato&lt;/em&gt;, or anything I want to remember for my next visit.&lt;/p&gt;
&lt;h4 id=&quot;-journal&quot;&gt;✍ Journal&lt;/h4&gt;
&lt;p&gt;I won’t show my &lt;em&gt;journal&lt;/em&gt; because it contains private information, and besides, there isn’t much &lt;em&gt;complexity&lt;/em&gt; to it. It simply involves mentioning the &lt;em&gt;restaurant&lt;/em&gt; note in my &lt;em&gt;journal&lt;/em&gt; entry.&lt;br&gt;
Once again, this is the part of the &lt;em&gt;system&lt;/em&gt; that I like the least because it only works if it’s my first time at the place and I create dish notes, or if I make an &lt;em&gt;explicit mention&lt;/em&gt;.&lt;br&gt;
If you have a better idea on how to ensure that each time I mention a &lt;em&gt;dish&lt;/em&gt; note in my &lt;em&gt;meals&lt;/em&gt; section, it gets &lt;em&gt;&quot;logged&quot;&lt;/em&gt; as a visit, I would be very &lt;em&gt;grateful&lt;/em&gt; if you left me a comment.&lt;/p&gt;
&lt;h3 id=&quot;conclusion-1&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;This system in &lt;strong&gt;Obsidian&lt;/strong&gt; has allowed me to improve my organization and memory regarding restaurants and dishes I have tried. Although it has some areas for improvement, such as automating the last visit, its modular structure has been quite useful. In the end, the important thing is to have a system that adapts to my needs and can evolve over time. If you have suggestions on how to improve this methodology, I would love to hear them. Thanks for your time! &lt;/p&gt;
</description>
<category>Proj Mgmt Tools</category>
<guid isPermaLink="true">https://coderlegion.com/1222/obsidian-restaurants-rating</guid>
<pubDate>Mon, 24 Feb 2025 08:54:04 +0000</pubDate>
</item>
</channel>
</rss>