import { useState, useEffect, useCallback } from "react"; const CSS = ` @import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,600;0,700;1,400&family=IBM+Plex+Sans:wght@300;400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap'); *,*::before,*::after{box-sizing:border-box;margin:0;padding:0} :root{ --red:#C0272D;--rd:#8B1A1E;--rg:rgba(192,39,45,0.12); --black:#0F0F0F;--surf:#161616;--s2:#1E1E1E;--s3:#252525; --border:rgba(255,255,255,0.07);--bb:rgba(255,255,255,0.15); --text:#E8E8E8; --muted:#AAAAAA; --dim:#777777; --green:#2ECC71;--amber:#F39C12;--blue:#3498DB; --mono:'IBM Plex Mono',monospace; } html{scroll-behavior:smooth} body{background:var(--black);color:var(--text);font-family:'IBM Plex Sans',sans-serif;font-size:15px;line-height:1.7;min-height:100vh} .nav{background:rgba(22,22,22,0.97);border-bottom:1px solid var(--border);padding:0 28px;position:sticky;top:0;z-index:200;backdrop-filter:blur(12px)} .nav-inner{max-width:980px;margin:0 auto;height:54px;display:flex;align-items:center;justify-content:space-between} .nav-brand{font-family:'Cormorant Garamond',serif;font-size:18px;font-weight:700;color:var(--text)} .nav-brand em{color:var(--red);font-style:normal} .nav-right{display:flex;align-items:center;gap:16px} .status-dot{width:7px;height:7px;border-radius:50%;background:var(--dim);transition:all .4s} .status-dot.live{background:var(--green);box-shadow:0 0 8px rgba(46,204,113,.6)} .status-label{font-size:12px;color:var(--dim);transition:color .3s;font-family:'IBM Plex Sans',sans-serif} .status-label.live{color:var(--green)} .saved-pill{display:none;align-items:center;gap:6px;font-size:11px;color:var(--amber);background:rgba(243,156,18,.08);border:1px solid rgba(243,156,18,.25);border-radius:12px;padding:3px 10px;cursor:pointer} .saved-pill.shown{display:flex} .saved-dot{width:5px;height:5px;border-radius:50%;background:var(--amber);animation:pulse 2s ease-in-out infinite} @keyframes pulse{0%,100%{opacity:1}50%{opacity:.4}} @keyframes fi{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}} @keyframes bounce{0%,100%{transform:translateY(0)}50%{transform:translateY(4px)}} @keyframes rot{to{transform:rotate(360deg)}} .wrap{max-width:980px;margin:0 auto;padding:0 28px} .hero{padding:72px 0 60px;position:relative} .hero::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--border),transparent)} .hero-pre{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.2em;color:var(--red);margin-bottom:18px;display:flex;align-items:center;gap:10px} .hero-pre::before{content:'';width:24px;height:1px;background:var(--red)} h1.hero-title{font-family:'Cormorant Garamond',serif;font-size:clamp(40px,6vw,72px);font-weight:700;line-height:1.04;color:#fff;margin-bottom:24px} h1.hero-title em{color:var(--red);font-style:italic} .hero-deck{font-size:17px;color:var(--muted);max-width:560px;line-height:1.8;margin-bottom:40px} .hero-deck strong{color:var(--text);font-weight:500} .hero-arrow{font-size:13px;color:var(--dim);animation:bounce 2s ease-in-out infinite} .truths{display:grid;grid-template-columns:repeat(5,1fr);gap:1px;background:var(--border);border:1px solid var(--border);border-radius:8px;overflow:hidden;margin:40px 0 0} .truth{background:var(--surf);padding:16px} .truth-n{font-family:var(--mono);font-size:10px;color:var(--red);margin-bottom:5px} .truth-t{font-size:12px;font-weight:500;color:var(--text);margin-bottom:3px} .truth-d{font-size:11px;color:var(--muted);line-height:1.5} .section{padding:72px 0;position:relative} .section::after{content:'';position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--border),transparent)} .sec-pre{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.18em;color:var(--red);margin-bottom:14px;display:flex;align-items:center;gap:10px} .sec-pre::before{content:'';width:20px;height:1px;background:var(--red)} .sec-title{font-family:'Cormorant Garamond',serif;font-size:clamp(28px,4vw,46px);font-weight:700;color:#fff;line-height:1.12;margin-bottom:16px} .sec-sub{font-size:15px;color:var(--muted);max-width:560px;line-height:1.8;margin-bottom:36px} .sec-sub strong{color:var(--text);font-weight:500} .key-gate{background:var(--s2);border:1px solid var(--border);border-radius:10px;padding:24px;margin-bottom:28px;animation:fi .25s ease} .key-gate-title{font-size:14px;font-weight:600;color:var(--text);margin-bottom:6px} .key-gate-sub{font-size:13px;color:var(--muted);margin-bottom:16px;line-height:1.6} .key-gate-sub a{color:var(--red);text-decoration:none} .key-row{display:flex;gap:10px;align-items:center;margin-bottom:10px} .key-inp{flex:1;background:var(--s3);border:1px solid var(--border);border-radius:6px;padding:10px 14px;font-family:var(--mono);font-size:13px;color:var(--text);outline:none;transition:all .2s} .key-inp.live{border-color:rgba(46,204,113,.4);background:rgba(46,204,113,.04)} .key-inp::placeholder{color:var(--dim)} .key-safety-row{display:flex;gap:16px;flex-wrap:wrap;margin-top:8px} .ks-item{font-size:11px;color:var(--dim)} .ks-item a{color:var(--dim);text-decoration:none} .agrid{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px} .apanel{background:var(--s2);border:1px solid var(--border);border-radius:8px;overflow:hidden;display:flex;flex-direction:column} .apanel-top{background:var(--s3);border-bottom:1px solid var(--border);padding:10px 16px;display:flex;justify-content:space-between;align-items:center;flex-shrink:0} .apanel-label{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;color:var(--dim)} .apanel-meta{font-family:var(--mono);font-size:11px;color:var(--dim)} textarea.code-ta{width:100%;min-height:280px;background:transparent;border:none;outline:none;padding:16px;font-family:var(--mono);font-size:12.5px;color:#e0e6ed;line-height:1.7;resize:vertical} textarea.code-ta::placeholder{color:var(--dim)} .results-inner{padding:14px;flex:1;overflow-y:auto;min-height:280px;font-size:13px;color:var(--muted);line-height:1.8} .results-inner ul{margin-top:8px;padding-left:16px} .results-inner li{margin-bottom:4px;color:var(--muted)} .run-btn{width:100%;background:var(--red);color:#fff;border:none;border-radius:8px;padding:14px;font-family:'IBM Plex Sans',sans-serif;font-size:15px;font-weight:600;cursor:pointer;transition:all .2s;display:flex;align-items:center;justify-content:center;gap:10px;margin-bottom:16px} .run-btn:hover:not(:disabled){background:#a02025;transform:translateY(-1px)} .run-btn:disabled{opacity:.4;cursor:not-allowed;transform:none} .run-btn.green-btn{background:rgba(46,204,113,.12);color:var(--green);border:1px solid rgba(46,204,113,.3);margin-top:12px;margin-bottom:0} .spin{width:15px;height:15px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:rot .5s linear infinite} .spin.green-spin{border-color:rgba(46,204,113,.3);border-top-color:var(--green)} .issue-badges{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:12px} .ibadge{padding:3px 10px;border-radius:10px;font-size:11px;font-weight:600;border:1px solid} .ibadge-c{background:rgba(192,39,45,.1);border-color:rgba(192,39,45,.3);color:var(--red)} .ibadge-w{background:rgba(243,156,18,.1);border-color:rgba(243,156,18,.3);color:var(--amber)} .ibadge-i{background:rgba(52,152,219,.1);border-color:rgba(52,152,219,.2);color:var(--blue)} .issue-card{border:1px solid var(--border);border-radius:6px;overflow:hidden;margin-bottom:10px} .ic-hdr{padding:10px 13px;display:flex;align-items:flex-start;gap:9px;cursor:pointer} .ic-hdr:hover{background:rgba(255,255,255,.025)} .ic-sev{width:7px;height:7px;border-radius:50%;flex-shrink:0;margin-top:5px} .sev-c{background:var(--red)}.sev-w{background:var(--amber)}.sev-i{background:var(--blue)} .ic-line{font-family:var(--mono);font-size:11px;color:var(--dim);min-width:48px;flex-shrink:0} .ic-desc{font-size:13px;color:var(--text);flex:1;line-height:1.45} .ic-arr{font-size:13px;color:var(--dim);transition:transform .2s;flex-shrink:0} .ic-body{border-top:1px solid var(--border);padding:14px;background:rgba(0,0,0,.3)} .ic-body p{font-size:13px;color:var(--muted);line-height:1.65;margin-bottom:12px} .ic-fix-lbl{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;color:var(--green);margin-bottom:6px;display:flex;align-items:center;gap:8px} .ic-fix{background:#080808;border:1px solid rgba(46,204,113,.18);border-radius:5px;padding:12px 14px;font-family:var(--mono);font-size:12px;color:#b8f0d0;line-height:1.7;white-space:pre-wrap;word-break:break-all;margin-bottom:12px} .ic-actions{display:flex;gap:8px;flex-wrap:wrap;padding-top:10px;border-top:1px solid var(--border);margin-top:2px} .fix-result{margin-top:14px;animation:fi .3s ease} .fix-result-header{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;color:var(--green);margin-bottom:8px;display:flex;align-items:center;gap:8px} .fix-result-header::after{content:'';flex:1;height:1px;background:rgba(46,204,113,.2)} .fixed-code{background:#060606;border:1px solid rgba(46,204,113,.2);border-radius:6px;padding:14px 16px;font-family:var(--mono);font-size:12px;color:#c8ecd8;line-height:1.7;white-space:pre-wrap;word-break:break-all;max-height:280px;overflow-y:auto;margin-bottom:12px} .publish-panel{background:rgba(46,204,113,.04);border:1px solid rgba(46,204,113,.2);border-radius:8px;padding:16px;margin-top:12px;animation:fi .25s ease} .pp-title{font-size:13px;font-weight:600;color:var(--green);margin-bottom:6px;display:flex;align-items:center;gap:7px} .pp-sub{font-size:12px;color:var(--muted);margin-bottom:12px;line-height:1.55} .pp-tabs{display:flex;gap:0;border-bottom:1px solid rgba(46,204,113,.15);margin-bottom:0} .pp-tab{padding:7px 14px;font-size:12px;font-weight:500;color:var(--dim);cursor:pointer;border-bottom:2px solid transparent;transition:all .15s} .pp-tab:hover{color:var(--text)} .pp-tab.active{color:var(--green);border-bottom-color:var(--green)} .pp-panel{padding:12px 0 0;animation:fi .2s ease} .pp-code{background:#060606;border:1px solid var(--border);border-radius:5px;padding:12px 14px;font-family:var(--mono);font-size:11px;color:#c9d1d9;line-height:1.65;max-height:180px;overflow-y:auto;white-space:pre-wrap;word-break:break-all;margin-bottom:10px} .verdict-box{border-radius:6px;padding:13px 15px;margin-top:10px;font-size:13px;line-height:1.65} .verdict-ok{background:rgba(46,204,113,.06);border:1px solid rgba(46,204,113,.2);color:#c8ecd8} .verdict-bad{background:rgba(192,39,45,.06);border:1px solid rgba(192,39,45,.2);color:#f0b8ba} .verdict-lbl{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;margin-bottom:5px} .reveal-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--border);border:1px solid var(--border);border-radius:10px;overflow:hidden;margin-bottom:28px} .rg-cell{background:var(--surf);padding:20px} .rg-num{font-family:var(--mono);font-size:10px;color:var(--red);margin-bottom:8px} .rg-title{font-size:14px;font-weight:600;color:var(--text);margin-bottom:6px} .rg-desc{font-size:13px;color:var(--muted);line-height:1.6} .rg-moat{background:var(--rg)} .rg-moat .rg-title{color:var(--red)} .prb{width:100%;background:transparent;border:1px dashed var(--bb);border-radius:6px;padding:12px 18px;display:flex;justify-content:space-between;align-items:center;font-family:'IBM Plex Sans',sans-serif;font-size:13px;color:var(--muted);cursor:pointer;transition:all .2s;margin-bottom:8px} .prb:hover{border-color:var(--red);color:var(--red)} .prb-arr{transition:transform .25s} .prb-open{transform:rotate(180deg)} .prompt-box{background:#060606;border:1px solid var(--border);border-radius:0 0 6px 6px;padding:18px;font-family:var(--mono);font-size:12px;color:#c9d1d9;line-height:1.7;white-space:pre-wrap;word-break:break-all;max-height:340px;overflow-y:auto;margin-bottom:8px;animation:fi .2s ease} .callout{border-left:3px solid var(--red);background:var(--s2);border-radius:0 6px 6px 0;padding:16px 20px;margin:20px 0;font-size:14px;color:var(--muted);line-height:1.75} .callout strong{color:var(--text);font-weight:500} .callout-green{border-color:var(--green)} .callout-amber{border-color:var(--amber)} .lc-row{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:24px} .lc{background:var(--s2);border:1px solid var(--border);border-radius:8px;padding:16px;transition:all .3s} .lc.current{border-color:rgba(46,204,113,.35);background:rgba(46,204,113,.04)} .lc-dot{width:8px;height:8px;border-radius:50%;background:var(--dim);margin-bottom:10px;transition:all .3s} .lc.current .lc-dot{background:var(--green);box-shadow:0 0 6px rgba(46,204,113,.5)} .lc-t{font-size:13px;font-weight:600;color:var(--text);margin-bottom:5px} .lc-d{font-size:12px;color:var(--muted);line-height:1.55} .sgrid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:16px 0} .sg{background:var(--s2);border:1px solid var(--border);border-radius:6px;padding:14px;display:flex;gap:10px} .sg-ico{font-size:15px;flex-shrink:0;margin-top:1px} .sg-body strong{font-size:12px;font-weight:600;color:var(--text);display:block;margin-bottom:3px} .sg-body p{font-size:12px;color:var(--muted);line-height:1.55} .sg-body a{color:var(--red);text-decoration:none} .key-card{background:var(--s2);border:1px solid var(--border);border-radius:10px;padding:22px} .key-card-hdr{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:16px;flex-wrap:wrap;gap:10px} .key-card-title{font-size:14px;font-weight:600;color:var(--text)} .kcs{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--dim);transition:color .3s} .kcs-dot{width:7px;height:7px;border-radius:50%;background:var(--dim);transition:all .3s} .kcs.live .kcs-dot{background:var(--green);box-shadow:0 0 5px rgba(46,204,113,.5)} .kcs.live{color:var(--green)} .key-acts{display:flex;gap:8px;flex-wrap:wrap;margin:10px 0} .key-meta{font-size:11px;color:var(--dim);line-height:1.6} .key-meta a{color:var(--red);text-decoration:none} .build-card{background:var(--s2);border:1px solid var(--border);border-radius:10px;overflow:hidden} .bc-hdr{background:var(--s3);border-bottom:1px solid var(--border);padding:18px 24px;display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px} .bc-title{font-size:15px;font-weight:600;color:var(--text)} .bc-sub{font-size:12px;color:var(--dim);margin-top:2px} .bc-ki{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--dim);font-family:var(--mono)} .bc-ki .dot{width:6px;height:6px;border-radius:50%;background:var(--dim)} .bc-ki.live .dot{background:var(--green)} .bc-ki.live{color:var(--green)} .bc-body{padding:24px} .q-grp{margin-bottom:18px} .q-lbl{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;color:var(--dim);margin-bottom:4px;display:flex;align-items:center;gap:7px} .q-lbl em{color:var(--red);font-style:normal;font-size:12px} .q-why{font-size:11px;color:var(--dim);font-style:italic;margin-bottom:7px} .q-inp{width:100%;background:var(--s3);border:1px solid var(--border);border-radius:6px;padding:10px 13px;font-family:'IBM Plex Sans',sans-serif;font-size:13px;color:var(--text);outline:none;transition:border-color .15s;resize:none} .q-inp:focus{border-color:var(--bb)} .q-inp::placeholder{color:var(--dim)} .q-sel{width:100%;background:var(--s3);border:1px solid var(--border);border-radius:6px;padding:10px 13px;font-family:'IBM Plex Sans',sans-serif;font-size:13px;color:var(--text);outline:none;cursor:pointer} .q-sel option{background:var(--s2)} .q-row2{display:grid;grid-template-columns:1fr 1fr;gap:14px} .gen-btn{width:100%;background:var(--red);color:#fff;border:none;border-radius:8px;padding:15px;font-family:'IBM Plex Sans',sans-serif;font-size:15px;font-weight:600;cursor:pointer;transition:all .2s;display:flex;align-items:center;justify-content:center;gap:10px;margin-top:6px} .gen-btn:hover:not(:disabled){background:#a02025;transform:translateY(-1px)} .gen-btn:disabled{opacity:.4;cursor:not-allowed;transform:none} .gen-out{animation:fi .3s ease} .gen-sec{font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.1em;color:var(--red);margin-bottom:12px;display:flex;align-items:center;gap:8px;margin-top:24px} .gen-sec::after{content:'';flex:1;height:1px;background:var(--border)} .unsaved-banner{background:rgba(243,156,18,.08);border:1px solid rgba(243,156,18,.35);border-radius:8px;padding:16px 20px;margin-bottom:20px;display:flex;align-items:flex-start;gap:14px;animation:fi .3s ease} .ub-icon{font-size:20px;flex-shrink:0} .ub-title{font-size:14px;font-weight:600;color:var(--amber);margin-bottom:4px} .ub-desc{font-size:13px;color:#f5c97a;line-height:1.65} .ub-desc strong{color:#fff;font-weight:500} .ub-acts{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px} .restore-banner{background:rgba(52,152,219,.06);border:1px solid rgba(52,152,219,.25);border-radius:8px;padding:16px 20px;margin-bottom:24px;display:flex;align-items:flex-start;gap:14px;animation:fi .3s ease} .rb-title{font-size:14px;font-weight:600;color:var(--blue);margin-bottom:4px} .rb-desc{font-size:13px;color:#a8d4f0;line-height:1.65} .rb-acts{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px} .ltb{background:var(--s3);border:1px solid rgba(46,204,113,.2);border-radius:8px;overflow:hidden;margin-bottom:20px} .ltb-hdr{background:rgba(46,204,113,.06);border-bottom:1px solid rgba(46,204,113,.15);padding:12px 18px;display:flex;align-items:center;gap:10px} .ltb-dot{width:8px;height:8px;border-radius:50%;background:var(--green);box-shadow:0 0 6px rgba(46,204,113,.5)} .ltb-title{font-size:13px;font-weight:600;color:var(--green)} .ltb-sub{font-size:11px;color:rgba(46,204,113,.7);margin-top:1px} .ltb-body{padding:16px} .ltb-hint{font-size:13px;color:var(--muted);margin-bottom:12px;line-height:1.6} .dtabs{display:flex;gap:0;border-bottom:1px solid var(--border);margin-bottom:0} .dtab{padding:10px 18px;font-size:13px;font-weight:500;color:var(--dim);cursor:pointer;border-bottom:2px solid transparent;transition:all .15s;user-select:none} .dtab:hover{color:var(--text)} .dtab.active{color:var(--text);border-bottom-color:var(--red)} .dpanel{padding:16px 0 0;animation:fi .2s ease} .code-block{background:#060606;border:1px solid var(--border);border-radius:6px;padding:14px 16px;font-family:var(--mono);font-size:12px;color:#c9d1d9;line-height:1.65;max-height:220px;overflow-y:auto;white-space:pre-wrap;word-break:break-all;margin-bottom:10px} .err-box{background:rgba(192,39,45,.08);border:1px solid rgba(192,39,45,.25);border-radius:6px;padding:12px 16px;color:#f0b8ba;font-size:13px;line-height:1.6;margin-top:12px;animation:fi .2s ease} .fix-note{background:rgba(46,204,113,.05);border:1px solid rgba(46,204,113,.18);border-radius:6px;padding:10px 14px;font-size:12px;color:#b8f0d0;margin-bottom:16px;line-height:1.6} .fix-note strong{color:var(--green);font-weight:600} .fix-note code{font-family:var(--mono);background:rgba(46,204,113,.1);padding:1px 5px;border-radius:3px;color:#b8f0d0} .btn{display:inline-flex;align-items:center;gap:7px;padding:9px 20px;border-radius:6px;font-family:'IBM Plex Sans',sans-serif;font-size:13px;font-weight:600;cursor:pointer;transition:all .2s;border:none;text-decoration:none;white-space:nowrap} .btn-red{background:var(--red);color:#fff}.btn-red:hover{background:#a02025} .btn-o{background:transparent;color:var(--text);border:1px solid var(--bb)}.btn-o:hover{border-color:var(--rd);color:var(--red)} .btn-g{background:rgba(46,204,113,.1);color:var(--green);border:1px solid rgba(46,204,113,.3)}.btn-g:hover{background:rgba(46,204,113,.2)} .btn-a{background:rgba(243,156,18,.1);color:var(--amber);border:1px solid rgba(243,156,18,.3)}.btn-a:hover{background:rgba(243,156,18,.2)} .btn-b{background:rgba(52,152,219,.1);color:var(--blue);border:1px solid rgba(52,152,219,.3)}.btn-b:hover{background:rgba(52,152,219,.2)} .btn-sm{padding:6px 14px;font-size:12px} .btn-xs{padding:4px 10px;font-size:11px} .btn-grp{display:flex;gap:8px;flex-wrap:wrap} .footer{padding:56px 0;text-align:center;border-top:1px solid var(--border)} .footer-brand{font-family:'Cormorant Garamond',serif;font-size:22px;font-weight:700;color:var(--dim);margin-bottom:8px} .footer-brand em{color:var(--red);font-style:normal} .footer-note{font-size:12px;color:var(--dim)} .footer-note a{color:var(--red);text-decoration:none} code{font-family:var(--mono);font-size:12px;background:var(--s3);padding:1px 5px;border-radius:3px;color:#c9d1d9} .reminder-box{background:rgba(243,156,18,.06);border:1px solid rgba(243,156,18,.2);border-radius:6px;padding:12px 16px;margin-bottom:14px;font-size:13px;color:#f5c97a;line-height:1.6} @media(max-width:700px){.truths{grid-template-columns:1fr 1fr}.agrid{grid-template-columns:1fr}.reveal-grid{grid-template-columns:1fr}.lc-row{grid-template-columns:1fr}.sgrid{grid-template-columns:1fr}.q-row2{grid-template-columns:1fr}h1.hero-title{font-size:38px}} `; const AUDITOR_SYSTEM = `You are a strict pre-flight code auditor for Python scripts designed to run as cron jobs on Linux or macOS. Your job: find every failure BEFORE it runs. Return only valid JSON. Check ALL of these — no exceptions: 1. HARDCODED CREDENTIALS: API key, token, secret directly in code. Critical. 2. RELATIVE FILE PATHS: Any path using ./ or ~/ or no leading /. Cron has no working directory. 3. MISSING LOGGING: No logging module. Script crashes with zero record. 4. MISSING sys.exit(1): No failure exit code. Cron thinks it succeeded even when crashed. 5. RELATIVE .ENV LOADING: load_dotenv() without absolute path. Credentials never load. 6. VIRTUAL ENVIRONMENT PATH: Generic python3 used — pip-installed packages fail with ModuleNotFoundError. 7. X/TWITTER AUTH GAPS: No verification that app has Write permissions at developer.twitter.com. 8. MACOS CRON: If macOS indicators exist, note launchd may be required instead. 9. MISSING GITIGNORE: .env referenced but no .gitignore mention. 10. SILENT EXCEPTIONS: Bare except, pass in except, exceptions not logged. Return ONLY this JSON: {"issues":[{"severity":"critical|warning|info","line":"Line N or General","description":"one sentence","explanation":"two sentences why this breaks","fix":"exact corrected code snippet for this specific issue"}],"verdict":"one paragraph assessment","safe_to_run":true|false,"critical_count":number,"warning_count":number}`; const K = 'jdm_key', KT = 'jdm_key_ts', GK = 'jdm_generated_tool'; function timeAgo(ts) { const s = Math.floor((Date.now() - ts) / 1000); if (s < 60) return 'just now'; if (s < 3600) return Math.floor(s / 60) + 'm ago'; if (s < 86400) return Math.floor(s / 3600) + 'h ago'; return Math.floor(s / 86400) + 'd ago'; } function isValidKey(k) { return k && k.startsWith('sk-ant') && k.length > 20; } async function callClaude(key, system, userMsg, maxTokens) { const r = await fetch('https://api.anthropic.com/v1/messages', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': key, 'anthropic-version': '2023-06-01', 'anthropic-dangerous-direct-browser-access': 'true' }, body: JSON.stringify({ model: 'claude-sonnet-4-20250514', max_tokens: maxTokens, system, messages: [{ role: 'user', content: userMsg }] }) }); if (!r.ok) { const e = await r.json(); throw new Error(e.error?.message || 'API error ' + r.status); } return r.json(); } function parseJSON(raw) { try { return JSON.parse(raw.trim()); } catch { const m = raw.match(/\{[\s\S]*\}/); if (m) return JSON.parse(m[0]); throw new Error('Could not parse response'); } } function errMsg(e) { if (e.message.includes('401')) return 'Invalid API key. Check at console.anthropic.com/settings/keys.'; if (e.message.includes('429')) return 'Rate limit. Wait 30 seconds and try again.'; return 'Error: ' + e.message; } function CopyBtn({ text, label, className }) { const [copied, setCopied] = useState(false); return ( ); } // ── PUBLISH PANEL: appears after a fix is generated ── function PublishPanel({ fixedScript, originalDomain }) { const [tab, setTab] = useState('mcp'); const slug = 'fixed-script-' + Date.now().toString(36); const publishDomain = originalDomain || 'joe.asapai.net'; const htmlPage = `
Generated by The Forge Auditor · All identified issues resolved
${fixedScript.replace(//g,'>')}
Open Claude with NowPage MCP connected. Copy and paste this. Your fixed script goes live in one message.
Open any Claude session. Paste this and send.
Complete self-contained HTML page. Deploy anywhere.
{issue.explanation}
{issue.fix && ( <>This page is a live AI tool that explains how it works while running. Paste a Python script below. Watch it get audited. Each issue generates a fixed version you can publish in one click.
anthropic-dangerous-direct-browser-access header. No server. No proxy. Key in localStorage — close the tab and it's gone.
anthropic-dangerous-direct-browser-access: true header is what makes this legal. That's the unlock. Each issue card can now generate a complete fixed script and publish it live.
{d}
Copy this. Open Claude with NowPage MCP connected. Paste and send. Live in one message.
Copy this. Open any Claude session. Paste and send.
Complete HTML. Works on NowPage, Vercel, GitHub Pages, or locally.