<?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: getobserver</title>
    <description>The latest articles on DEV Community by getobserver (@getobserver205).</description>
    <link>https://dev.to/getobserver205</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%2F4022749%2Fd03196c1-a202-492e-9bd5-a2b151e549f7.png</url>
      <title>DEV Community: getobserver</title>
      <link>https://dev.to/getobserver205</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/getobserver205"/>
    <language>en</language>
    <item>
      <title>Did anyone check with their own build web application to see how if AI generated code passes the code auditing? Try out today without uploading your project to third party server or giving access to any third party app. Share your feedback.</title>
      <dc:creator>getobserver</dc:creator>
      <pubDate>Wed, 30 Sep 2026 08:18:20 +0000</pubDate>
      <link>https://dev.to/getobserver205/did-anyone-check-with-their-own-build-web-application-to-see-how-if-ai-generated-code-passes-the-2dbc</link>
      <guid>https://dev.to/getobserver205/did-anyone-check-with-their-own-build-web-application-to-see-how-if-ai-generated-code-passes-the-2dbc</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/getobserver205/i-compared-an-offline-security-audit-with-sonarqube-on-4-real-projects-36a3" class="crayons-story__hidden-navigation-link"&gt;I Compared an Offline Security Audit With SonarQube on 4 Real Projects with Observer&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/getobserver205" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F4022749%2Fd03196c1-a202-492e-9bd5-a2b151e549f7.png" alt="getobserver205 profile" class="crayons-avatar__image" width="512" height="512"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/getobserver205" class="crayons-story__secondary fw-medium m:hidden"&gt;
              getobserver
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                getobserver
                
                
              
              &lt;div id="story-author-preview-content-4727320" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/getobserver205" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F4022749%2Fd03196c1-a202-492e-9bd5-a2b151e549f7.png" class="crayons-avatar__image" alt="" width="512" height="512"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;getobserver&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/getobserver205/i-compared-an-offline-security-audit-with-sonarqube-on-4-real-projects-36a3" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Sep 23&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/getobserver205/i-compared-an-offline-security-audit-with-sonarqube-on-4-real-projects-36a3" id="article-link-4727320"&gt;
          I Compared an Offline Security Audit With SonarQube on 4 Real Projects with Observer
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/security"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;security&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/php"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;php&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devtools"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devtools&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/getobserver205/i-compared-an-offline-security-audit-with-sonarqube-on-4-real-projects-36a3#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            2 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>I Compared an Offline Security Audit With SonarQube on 4 Real Projects with Observer</title>
      <dc:creator>getobserver</dc:creator>
      <pubDate>Wed, 23 Sep 2026 18:52:52 +0000</pubDate>
      <link>https://dev.to/getobserver205/i-compared-an-offline-security-audit-with-sonarqube-on-4-real-projects-36a3</link>
      <guid>https://dev.to/getobserver205/i-compared-an-offline-security-audit-with-sonarqube-on-4-real-projects-36a3</guid>
      <description>&lt;p&gt;I wasn't planning to compare Observer with SonarQube.&lt;/p&gt;

&lt;p&gt;I was just curious.&lt;/p&gt;

&lt;p&gt;I've been building Observer because I wanted a simpler first pass when looking at an unfamiliar codebase.&lt;/p&gt;

&lt;p&gt;The problem I kept running into was not finding enough information.&lt;/p&gt;

&lt;p&gt;It was having too much information and still not knowing where to start.&lt;/p&gt;

&lt;p&gt;So I built a local audit workflow around a simple question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"What should I look at first?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recently I decided to test that idea against SonarQube.&lt;/p&gt;

&lt;p&gt;I used the exact same 4 projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Monica&lt;/strong&gt;: Laravel&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WordPress&lt;/strong&gt;: PHP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OWASP Juice Shop&lt;/strong&gt;: Node.js&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FinDocAnalyzer&lt;/strong&gt;: Laravel&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The results from my tests
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Project&lt;/th&gt;
&lt;th&gt;Observer&lt;/th&gt;
&lt;th&gt;SonarQube&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Monica&lt;/td&gt;
&lt;td&gt;169&lt;/td&gt;
&lt;td&gt;2,530+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WordPress&lt;/td&gt;
&lt;td&gt;244&lt;/td&gt;
&lt;td&gt;2,470+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Juice Shop&lt;/td&gt;
&lt;td&gt;226&lt;/td&gt;
&lt;td&gt;312+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FinDocAnalyzer&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;63+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Measured on v0.6.0.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At first those numbers look strange.&lt;/p&gt;

&lt;p&gt;But I don't think they're really a "who found more?" comparison.&lt;/p&gt;

&lt;p&gt;The tools are doing different jobs.&lt;/p&gt;

&lt;p&gt;SonarQube has a broad code-quality and static-analysis focus.&lt;/p&gt;

&lt;p&gt;Observer is more focused on security triage and actionable findings.&lt;/p&gt;

&lt;p&gt;That difference was actually the most interesting part of the experiment.&lt;/p&gt;

