added on local at 2026-07-13 19:42:24
| 1 | <div class="page-head"> | |
| 2 | <span class="page-eyebrow"><span class="dot"></span> Search captures</span> | |
| 3 | <h1 class="page-title">Grep every captured blob</h1> | |
| 4 | <p class="page-subtitle">Content search across the SHA-addressed blob store. Text files only (extensions like .pl .pm .cgi .js .css .html .md ...). Skips binaries and blobs > 512 KB. Scans the newest 5,000 unique captures.</p> | |
| 5 | </div> | |
| 6 | ||
| 7 | <div class="module glow-teal"> | |
| 8 | <div class="module-body"> | |
| 9 | <form method="get" action="/search.cgi" style="display:flex;gap:10px;align-items:center;flex-wrap:wrap"> | |
| 10 | <input type="text" name="q" value="$q_h" placeholder="Search text or /regex/ ..." autofocus | |
| 11 | style="flex:1 1 320px;min-width:240px;padding:9px 12px;background:var(--panel-2);border:1px solid var(--border);border-radius:8px;color:var(--text);font-family:var(--mono);font-size:13px"> | |
| 12 | [if:$has_monitors] | |
| 13 | <select name="mid" style="padding:9px 12px;background:var(--panel-2);border:1px solid var(--border);border-radius:8px;color:var(--text);font-size:13px"> | |
| 14 | <option value="0">All sites</option> | |
| 15 | [loop:@monitors]<option value="$mid"[if:$selected] selected[/if]>$label</option>[/loop] | |
| 16 | </select> | |
| 17 | [/if] | |
| 18 | <label style="display:flex;gap:5px;align-items:center;font-size:12.5px;color:var(--text-dim)"><input type="checkbox" name="case" value="1" [if:$case_sens]checked[/if]> case</label> | |
| 19 | <label style="display:flex;gap:5px;align-items:center;font-size:12.5px;color:var(--text-dim)"><input type="checkbox" name="regex" value="1" [if:$regex_mode]checked[/if]> regex</label> | |
| 20 | <button type="submit" class="tr-chip is-active" style="border:none;padding:9px 22px">Search</button> | |
| 21 | </form> | |
| 22 | </div> | |
| 23 | </div> | |
| 24 | ||
| 25 | [if:$has_error] | |
| 26 | <div class="module glow-rose" style="margin-top:16px"> | |
| 27 | <div class="module-head"><div class="left"> | |
| 28 | <div class="module-title">Search error</div> | |
| 29 | <span class="module-subtitle">Your query couldn't be parsed.</span> | |
| 30 | </div></div> | |
| 31 | <div class="module-body"><pre style="margin:0;color:var(--accent-danger-hi);font-family:var(--mono);font-size:12px">$error_msg</pre></div> | |
| 32 | </div> | |
| 33 | [/if] | |
| 34 | ||
| 35 | [if:$has_query][if:!$has_error] | |
| 36 | <div class="module" style="margin-top:16px"> | |
| 37 | <div class="module-head"><div class="left"> | |
| 38 | <div class="module-title">$hit_count hit[if:$hit_count]s[/if] across $matched_blobs blob[if:$matched_blobs]s[/if]</div> | |
| 39 | <span class="module-subtitle">Scanned $scanned unique captures. Each hit shows the first line matching in that file plus surrounding context.</span> | |
| 40 | </div></div> | |
| 41 | <div class="module-body tight"> | |
| 42 | [if:!$has_hits]<p class="dim" style="padding:8px 0">No matches.</p>[/if] | |
| 43 | [if:$has_hits] | |
| 44 | <style> | |
| 45 | .sr-hit { border-top:1px solid var(--border); padding:10px 0 } | |
| 46 | .sr-hit:first-child { border-top:none } | |
| 47 | .sr-hit .sr-file { display:flex;align-items:center;gap:10px;margin-bottom:6px } | |
| 48 | .sr-hit .sr-file .path { font-family:var(--mono);font-size:12.5px;color:var(--text) } | |
| 49 | .sr-hit .sr-file .actions { margin-left:auto;display:flex;gap:6px } | |
| 50 | .sr-hit table.sr-code { width:100%;border-collapse:collapse;font-family:var(--mono);font-size:11.5px;line-height:1.55;background:var(--panel-2);border-radius:6px;margin-top:4px } | |
| 51 | .sr-hit table.sr-code td { padding:1px 8px;vertical-align:top;white-space:pre-wrap;word-wrap:break-word } | |
| 52 | .sr-hit table.sr-code td.ln { color:var(--text-muted);text-align:right;width:44px;border-right:1px solid var(--border);user-select:none;font-size:11px } | |
| 53 | .sr-hit table.sr-code tr.op-hit td.text { background:rgba(20,184,166,.10) } | |
| 54 | .sr-hit table.sr-code tr.op-ctx td { color:var(--text-dim) } | |
| 55 | .sr-hit mark { background:rgba(250,204,21,.35);color:var(--text);padding:0 2px;border-radius:2px } | |
| 56 | </style> | |
| 57 | [loop:@hits] | |
| 58 | <div class="sr-hit"> | |
| 59 | <div class="sr-file"> | |
| 60 | <span class="path">$file_name_h</span> | |
| 61 | <span class="dim mono" style="font-size:11px">blob $blob_short</span> | |
| 62 | <span class="dim" style="font-size:11.5px"><span class="ts" data-ts="$latest_epoch" data-fmt="relative"></span></span> | |
| 63 | <span class="actions"> | |
| 64 | <a href="$file_url" class="tr-chip">Open diff</a> | |
| 65 | <a href="$restore_url" class="tr-chip">Restore</a> | |
| 66 | </span> | |
| 67 | </div> | |
| 68 | <table class="sr-code"><tbody> | |
| 69 | [loop:@hit_lines]<tr class="op-$op"><td class="ln">$ln</td><td class="text">$text</td></tr>[/loop] | |
| 70 | </tbody></table> | |
| 71 | </div> | |
| 72 | [/loop] | |
| 73 | [/if] | |
| 74 | </div> | |
| 75 | </div> | |
| 76 | [/if][/if] | |
| 77 | ||
| 78 | [if:!$has_query] | |
| 79 | <div class="module glow-teal" style="margin-top:16px"> | |
| 80 | <div class="module-body"> | |
| 81 | <p class="dim" style="margin:0 0 14px;font-size:13px">Type a query above to search across every captured blob's text content, or click any example below.</p> | |
| 82 | ||
| 83 | <style> | |
| 84 | .sr-examples { display:grid; grid-template-columns:repeat(auto-fill, minmax(340px, 1fr)); gap:14px; } | |
| 85 | .sr-ex-group { border:1px solid var(--border); border-radius:10px; padding:14px 16px; background:var(--bg-2); } | |
| 86 | .sr-ex-group h4 { margin:0 0 4px; font-size:12px; letter-spacing:.06em; text-transform:uppercase; color:var(--accent-hi); font-weight:700; } | |
| 87 | .sr-ex-group p { margin:0 0 12px; font-size:11.5px; color:var(--text-muted); } | |
| 88 | .sr-ex-list { display:flex; flex-direction:column; gap:6px; } | |
| 89 | .sr-ex-list a { | |
| 90 | display:flex; align-items:center; gap:10px; padding:8px 12px; | |
| 91 | background:var(--bg-1); border:1px solid var(--border); border-radius:8px; | |
| 92 | color:var(--text); text-decoration:none; transition:border-color .12s, box-shadow .12s, transform .12s; | |
| 93 | } | |
| 94 | .sr-ex-list a:hover { border-color:var(--accent); box-shadow:0 0 0 3px rgba(20,184,166,.10); transform:translateY(-1px); } | |
| 95 | .sr-ex-list a code { | |
| 96 | flex:0 0 auto; font-family:var(--mono); font-size:11.5px; | |
| 97 | background:rgba(20,184,166,.08); color:var(--accent-hi); | |
| 98 | padding:2px 8px; border-radius:5px; border:1px solid rgba(20,184,166,.20); | |
| 99 | white-space:nowrap; max-width:180px; overflow:hidden; text-overflow:ellipsis; | |
| 100 | } | |
| 101 | .sr-ex-list a .sr-ex-desc { font-size:11.5px; color:var(--text-dim); flex:1; min-width:0; } | |
| 102 | .sr-ex-list a .sr-ex-badge { font-size:9.5px; letter-spacing:.08em; text-transform:uppercase; color:var(--text-muted); background:var(--bg-2); padding:1px 6px; border-radius:4px; border:1px solid var(--border); } | |
| 103 | </style> | |
| 104 | ||
| 105 | <div class="sr-examples"> | |
| 106 | <div class="sr-ex-group"> | |
| 107 | <h4>Find secrets</h4> | |
| 108 | <p>Common patterns for credentials that shouldn't be in code.</p> | |
| 109 | <div class="sr-ex-list"> | |
| 110 | <a href="/search.cgi?q=password"><code>password</code><span class="sr-ex-desc">the word "password"</span></a> | |
| 111 | <a href="/search.cgi?q=api_key&case=1"><code>api_key</code><span class="sr-ex-desc">exact case</span><span class="sr-ex-badge">case</span></a> | |
| 112 | <a href="/search.cgi?q=%5E.%2A%3D%5Cs*%5B%22%27%5D.%2A%5B%22%27%5D&regex=1"><code>= "..."</code><span class="sr-ex-desc">quoted-string assignments</span><span class="sr-ex-badge">regex</span></a> | |
| 113 | <a href="/search.cgi?q=BEGIN%20PRIVATE%20KEY"><code>BEGIN PRIVATE KEY</code><span class="sr-ex-desc">PEM headers</span></a> | |
| 114 | </div> | |
| 115 | </div> | |
| 116 | ||
| 117 | <div class="sr-ex-group"> | |
| 118 | <h4>Find code smells</h4> | |
| 119 | <p>Debug leftovers, hardcoded values, TODO comments.</p> | |
| 120 | <div class="sr-ex-list"> | |
| 121 | <a href="/search.cgi?q=TODO"><code>TODO</code><span class="sr-ex-desc">unfinished work</span></a> | |
| 122 | <a href="/search.cgi?q=console.log"><code>console.log</code><span class="sr-ex-desc">forgotten JS debug</span></a> | |
| 123 | <a href="/search.cgi?q=print%20STDERR"><code>print STDERR</code><span class="sr-ex-desc">forgotten Perl debug</span></a> | |
| 124 | <a href="/search.cgi?q=%5EDBI-%3E&regex=1"><code>^DBI-></code><span class="sr-ex-desc">direct DBI at line start</span><span class="sr-ex-badge">regex</span></a> | |
| 125 | </div> | |
| 126 | </div> | |
| 127 | ||
| 128 | <div class="sr-ex-group"> | |
| 129 | <h4>Find code shape</h4> | |
| 130 | <p>Structural searches for migrations, imports, function definitions.</p> | |
| 131 | <div class="sr-ex-list"> | |
| 132 | <a href="/search.cgi?q=%5Esub%20%5C%5Cw%2B_migration&regex=1"><code>^sub \w+_migration</code><span class="sr-ex-desc">migration functions</span><span class="sr-ex-badge">regex</span></a> | |
| 133 | <a href="/search.cgi?q=%5Euse%20MODS%3A%3A&regex=1"><code>^use MODS::</code><span class="sr-ex-desc">module imports</span><span class="sr-ex-badge">regex</span></a> | |
| 134 | <a href="/search.cgi?q=%5EINSERT%20INTO&regex=1&case=1"><code>^INSERT INTO</code><span class="sr-ex-desc">SQL inserts (case)</span><span class="sr-ex-badge">regex</span><span class="sr-ex-badge">case</span></a> | |
| 135 | <a href="/search.cgi?q=CREATE%20TABLE"><code>CREATE TABLE</code><span class="sr-ex-desc">table DDL</span></a> | |
| 136 | </div> | |
| 137 | </div> | |
| 138 | ||
| 139 | <div class="sr-ex-group"> | |
| 140 | <h4>Portfolio hunts</h4> | |
| 141 | <p>Cross-site checks for shared code, feature usage, config drift.</p> | |
| 142 | <div class="sr-ex-list"> | |
| 143 | <a href="/search.cgi?q=Sh%40wn135"><code>Sh@wn135</code><span class="sr-ex-desc">shared DB password</span></a> | |
| 144 | <a href="/search.cgi?q=stripe"><code>stripe</code><span class="sr-ex-desc">payment integrations</span></a> | |
| 145 | <a href="/search.cgi?q=drift_sense"><code>drift_sense</code><span class="sr-ex-desc">DriftSense references</span></a> | |
| 146 | <a href="/search.cgi?q=%40mail-service-ip"><code>mail-service-ip</code><span class="sr-ex-desc">Plesk mail config</span></a> | |
| 147 | </div> | |
| 148 | </div> | |
| 149 | </div> | |
| 150 | ||
| 151 | <p class="dim" style="margin:16px 0 0;font-size:11.5px;line-height:1.55"> | |
| 152 | <strong style="color:var(--text-dim)">Tip:</strong> | |
| 153 | Regex mode wraps your input in <code>qr/.../</code> so you can use anchors like <code>^</code> and <code>$</code>, character classes, and backreferences. | |
| 154 | Turn on <code>case</code> when your target really is uppercase (e.g. SQL keywords). | |
| 155 | Combine with the <strong>site dropdown</strong> to scope the search to a single portfolio site. | |
| 156 | </p> | |
| 157 | </div> | |
| 158 | </div> | |
| 159 | [/if] |