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 = ` Fixed Script

Fixed Script

Generated by The Forge Auditor · All identified issues resolved

Python · Fixed Version
${fixedScript.replace(//g,'>')}
`; const mcpPrompt = `Please publish this fixed script page to NowPage using the MCP. Domain: ${publishDomain} Name: Fixed Script — Forge Auditor Output Slug: ${slug} Tags: ["fixed-script", "forge-auditor", "python"] Update mode: replace HTML: ${htmlPage}`; const copyPrompt = `Please publish this page. It contains a fixed Python script generated by The Forge Auditor. Publish to ${publishDomain} with slug "${slug}" using NowPage MCP if available, otherwise save as index.html. HTML: ${htmlPage}`; return (
🚀 Publish Your Fixed Script
Choose how to make this permanent. Once published, you get a live URL anyone can access.
{[['mcp','🔗 NowPage MCP'],['copy','📋 Claude Prompt'],['html','📄 Raw HTML']].map(([id,label]) => (
setTab(id)}>{label}
))}
{tab === 'mcp' && (

Open Claude with NowPage MCP connected. Copy and paste this. Your fixed script goes live in one message.

{mcpPrompt}
)} {tab === 'copy' && (

Open any Claude session. Paste this and send.

{copyPrompt}
)} {tab === 'html' && (

Complete self-contained HTML page. Deploy anywhere.

{htmlPage}
)}
); } // ── ISSUE CARD with Generate Fix + Publish ── function IssueCard({ issue, apiKey, fullCode, publishDomain }) { const [open, setOpen] = useState(issue.severity === 'critical'); const [fixLoading, setFixLoading] = useState(false); const [fixedScript, setFixedScript] = useState(null); const [fixErr, setFixErr] = useState(''); const [showPublish, setShowPublish] = useState(false); const [copiedFix, setCopiedFix] = useState(false); const sc = issue.severity === 'critical' ? 'sev-c' : issue.severity === 'warning' ? 'sev-w' : 'sev-i'; const generateFix = async (e) => { e.stopPropagation(); if (!apiKey || !fullCode) return; setFixLoading(true); setFixErr(''); setFixedScript(null); setShowPublish(false); try { const system = `You are a Python expert. The user has a script with a specific issue. Fix ONLY that issue and return the complete corrected script. Return ONLY the fixed Python code — no explanation, no markdown fences, no preamble. Just the working script.`; const msg = `Issue to fix: ${issue.description} Why it breaks: ${issue.explanation} Original script: ${fullCode} Return the complete corrected Python script with this issue resolved.`; const data = await callClaude(apiKey, system, msg, 2000); let fixed = data.content[0].text.trim(); // Strip markdown fences if present fixed = fixed.replace(/^```python\n?/, '').replace(/^```\n?/, '').replace(/\n?```$/, '').trim(); setFixedScript(fixed); } catch (e) { setFixErr(errMsg(e)); } finally { setFixLoading(false); } }; return (
setOpen(!open)}>
{issue.line || 'General'}
{issue.description}
{open && (
e.stopPropagation()}>

{issue.explanation}

{issue.fix && ( <>
Quick Fix Snippet
{issue.fix}
)}
{/* GENERATE FIX BUTTON */} {fixedScript && ( )}
{fixErr &&
{fixErr}
} {/* FIXED SCRIPT OUTPUT */} {fixedScript && (
✓ Fixed Script — {issue.description}
{fixedScript}
{/* PUBLISH PANEL */} {showPublish && }
)}
)}
); } function AuditResults({ data, apiKey, fullCode, publishDomain }) { if (!data) return null; const issues = data.issues || []; const crit = issues.filter(i => i.severity === 'critical').length; const warn = issues.filter(i => i.severity === 'warning').length; const info = issues.filter(i => i.severity === 'info').length; return (
{crit > 0 && ⛔ {crit} Critical} {warn > 0 && ⚠️ {warn} Warning{warn > 1 ? 's' : ''}} {info > 0 && ℹ️ {info} Info}
{issues.map((issue, i) => ( ))} {data.verdict && (
{data.safe_to_run ? '✓ Verdict' : '⛔ Verdict'}
{data.verdict}
)}
); } export default function App() { const [key, setKey] = useState(''); const [keyValid, setKeyValid] = useState(false); const [keyLastUsed, setKeyLastUsed] = useState(null); const [code, setCode] = useState(''); const [publishDomain, setPublishDomain] = useState(''); const [auditLoading, setAuditLoading] = useState(false); const [auditResult, setAuditResult] = useState(null); const [auditErr, setAuditErr] = useState(''); const [promptOpen, setPromptOpen] = useState(false); const [b1,setB1]=useState('');const [b2,setB2]=useState('');const [b3,setB3]=useState(''); const [b4,setB4]=useState('#C0272D');const [b5,setB5]=useState('');const [b6,setB6]=useState('mcp'); const [genLoading,setGenLoading]=useState(false);const [genErr,setGenErr]=useState(''); const [genObj,setGenObj]=useState(null);const [deployTab,setDeployTab]=useState('mcp'); const [testInput,setTestInput]=useState('');const [testLoading,setTestLoading]=useState(false); const [testResult,setTestResult]=useState(null);const [testErr,setTestErr]=useState(''); const [hasSaved,setHasSaved]=useState(false);const [showRestore,setShowRestore]=useState(false); useEffect(()=>{ const saved=localStorage.getItem(K)||'';const ts=localStorage.getItem(KT); setKey(saved);setKeyValid(isValidKey(saved));if(ts)setKeyLastUsed(+ts); const raw=localStorage.getItem(GK); if(raw){try{const p=JSON.parse(raw);if(p&&p.html){setHasSaved(true);setShowRestore(true);}}catch(e){}} },[]); const handleKey=(v)=>{setKey(v);const valid=isValidKey(v);setKeyValid(valid);if(valid){localStorage.setItem(K,v);localStorage.setItem(KT,Date.now());setKeyLastUsed(Date.now());}}; const clearKey=()=>{localStorage.removeItem(K);localStorage.removeItem(KT);setKey('');setKeyValid(false);setKeyLastUsed(null);}; const runAudit=async()=>{ if(!key||!code.trim())return; setAuditLoading(true);setAuditErr('');setAuditResult(null); try{ const data=await callClaude(key,AUDITOR_SYSTEM,'Audit this script:\n\n'+code,2000); localStorage.setItem(KT,Date.now());setKeyLastUsed(Date.now()); setAuditResult(parseJSON(data.content[0].text)); }catch(e){setAuditErr(errMsg(e));} finally{setAuditLoading(false);} }; const runTest=async()=>{ if(!key||!testInput.trim()||!genObj?.systemPrompt)return; setTestLoading(true);setTestErr('');setTestResult(null); try{ const data=await callClaude(key,genObj.systemPrompt,testInput,2000); localStorage.setItem(KT,Date.now());setKeyLastUsed(Date.now()); setTestResult(parseJSON(data.content[0].text)); }catch(e){setTestErr(errMsg(e));} finally{setTestLoading(false);} }; const generateTool=async()=>{ if(!key||!b1.trim()||!b2.trim()||!b3.trim()){setGenErr('Fill in questions 1–3 and make sure your key is active.');return;} setGenLoading(true);setGenErr('');setGenObj(null); const slug=b1.toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,''); const pub=b5.trim()||'your-domain.com';const color=b4.trim()||'#C0272D'; const metaSystem=`You are an expert at building Embedded Intelligence tools — single-file HTML pages that call the Anthropic API directly from the browser using the header 'anthropic-dangerous-direct-browser-access: true'. Generate TWO things separated by ===SPLIT=== PART 1 — Expert System Prompt (150–250 words): Write the system prompt for a tool that analyses: ${b2}. Embodies expertise in: ${b1}. Produces: ${b3}. Require JSON: {"issues":[{"severity":"critical|warning|info","area":"string","finding":"one sentence","explanation":"two sentences","recommendation":"specific action"}],"verdict":"one paragraph","score":0-100,"safe_to_proceed":boolean} ===SPLIT=== PART 2 — Complete self-contained HTML tool: Brand color ${color} on #0F0F0F. Google Fonts Cormorant Garamond + IBM Plex Sans. Sticky nav key status dot. localStorage key management with safety explanation, clear button, link to console.anthropic.com/settings/keys. Input panel for: ${b2}. Run button calling https://api.anthropic.com/v1/messages with Part 1 system prompt AND header 'anthropic-dangerous-direct-browser-access: true'. Severity-badged issue cards that expand, verdict box, score. Error handling for 401 and 429. Mobile responsive. Fully self-contained. Output ONLY the two parts separated by ===SPLIT=== no markdown.`; try{ const data=await callClaude(key,metaSystem,`Domain: ${b1}\nUser pastes: ${b2}\nProduces: ${b3}`,4096); localStorage.setItem(KT,Date.now());setKeyLastUsed(Date.now()); const raw=data.content[0].text;const parts=raw.split('===SPLIT==='); const systemPrompt=parts[0].trim();const html=parts[1]?parts[1].trim():raw; const mcpPrompt=`Please publish this to NowPage using the MCP.\n\nDomain: ${pub}\nName: ${b1} — AI Analysis Tool\nSlug: ${slug}-tool\nTags: ["${slug}","ai-tool","embedded-intelligence"]\nUpdate mode: replace\n\nHTML:\n${html}`; const copyPrompt=`I have a complete Embedded Intelligence tool to publish.\n\nPublish to ${pub} with slug "${slug}-tool" using NowPage MCP if available, otherwise save as index.html.\n\nHTML:\n${html}`; const obj={systemPrompt,html,mcpPrompt,copyPrompt,domain:b1,pubDomain:pub,slug,inputLabel:'Sample '+b2.split(' ').slice(0,3).join(' ')}; localStorage.setItem(GK,JSON.stringify({...obj,savedAt:Date.now()})); setGenObj(obj);setHasSaved(true);setDeployTab(b6==='mcp'?'mcp':'copy'); }catch(e){setGenErr(errMsg(e));} finally{setGenLoading(false);} }; const restoreSaved=()=>{try{const raw=localStorage.getItem(GK);if(raw){const s=JSON.parse(raw);setGenObj(s);setHasSaved(true);setShowRestore(false);}}catch(e){}}; const discardSaved=()=>{localStorage.removeItem(GK);setHasSaved(false);setShowRestore(false);}; const lineCount=code.split('\n').length; const auditCount=auditResult?(auditResult.issues||[]).length:null; const testCount=testResult?(testResult.issues||[]).length:null; return ( <>
The Embedded Intelligence Pattern

See it work.
Understand why.
Build your own.

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.

↓ Start by pasting your code
{[['01','Browser calls API directly','No server. Your laptop talks to Claude.'],['02','APIs are just functions','Input in. Structured output out.'],['03','System prompt = your IP','Anyone copies HTML. Nobody has your framework.'],['04','BYOK = zero server cost','User brings key. Close tab. Gone. No database.'],['05','NowPage deploys it','Concept → live URL in one conversation.']].map(([n,t,d])=>(
{n}
{t}
{d}
))}
Live Demo · The AI Code Auditor
Paste your script.
See what breaks before it does.
Claude audits your cron job line by line. Every issue shows a fix snippet. Hit Generate Fixed Script on any issue to get the complete corrected version — then publish it live in one click.
How this works without a backend: Your browser calls Anthropic directly using the anthropic-dangerous-direct-browser-access header. No server. No proxy. Key in localStorage — close the tab and it's gone.
{!keyValid&&(
🔑 Your Anthropic API key — one step
Calls Claude directly from your browser. Key stays in localStorage — close the tab, it's gone. Get a key at console.anthropic.com · ~$0.01 per audit. Full details below ↓
handleKey(e.target.value)}/>
🔒 localStorage only
✈️ Direct to Anthropic
💨 Close tab = gone
)} {/* Optional publish domain for per-issue publish */} {keyValid && (
Publish Domain (optional — used when you publish a fixed script)
setPublishDomain(e.target.value)} placeholder="e.g. joe.asapai.net — where fixed scripts get published" style={{maxWidth:480}}/>
)}
Your Python Script
{lineCount} line{lineCount===1?'':'s'}