&lt;p&gt;When I audit a project, I don't always want to start with a giant list.&lt;/p&gt;

&lt;p&gt;I want to quickly understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where are the risky areas?&lt;/li&gt;
&lt;li&gt;What should I investigate first?&lt;/li&gt;
&lt;li&gt;Where is the actual code?&lt;/li&gt;
&lt;li&gt;What can I do about it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's what Observer is trying to make easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  The basic workflow
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;observer analyze &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--out&lt;/span&gt; report.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It runs locally as a single binary and generates a self-contained HTML report. No account, no telemetry, and &lt;code&gt;--assert-offline&lt;/code&gt; enforces that your code never leaves your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's new in v0.7.0
&lt;/h2&gt;

&lt;p&gt;Running these comparisons exposed a few rough edges, and v0.7.0 fixes them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scans that don't hang.&lt;/strong&gt; Deep scans on large codebases used to be killed by a fixed 5-minute budget. Timeouts now scale with file count (a WordPress-sized repo of ~4,600 files gets roughly 7–9 minutes), and you can override them with &lt;code&gt;OBSERVER_SCAN_TIMEOUT=30m&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A time estimate up front.&lt;/strong&gt; After file discovery, Observer prints an estimate so you know what you're in for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fairer counts.&lt;/strong&gt; Semgrep now scans the same file set as Observer's built-in engine, with &lt;code&gt;vendor&lt;/code&gt;, &lt;code&gt;node_modules&lt;/code&gt;, &lt;code&gt;dist&lt;/code&gt;, &lt;code&gt;build&lt;/code&gt; and &lt;code&gt;*.min.js&lt;/code&gt; excluded, so finding counts are apples-to-apples.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A more honest comparison page.&lt;/strong&gt; The README and landing page now include a "Code leaves your machine?" row and label which engine (built-in, Semgrep, PHPStan) produced each finding.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Release notes: &lt;a href="https://github.com/sanks205/getobserver/releases/tag/v0.7.0" rel="noopener noreferrer"&gt;https://github.com/sanks205/getobserver/releases/tag/v0.7.0&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  I'm curious how you handle this
&lt;/h2&gt;

&lt;p&gt;When a code scan finishes, do you normally start with security findings, code quality, dependencies, runtime errors, or something else?&lt;/p&gt;

</description>
      <category>security</category>
      <category>opensource</category>
      <category>php</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Same Laravel app, 582 files — Built-in: 58 issues (31 High), With Semgrep+PHPStan: 348 issues (26 High, 297 Medium). See why built-in is for CI and deep is for pre-release. Offline, 1 command. Try on your app.</title>
      <dc:creator>getobserver</dc:creator>
      <pubDate>Tue, 15 Sep 2026 16:37:39 +0000</pubDate>
      <link>https://dev.to/getobserver205/same-laravel-app-582-files-built-in-58-issues-31-high-with-semgrepphpstan-348-issues-26-4gep</link>
      <guid>https://dev.to/getobserver205/same-laravel-app-582-files-built-in-58-issues-31-high-with-semgrepphpstan-348-issues-26-4gep</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/getobserver205/i-scanned-a-laravel-app-with-and-without-local-engines-the-dashboard-now-shows-the-difference-3fam" class="crayons-story__hidden-navigation-link"&gt;I scanned a Laravel app with and without local engines — the dashboard now shows the difference&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/getobserver205" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F4022749%2Fd03196c1-a202-492e-9bd5-a2b151e549f7.png" alt="getobserver205 profile" class="crayons-avatar__image" width="512" height="512"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/getobserver205" class="crayons-story__secondary fw-medium m:hidden"&gt;
              getobserver
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                getobserver
                
                
              
              &lt;div id="story-author-preview-content-4456395" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/getobserver205" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F4022749%2Fd03196c1-a202-492e-9bd5-a2b151e549f7.png" class="crayons-avatar__image" alt="" width="512" height="512"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;getobserver&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/getobserver205/i-scanned-a-laravel-app-with-and-without-local-engines-the-dashboard-now-shows-the-difference-3fam" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 21&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/getobserver205/i-scanned-a-laravel-app-with-and-without-local-engines-the-dashboard-now-shows-the-difference-3fam" id="article-link-4456395"&gt;
          I scanned a Laravel app with and without local engines — the dashboard now shows the difference
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag crayons-tag--filled  " href="/t/showdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;showdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/php"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;php&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/security"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;security&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devtools"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devtools&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/getobserver205/i-scanned-a-laravel-app-with-and-without-local-engines-the-dashboard-now-shows-the-difference-3fam#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              1&lt;span class="hidden s:inline"&gt;&amp;nbsp;comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>PersonalCleaner v1.3 — I Didn't Add More Features. I Made It Easier to Use.</title>
      <dc:creator>getobserver</dc:creator>
      <pubDate>Tue, 08 Sep 2026 16:30:00 +0000</pubDate>
      <link>https://dev.to/getobserver205/personalcleaner-v13-i-didnt-add-more-features-i-made-it-easier-to-use-bfc</link>
      <guid>https://dev.to/getobserver205/personalcleaner-v13-i-didnt-add-more-features-i-made-it-easier-to-use-bfc</guid>
      <description>&lt;p&gt;PersonalCleaner v1.3 — A Cleaner UI for a Cleaner Windows Experience 🧹&lt;/p&gt;

&lt;p&gt;When I released PersonalCleaner v1.2, I focused on building an honest Windows cleaner — no scareware, no fake "3,000 problems found!" warnings, and no unnecessary upsells.&lt;/p&gt;

&lt;p&gt;For v1.3, I decided to focus on something different:&lt;/p&gt;

&lt;p&gt;Make PersonalCleaner easier and more pleasant to use.&lt;/p&gt;

&lt;p&gt;The biggest change is the GUI/UX redesign.&lt;/p&gt;

&lt;p&gt;✨ What's new in v1.3?&lt;br&gt;
🎨 Cleaner, more modern desktop interface&lt;br&gt;
🧭 Simple sidebar navigation&lt;br&gt;
📊 New Dashboard with system overview and quick actions&lt;br&gt;
🧹 Improved Clean page with clearer cleanup options&lt;br&gt;
🪟 Smaller, centered default window&lt;br&gt;
⏳ New startup splash/loading experience&lt;br&gt;
📌 System tray support&lt;br&gt;
💾 Tray preference is remembered between launches&lt;br&gt;
🤫 Background maintenance can run silently without opening the main window&lt;br&gt;
👀 See it in action&lt;/p&gt;

&lt;p&gt;Instead of explaining the new UI with a long list of screenshots, here's a quick demo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fas3l0nq0li3bxruzxi5c.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fas3l0nq0li3bxruzxi5c.gif" alt="PersonalCleaner v1.3 dashboard and cleanup UI demo" width="560" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Open → understand → choose → clean.&lt;/p&gt;

&lt;p&gt;No complicated menus. No confusing workflow.&lt;/p&gt;

&lt;p&gt;🧠 Same philosophy. Better experience.&lt;/p&gt;

&lt;p&gt;The interface changed, but the philosophy didn't.&lt;/p&gt;

&lt;p&gt;PersonalCleaner is still:&lt;/p&gt;

&lt;p&gt;Free • Open Source • MIT Licensed • Local • No scareware&lt;/p&gt;

&lt;p&gt;You can see exactly what you're about to clean before taking action.&lt;/p&gt;

&lt;p&gt;🚀 Get PersonalCleaner v1.3&lt;/p&gt;

&lt;p&gt;PersonalCleaner v1.3 is available now.&lt;/p&gt;

&lt;p&gt;👉 Download PersonalCleaner v1.3&lt;/p&gt;

&lt;p&gt;It's free to try, and the source code is available on GitHub.&lt;/p&gt;

&lt;p&gt;If you try it, I'd love to hear what you think about the new UI/UX — especially what feels intuitive and what still needs improvement.&lt;/p&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>showdev</category>
      <category>tooling</category>
    </item>
    <item>
      <title>I scanned a Laravel app with and without local engines — the dashboard now shows the difference</title>
      <dc:creator>getobserver</dc:creator>
      <pubDate>Fri, 21 Aug 2026 19:38:42 +0000</pubDate>
      <link>https://dev.to/getobserver205/i-scanned-a-laravel-app-with-and-without-local-engines-the-dashboard-now-shows-the-difference-3fam</link>
      <guid>https://dev.to/getobserver205/i-scanned-a-laravel-app-with-and-without-local-engines-the-dashboard-now-shows-the-difference-3fam</guid>
      <description>&lt;p&gt;You point Observer at a Laravel repo and it scans. Easy. But here's the thing I kept getting asked:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which engine actually found what? And what changes if I install Semgrep or PHPStan?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Good question. In v0.6.0 the dashboard answers both, right in the scan history. Every past scan now shows an &lt;strong&gt;Engines&lt;/strong&gt; column — a pill for each engine that ran (Semgrep, PHPStan, Bandit, gosec, ESLint), or a plain &lt;strong&gt;Built-in&lt;/strong&gt; badge when you scanned with no local engines installed. There's a legend too, and scans are sorted newest-first so the comparison you care about is always at the top.&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%2Fwmujn5qd69e6lwrlrul4.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%2Fwmujn5qd69e6lwrlrul4.png" alt="Observer dashboard scan history — the Engines column shows a Built-in badge next to Semgrep and PHPStan pills" width="800" height="972"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No flags. Observer auto-detects whatever you have installed and runs it. Install more → deeper scan. Uninstall → still works, just faster and built-in only.&lt;/p&gt;

&lt;h2&gt;
  
  
  The demo: one Laravel app, two scans
&lt;/h2&gt;

&lt;p&gt;I scanned the same project twice — &lt;strong&gt;FinDocAnalyzer&lt;/strong&gt;, a Laravel + MySQL app (582 files). First with zero local engines, then again with &lt;strong&gt;Semgrep&lt;/strong&gt; and &lt;strong&gt;PHPStan&lt;/strong&gt; installed. Same code, same machine, just a different toolchain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scan 1 — Built-in only (no engines installed)
&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%2F72zjee9thojsf6o4kjgx.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%2F72zjee9thojsf6o4kjgx.png" alt="Observer report summary for a built-in-only Laravel scan — 58 issues, Built-in badge" width="799" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;58 issues&lt;/strong&gt; — 31 high, 2 medium, 25 low&lt;/li&gt;
&lt;li&gt;Security &lt;strong&gt;79 / C&lt;/strong&gt;, Health &lt;strong&gt;99 / A&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Took &lt;strong&gt;39.9s&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Dashboard shows: &lt;strong&gt;Built-in&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the "no setup" path. Observer runs its own offline rules — secrets in commits, raw SQL concatenation, &lt;code&gt;APP_DEBUG=true&lt;/code&gt; in prod, unguarded &lt;code&gt;eval&lt;/code&gt;, that kind of thing. Fast, zero dependencies, catches the scary patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scan 2 — With Semgrep + PHPStan installed
&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%2Fpj7bm22wxy962ljjyg13.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%2Fpj7bm22wxy962ljjyg13.png" alt="Observer report summary for a Laravel scan with Semgrep and PHPStan installed — 348 issues" width="799" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;348 issues&lt;/strong&gt; — 26 high, 297 medium, 25 low&lt;/li&gt;
&lt;li&gt;Security &lt;strong&gt;81 / B&lt;/strong&gt;, Health &lt;strong&gt;66 / D&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Took &lt;strong&gt;52.3s&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Dashboard shows: &lt;strong&gt;Semgrep · PHPStan&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The moment PHPStan and Semgrep are on &lt;code&gt;PATH&lt;/code&gt;, Observer picks them up and runs them — no config, no switches. Now the same 582 files get &lt;strong&gt;type-aware&lt;/strong&gt; analysis: PHPStan's &lt;code&gt;argument.type&lt;/code&gt; / &lt;code&gt;return.type&lt;/code&gt; / mass-assignment findings, Semgrep's taint and framework-specific rules. The issue count jumps from 58 to 348 mostly because of &lt;em&gt;medium&lt;/em&gt; findings that only a real type-checker can see.&lt;/p&gt;

&lt;h2&gt;
  
  
  So which one should you run?
&lt;/h2&gt;

&lt;p&gt;Neither is "wrong." They're a speed-vs-depth tradeoff you now control:&lt;/p&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;Built-in&lt;/th&gt;
&lt;th&gt;With engines&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Setup&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;install Semgrep + PHPStan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Issues&lt;/td&gt;
&lt;td&gt;58&lt;/td&gt;
&lt;td&gt;348&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;31&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;297&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Health&lt;/td&gt;
&lt;td&gt;99 / A&lt;/td&gt;
&lt;td&gt;66 / D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time&lt;/td&gt;
&lt;td&gt;39.9s&lt;/td&gt;
&lt;td&gt;52.3s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notice the built-in scan flagged &lt;strong&gt;more "high"&lt;/strong&gt; findings (31 vs 26). That's not because it's smarter — it's because without type context it can't downgrade a pattern that PHPStan proves is safe. Installing engines doesn't just add findings, it adds &lt;em&gt;judgement&lt;/em&gt;: fewer false highs, way more real mediums worth fixing.&lt;/p&gt;

&lt;p&gt;My rule of thumb:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CI on every push&lt;/strong&gt; → built-in. Fast, no extra deps, still catches the worst stuff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pre-release / deep audit&lt;/strong&gt; → install the engines once, get the type-aware pass.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And because the dashboard records the engine set per scan, you can literally watch the "Change" column flip from &lt;code&gt;-290&lt;/code&gt; (the built-in scan, 290 fewer than the deep one) to &lt;code&gt;+291&lt;/code&gt; (the deep scan, 291 more than the one before it) as you add tooling. The history tells the story.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
bash
# free, no engines needed
observer serve
# open http://127.0.0.1:7777, paste your project path, hit Scan

# want the deeper pass? just install the engines — Observer finds them:
composer global require phpstan/phpstan
pip install semgrep
# re-scan the same project — the Engines column now shows the pills
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>showdev</category>
      <category>php</category>
      <category>security</category>
      <category>devtools</category>
    </item>
    <item>
      <title>PersonalCleaner v1.2 — a free, open-source Windows cleaner with an honest Pro key</title>
      <dc:creator>getobserver</dc:creator>
      <pubDate>Thu, 13 Aug 2026 15:12:06 +0000</pubDate>
      <link>https://dev.to/getobserver205/personalcleaner-v12-a-free-open-source-windows-cleaner-with-an-honest-pro-key-141j</link>
      <guid>https://dev.to/getobserver205/personalcleaner-v12-a-free-open-source-windows-cleaner-with-an-honest-pro-key-141j</guid>
      <description>&lt;p&gt;Every "PC cleaner" shows you a scary number and asks for money. I got tired of that, so I built one that shows real numbers — and lets you verify every line.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PersonalCleaner&lt;/strong&gt; is free and open source. v1.2 is out, and it adds an optional &lt;strong&gt;Pro key&lt;/strong&gt; for people who want automation. Here's the whole story.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Portable, no installer, no account.&lt;/li&gt;
&lt;li&gt;100% local — it makes &lt;strong&gt;zero network calls&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Open source (MIT) — one readable Python file. Audit it yourself.&lt;/li&gt;
&lt;li&gt;No fake "3,000 problems!" — every number is a real Windows measurement (temp files, RAM, startup entries).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Free, always
&lt;/h2&gt;

&lt;p&gt;The free build does the maintenance that matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧊 Catch frozen apps and close them safely&lt;/li&gt;
&lt;li&gt;🧠 Free up RAM (real before/after numbers)&lt;/li&gt;
&lt;li&gt;🧹 Clean junk (temp files older than 24h, known folders only)&lt;/li&gt;
&lt;li&gt;🚀 Startup manager&lt;/li&gt;
&lt;li&gt;🪟 Restart Explorer / close a stuck app&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  v1.2: the honest Pro split
&lt;/h2&gt;

&lt;p&gt;One thing I care about: not lying to users. So v1.2 ships a &lt;strong&gt;single build&lt;/strong&gt;. Free features work with no key. Four power-user features are locked until you enter a Pro key:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌙 &lt;strong&gt;Background automation&lt;/strong&gt; — silent upkeep on idle + daily&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Weekly idle restart&lt;/strong&gt; — only when you're away&lt;/li&gt;
&lt;li&gt;⚙️ &lt;strong&gt;Defender exclusions&lt;/strong&gt; — stop AV slowing your dev builds&lt;/li&gt;
&lt;li&gt;🔧 &lt;strong&gt;Service tuning&lt;/strong&gt; — cut background load, reversible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You unlock them in-app: type &lt;code&gt;L1&lt;/code&gt;, paste your key. Done. No account, no cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a key at all?
&lt;/h2&gt;

&lt;p&gt;Hosting, code-signing, and time cost money — and I'd rather be upfront than hide it. The license is an &lt;strong&gt;offline HMAC-signed key&lt;/strong&gt;, machine-locked, valid 1 year. A one-time payment. No subscription, no auto-renew, no phone-home. It's honor-based, not DRM — the validation code is public so you can verify it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trust
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Scanned on VirusTotal: v1.2 = &lt;strong&gt;0/67 clean&lt;/strong&gt;. (An earlier build showed 1/71 — the one hit was Microsoft Defender, a known false positive for unsigned PyInstaller apps. Not malware.)&lt;/li&gt;
&lt;li&gt;Not code-signed yet → one-time SmartScreen "Run anyway" on first launch. Expected.&lt;/li&gt;
&lt;li&gt;The free app is fully open source. Read it before you run it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🆓 Free (GitHub): &lt;a href="https://github.com/sanks205/PersonalCleaner" rel="noopener noreferrer"&gt;https://github.com/sanks205/PersonalCleaner&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔑 Pro key (1-year license, one-time payment): &lt;a href="https://observerly1.gumroad.com/l/ialzp" rel="noopener noreferrer"&gt;https://observerly1.gumroad.com/l/ialzp&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't trust your PC cleaner. Verify it.&lt;/p&gt;

</description>
      <category>microsoft</category>
      <category>python</category>
      <category>opensource</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>I built an offline Windows cleanup CLI in Python+Tkinter - MIT, no Electron, no phone-home</title>
      <dc:creator>getobserver</dc:creator>
      <pubDate>Sat, 08 Aug 2026 09:54:00 +0000</pubDate>
      <link>https://dev.to/getobserver205/i-built-a-windows-pc-cleaner-that-doesnt-lie-to-you-and-open-sourced-it-2ig1</link>
      <guid>https://dev.to/getobserver205/i-built-a-windows-pc-cleaner-that-doesnt-lie-to-you-and-open-sourced-it-2ig1</guid>
      <description>&lt;p&gt;Most "PC cleaners" are scareware: fake error counts, upsell popups, background&lt;br&gt;
services you never asked for. I got tired of that, so I built my own - as a proper&lt;br&gt;
dev tool, not a consumer product.&lt;/p&gt;

&lt;p&gt;It's &lt;strong&gt;Python + Tkinter&lt;/strong&gt;, packaged with &lt;strong&gt;PyInstaller&lt;/strong&gt; (no Electron bloat, no&lt;br&gt;
background services in the free build), and it runs &lt;strong&gt;100% offline&lt;/strong&gt;. Every number&lt;br&gt;
it shows comes straight from real Windows APIs (temp files, RAM, startup entries) -&lt;br&gt;
not a fabricated counter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why developers care
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No Electron, no background processes&lt;/strong&gt; - the free build is a single portable exe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real Windows APIs&lt;/strong&gt; - the numbers are actual temp-file sizes, RAM usage, startup
entries. Audit the code yourself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline Pro key&lt;/strong&gt; - the optional Pro license is HMAC-signed and machine-locked.
No phone-home licensing, no cloud.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MIT-licensed&lt;/strong&gt; - read exactly what it touches before you run it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What it does (free, open source)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scan &amp;amp; fix now&lt;/strong&gt; - real junk, cached RAM, health check&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free RAM now&lt;/strong&gt; - one-click memory release&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Startup manager&lt;/strong&gt; - see &amp;amp; control what runs at boot&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Close a stuck app&lt;/strong&gt; - mini task manager&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restart Explorer&lt;/strong&gt; - fix a hung taskbar instantly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Activity log &amp;amp; history&lt;/strong&gt; - see everything it did&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Never touches critical Windows system files. No "you have 3,000 problems!" alerts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pro version
&lt;/h2&gt;

&lt;p&gt;Basic maintenance stays free on GitHub. Pro adds background auto-clean, weekly idle&lt;br&gt;
restart, antivirus exclusions (stop Defender slowing your builds), and service tuning.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One-time fee, 1-year per-PC key (tied to your machine, works 100% offline)&lt;/li&gt;
&lt;li&gt;One key, one computer - no subscriptions, no cloud&lt;/li&gt;
&lt;li&gt;Unlocks via an in-app &lt;code&gt;L1&lt;/code&gt; menu&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;v1.2 is out and scanned clean on VirusTotal (0/67).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/sanks205/PersonalCleaner" rel="noopener noreferrer"&gt;https://github.com/sanks205/PersonalCleaner&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Pro: &lt;a href="https://observerly1.gumroad.com/l/ialzp" rel="noopener noreferrer"&gt;https://observerly1.gumroad.com/l/ialzp&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've ever wondered whether a "PC cleaner" actually does anything - this one's&lt;br&gt;
code is right there to check.&lt;/p&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>showdev</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Auditing a Laravel App's Security in One Command (No Terminal Required)</title>
      <dc:creator>getobserver</dc:creator>
      <pubDate>Sun, 19 Jul 2026 21:26:07 +0000</pubDate>
      <link>https://dev.to/getobserver205/auditing-a-laravel-apps-security-in-one-command-no-terminal-required-23h8</link>
      <guid>https://dev.to/getobserver205/auditing-a-laravel-apps-security-in-one-command-no-terminal-required-23h8</guid>
      <description>&lt;p&gt;Most security tools ask a lot of you before they tell you anything: create a cloud account, wire up CI, install a scanner and its dependencies, maybe send your code to a server. Sometimes you just want an honest snapshot of where a Laravel app stands — locally, right now, before a launch or a client handover.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; — &lt;a href="https://github.com/sanks205/getobserver" rel="noopener noreferrer"&gt;Observer&lt;/a&gt; is a free, MIT, single-binary tool that audits a Laravel app for security &amp;amp; production-health issues — offline, no account. Point it at your project (or just double-click it) and get one HTML report. &lt;strong&gt;&lt;a href="https://github.com/sanks205/getobserver/releases/latest" rel="noopener noreferrer"&gt;⬇️ Download it →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's the gap &lt;a href="https://github.com/sanks205/getobserver" rel="noopener noreferrer"&gt;Observer&lt;/a&gt; fills. It's a single offline binary (free and MIT) that scans a codebase for security and production-health issues and writes &lt;strong&gt;one self-contained HTML report&lt;/strong&gt; — no account, no telemetry, nothing installed on your system. Point it at a project, open the report. This post walks through auditing a Laravel app with it end to end.&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%2F02yg7ks25mh9ouiiia5y.gif" 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%2F02yg7ks25mh9ouiiia5y.gif" alt=" " width="600" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;p&gt;No runtime, no dependencies, no account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Easiest — download &amp;amp; double-click.&lt;/strong&gt; Grab the binary for your OS from the &lt;a href="https://github.com/sanks205/getobserver/releases/latest" rel="noopener noreferrer"&gt;releases page&lt;/a&gt; and double-click it: Observer opens a dashboard in your browser, you paste a folder, hit &lt;strong&gt;Scan&lt;/strong&gt;, done. No command line.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prefer the terminal?&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="c"&gt;# macOS / Linux&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;https://raw.githubusercontent.com/sanks205/getobserver/main/packaging/homebrew/observer.rb
&lt;span class="c"&gt;# Windows&lt;/span&gt;
scoop &lt;span class="nb"&gt;install &lt;/span&gt;https://raw.githubusercontent.com/sanks205/getobserver/main/packaging/scoop/observer.json
&lt;span class="c"&gt;# Go&lt;/span&gt;
go &lt;span class="nb"&gt;install &lt;/span&gt;github.com/sanks205/getobserver/cmd/cli@latest

&lt;span class="c"&gt;## The one command&lt;/span&gt;

From the root of your Laravel project:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
bash&lt;br&gt;
observer analyze . --out report.html&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
That's the whole audit. Observer detects the stack (Laravel, the PHP version, your database), scans the code, inspects your config and dependencies, scores the project, and writes `report.html`. Open it in a browser — or print it to PDF to hand to a client.

## Reading the report

The report leads with a **Security Rating (A–E)** — the same worst-severity-present model tools like SonarQube use, grounded in CVSS/CWE/OWASP — alongside 0–100 Security and Code Health scores. Below that, a **"Fix These First"** list surfaces the highest-impact issues, and findings are **grouped by rule** so a large app collapses into a few dozen scannable groups instead of an endless wall. Every finding carries a severity, a file/line, and a **before → after fix** you can act on immediately.

## What it flags on a Laravel app

Out of the box, the free core catches the things that most often bite Laravel apps in production:

- **Secrets and config** — Observer inspects your `.env` and config files for committed secrets, `APP_DEBUG=true` shipped to production, and hardcoded API keys in code.
- **Injection-prone queries** — raw SQL built with string concatenation (`DB::select("... " . $id)`) instead of bindings.
- **Dependency CVEs** — add `--cve` and it checks your `composer.json` against [OSV.dev](https://osv.dev) for known-vulnerable packages.
- **Infrastructure &amp;amp; config** — Dockerfiles, `docker-compose`, Kubernetes manifests, and nginx/Apache configs for misconfigurations (running as root, `:latest`, exposed DB ports, obsolete TLS).

For deeper, framework-aware rules — unescaped Blade (`{!! !!}`), mass-assignment, `APP_KEY` handling, Eloquent raw expressions, and packs for CodeIgniter, WordPress, Symfony, Django, Rails and Spring — there's an optional one-time [Observer Pro](https://observerly1.gumroad.com) add-on. The free core stands on its own for a solid audit; Pro layers Laravel-specific depth on top.

## No command line? Double-click it

The latest release (v0.4.0) added a zero-CLI path for teammates who don't live in a terminal: **double-click the binary** and Observer opens a local dashboard in your browser. Paste a folder, click **Scan**, and read the report — past scans, stack, and "new since last scan" all live on one page. Same engine, no typing.

## In CI

The same binary drops into a pipeline. Fail the build on new high-severity issues and emit SARIF for GitHub code scanning:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
bash&lt;br&gt;
observer analyze . --sarif observer.sarif --fail-on High&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Adopting it on an existing app? Record a baseline first, then report only *new* issues so you're not drowning in pre-existing debt:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
bash&lt;br&gt;
observer analyze . --write-baseline .observer-baseline.json&lt;br&gt;
observer analyze . --baseline .observer-baseline.json --fail-on Medium&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
## Offline and auditable

By default nothing leaves your machine — no account, no phone-home. For regulated or client-confidential work you can make that guarantee enforceable:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
bash&lt;br&gt;
observer analyze . --assert-offline&lt;/p&gt;



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


It refuses to run if any network-requiring flag was passed and prints `Offline mode: no network I/O.` so you can evidence it in an audit — useful for finance, healthcare, or reviewing a client's code under NDA.

## Wrap-up

Observer won't replace a continuous platform like SonarQube or an always-on monitor like Sentry — it's a different shape of tool: a fast, offline, one-command snapshot that unifies code, dependencies, config and infra into a single report you can read or share. For a pre-launch check, a legacy handover, or just seeing where a Laravel app really stands, it's about as low-friction as a security audit gets.

The core is free and MIT. Here's a 60-second challenge: **download it, double-click it, and scan your app** — then drop your **Security Rating (A–E)** in the comments. Most Laravel apps land on a C or D on the first scan. What does yours get?

👉 **[Download Observer](https://github.com/sanks205/getobserver/releases/latest)** — Windows / macOS / Linux, no install.
⭐ **[Star it on GitHub](https://github.com/sanks205/getobserver)** to grab it later when you need it.

If it catches something useful, a ⭐ on the repo genuinely helps other devs find it — and I'd love to hear what it flags on your project, good or bad, in the comments.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>devops</category>
      <category>security</category>
    </item>
    <item>
      <title>I built an offline CLI that audits a legacy PHP app in one command — and shows you the fix</title>
      <dc:creator>getobserver</dc:creator>
      <pubDate>Thu, 09 Jul 2026 18:04:00 +0000</pubDate>
      <link>https://dev.to/getobserver205/i-built-an-offline-cli-that-audits-a-legacy-php-app-in-one-command-and-shows-you-the-fix-5f6c</link>
      <guid>https://dev.to/getobserver205/i-built-an-offline-cli-that-audits-a-legacy-php-app-in-one-command-and-shows-you-the-fix-5f6c</guid>
      <description>&lt;p&gt;Every time I inherit a legacy PHP app — a CodeIgniter admin panel, an old Laravel service, a WordPress site someone's cousin built — &lt;strong&gt;day one is the same ritual&lt;/strong&gt;: grep for &lt;code&gt;password&lt;/code&gt;, squint at &lt;code&gt;config.php&lt;/code&gt;, wonder if &lt;code&gt;display_errors&lt;/code&gt; is on in prod, and hope there isn't a hardcoded API key waiting to ruin my week.&lt;/p&gt;

&lt;p&gt;So I built a tool to do that first pass for me, in one command, offline. It's called &lt;strong&gt;Observer&lt;/strong&gt;, it's a single Go binary, and it's free and MIT.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;observer analyze ./your-app &lt;span class="nt"&gt;--out&lt;/span&gt; report.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Point it at a folder, get one self-contained HTML report. No server, no account, no instrumentation, nothing sent anywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it actually found
&lt;/h2&gt;

&lt;p&gt;I ran it against a real CodeIgniter 3 admin app I'd picked up. A few seconds later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Project:   admin-panel
Language:  PHP
Framework: CodeIgniter 3 [High]
Database:  MySQL [High]

Security score: 81/100 (B)   Code health: 100/100 (A)
Static analysis: issues across secrets, config &amp;amp; dependencies

  [High]  application/config/firebase.php   Hardcoded Google API key
  [High]  index.php                         display_errors enabled
  [Med ]  composer.json                     End-of-life PHP version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;None of these are exotic. That's the point — the boring, high-impact stuff is exactly what gets missed on a handover, and it's what an attacker finds first. A hardcoded key in a config file that's sitting in the repo is a bad afternoon waiting to happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  It doesn't just flag — it shows the fix
&lt;/h2&gt;

&lt;p&gt;This is the part I care about most. Most free scanners hand you a wall of findings and leave you to Google each one. Every Observer finding carries a concrete &lt;strong&gt;before → after&lt;/strong&gt; fix, right in the report — no AI key required, fully offline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Before&lt;/span&gt;
&lt;span class="nv"&gt;$db&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"SELECT * FROM users WHERE id = "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// After&lt;/span&gt;
&lt;span class="nv"&gt;$db&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"SELECT * FROM users WHERE id = ?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each finding also gets a severity, a &lt;code&gt;file:line&lt;/code&gt;, and a CWE/OWASP tag, so you can triage instead of just staring.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it checks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security rules across PHP, JS/TS, Python, Java &amp;amp; Ruby&lt;/strong&gt; — hardcoded secrets, SQL injection, XSS, command execution, insecure deserialization, weak crypto, dangerous config&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency CVEs&lt;/strong&gt; via OSV.dev (&lt;code&gt;--cve&lt;/code&gt;) — Composer, npm, PyPI, Go&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Security score and a Code-Health score&lt;/strong&gt; (A–F) plus an estimated fix effort&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SARIF / JSON / CSV output + a GitHub Action&lt;/strong&gt;, so it drops into CI&lt;/li&gt;
&lt;li&gt;It also &lt;strong&gt;auto-detects Semgrep / PHPStan / Bandit / gosec&lt;/strong&gt; if you already have them, and folds their findings into the same report&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Offline by default (and provably so)
&lt;/h2&gt;

&lt;p&gt;No telemetry, no phone-home. The only things that touch the network are explicitly opt-in (&lt;code&gt;--cve&lt;/code&gt;, or &lt;code&gt;--ai&lt;/code&gt; &lt;em&gt;with&lt;/em&gt; your own OpenAI key). For regulated or client-confidential work there's a flag that makes it enforceable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;observer analyze ./client-app &lt;span class="nt"&gt;--assert-offline&lt;/span&gt;
&lt;span class="c"&gt;# Offline mode: no network I/O.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It refuses any network-touching option and keeps the AI on a local heuristic. Handy when you're auditing someone else's code under NDA and the code genuinely cannot leave the machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it's &lt;em&gt;not&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;It's not trying to replace SonarQube, Snyk, or Sentry. Those go deep in one dimension and want a server, a cloud account, or instrumentation. Observer is the opposite shape: a &lt;strong&gt;zero-setup, offline snapshot&lt;/strong&gt; for the moments those are too heavy — a legacy handover, a quick client audit, an air-gapped scan, or just "what's wrong with this thing I just cloned?" Run both; they answer different questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it / tell me what it misses
&lt;/h2&gt;

&lt;p&gt;It's genuinely free and MIT — grab a binary and point it at any repo:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/sanks205/getobserver" rel="noopener noreferrer"&gt;https://github.com/sanks205/getobserver&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are a few optional one-time paid add-ons (branded PDF reports, scheduled scans, deeper framework rule packs), but the whole core scanner is free with no account.&lt;/p&gt;

&lt;p&gt;This is early, and I'd really value feedback from people who work on older codebases: &lt;strong&gt;what did it flag that was noise? What rule would've actually saved you an afternoon?&lt;/strong&gt; Drop a comment — that's what I'm building from next.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>php</category>
      <category>security</category>
    </item>
  </channel>
</rss>
