From 26aa2b289df4e0c7db27fb9783a48ed4d5f9e8c9 Mon Sep 17 00:00:00 2001 From: matcha Date: Mon, 12 Oct 2026 17:32:50 +0000 Subject: [PATCH] UpToDate iteration 2: clear monitor CTA and public GitHub issue intake --- ventures/up-to-date/site/app.js | 15 ++++++++++++--- ventures/up-to-date/site/index.html | 15 +++++++-------- ventures/up-to-date/site/style.css | 1 + 3 files changed, 20 insertions(+), 11 deletions(-) create mode 100644 ventures/up-to-date/site/style.css diff --git a/ventures/up-to-date/site/app.js b/ventures/up-to-date/site/app.js index 6671a43..fef1f31 100644 --- a/ventures/up-to-date/site/app.js +++ b/ventures/up-to-date/site/app.js @@ -14,7 +14,7 @@ else if(path.includes('.github/workflows/')){for(const m of text.matchAll(/\buse else {add(path.split('/').pop(),'Detected','stack file');gaps.push(`${path}: detected but full parser unavailable (including yarn/pnpm/Python project lock formats).`);} }catch(e){gaps.push(`${path}: parse failed: ${e.message}`);}} function signal(title,detail,url,date,severity='info'){report.signals.push({title,detail,url,date,severity});} -async function scan(){if($('run').disabled)return;let repo;try{repo=parseRepo($('repo').value)}catch(e){$('status').textContent=e.message;return;}$('run').disabled=true;$('demo').disabled=true;$('export').disabled=true;$('results').hidden=true; +async function scan(){if($('run').disabled)return;let repo;try{repo=parseRepo($('repo').value)}catch(e){$('status').textContent=e.message;return;}$('run').disabled=true;$('demo').disabled=true;$('export').disabled=true;$('results').hidden=true;$('onboarding').hidden=true;$('public-consent').checked=false; report={repo,checkedAt:new Date().toISOString(),items:[],signals:[],gaps:[],files:[]};const gaps=report.gaps;try{ $('status').textContent='Reading repository metadata…';const api=`https://api.github.com/repos/${repo}`;const meta=await json(api);const branch=meta.default_branch;const commit=await json(`${api}/commits/${encodeURIComponent(branch)}`);report.commit=commit.sha;report.branch=branch; const tree=await json(`${api}/git/trees/${commit.sha}?recursive=1`);if(tree.truncated)gaps.push('GitHub tree is truncated; inventory may omit files.');const paths=tree.tree.filter(f=>f.type==='blob'&&/(^|\/)(package\.json|package-lock\.json|yarn\.lock|pnpm-lock\.yaml|requirements[^/]*\.txt|pyproject\.toml|poetry\.lock|uv\.lock|go\.mod|Cargo\.toml|Dockerfile[^/]*|\.nvmrc|\.node-version)$|(^|\/)\.github\/workflows\/[^/]+\.ya?ml$/.test(f.path));if(paths.length>24)gaps.push(`${paths.length} relevant files found; first 24 scanned.`); @@ -29,5 +29,14 @@ const signature=JSON.stringify(report.items.map(i=>[i.name,i.version,i.path]));r $('status').textContent=`Scan complete · ${report.checkedAt} · ${repo}`; }catch(e){gaps.push(`Scan incomplete: ${e.message}. Check repository visibility, connectivity and GitHub's unauthenticated rate limit (usually 60 requests/hour/IP). Retry later; no clean bill of health is implied.`);$('status').textContent='Scan incomplete — see unknowns below.';} render();$('run').disabled=false;$('demo').disabled=false;$('export').disabled=false;} -function render(){$('results').hidden=false;$('summary').innerHTML=`

${report.files.length?'Live API evidence':'No repository evidence collected'} ${report.items.length} observations · ${report.files.length} files · ${esc(report.checkedAt)}

${esc(report.comparison||'Incomplete scan; no baseline saved.')} ${report.commit?link(`https://github.com/${report.repo}/tree/${report.commit}`,`Source ${report.commit.slice(0,8)}`):''}

`;$('inventory').innerHTML=report.items.map(i=>`${esc(i.name)}
${esc(i.ecosystem)}${esc(i.version)}${link(i.url,i.path)}${esc(i.coverage)}`).join('');$('signals').innerHTML=report.signals.map(s=>`
${esc(s.title)}

${esc(s.detail)}

${link(s.url,'Source')} · source/checked time: ${esc(s.date)}
`).join('')||'

No verified signals collected. See coverage gaps.

';$('gaps').innerHTML=report.gaps.map(g=>`
  • ${esc(g)}
  • `).join('');} -$('scan').onsubmit=e=>{e.preventDefault();scan();};$('demo').onclick=()=>{$('repo').value='https://github.com/expressjs/express';scan();};$('interval').onchange=()=>{clearInterval(timer);if(+$('interval').value)timer=setInterval(scan,+$('interval').value);};$('export').onclick=()=>{const url=URL.createObjectURL(new Blob([JSON.stringify(report,null,2)],{type:'application/json'}));const a=document.createElement('a');a.href=url;a.download='up-to-date-evidence.json';a.click();setTimeout(()=>URL.revokeObjectURL(url),1000);};if(new URLSearchParams(location.search).get('joined')==='1')$('join').innerHTML='

    Thanks — your interest has been recorded.

    '; +function render(){$('results').hidden=false;$('onboarding').hidden=!report.files.length;$('summary').innerHTML=`

    ${report.files.length?'Live API evidence':'No repository evidence collected'} ${report.items.length} observations · ${report.files.length} files · ${esc(report.checkedAt)}

    ${esc(report.comparison||'Incomplete scan; no baseline saved.')} ${report.commit?link(`https://github.com/${report.repo}/tree/${report.commit}`,`Source ${report.commit.slice(0,8)}`):''}

    `;$('inventory').innerHTML=report.items.map(i=>`${esc(i.name)}
    ${esc(i.ecosystem)}${esc(i.version)}${link(i.url,i.path)}${esc(i.coverage)}`).join('');$('signals').innerHTML=report.signals.map(s=>`
    ${esc(s.title)}

    ${esc(s.detail)}

    ${link(s.url,'Source')} · source/checked time: ${esc(s.date)}
    `).join('')||'

    No verified signals collected. See coverage gaps.

    ';$('gaps').innerHTML=report.gaps.map(g=>`
  • ${esc(g)}
  • `).join('');} +$('scan').onsubmit=e=>{e.preventDefault();scan();};$('demo').onclick=()=>{$('repo').value='https://github.com/expressjs/express';scan();};$('interval').onchange=()=>{clearInterval(timer);if(+$('interval').value)timer=setInterval(scan,+$('interval').value);};$('export').onclick=()=>{const url=URL.createObjectURL(new Blob([JSON.stringify(report,null,2)],{type:'application/json'}));const a=document.createElement('a');a.href=url;a.download='up-to-date-evidence.json';a.click();setTimeout(()=>URL.revokeObjectURL(url),1000);}; +function issueDraft(){ +if(!report?.files.length)throw new Error('Scan a public repo before requesting monitoring.'); +const repoUrl='https://github.com/'+report.repo; +const request=`UpToDate monitoring request\n\nRepository: ${repoUrl}\nRequested cadence: ${$('cadence').value}\nNotification preference: ${$('notification').value}\n\nFirst scan: ${report.checkedAt}\nSource commit: ${report.commit}\n\nI understand this is an early-access request. Hosted monitoring is NOT active until confirmed on this issue. No credentials or private details are included.`; +const query=new URLSearchParams({template:'early-access.yml',title:'Early access: UpToDate — '+report.repo,venture:'up-to-date',plan:'Free / hosted monitoring request',use:request}); +return 'https://github.com/teahubxyz/time/issues/new?'+query; +} +$('request').onsubmit=e=>{e.preventDefault();if(!$('public-consent').checked)return;const url=issueDraft();$('request-status').textContent='Opening your draft. Submit it on GitHub to request monitoring; hosted checks remain inactive.';location.assign(url);}; +document.querySelectorAll('a[href="#scan"]').forEach(a=>a.addEventListener('click',()=>setTimeout(()=>$('repo').focus({preventScroll:true}),300))); diff --git a/ventures/up-to-date/site/index.html b/ventures/up-to-date/site/index.html index f4b0b7a..5125a4c 100644 --- a/ventures/up-to-date/site/index.html +++ b/ventures/up-to-date/site/index.html @@ -1,8 +1,7 @@ -UpToDate · Stack monitor -
    NotPlanned / UpToDate01 — monitor first

    Your stack moves.
    Keep an eye on it.

    Inspect a public GitHub repository. See what it runs, what changed upstream, and which exact versions have published advisories. Read the evidence before deciding what to change.

    -
    -

    Live, unauthenticated APIs. No tokens, repository writes, or background service. This unlisted link is publicly accessible, not access-controlled.

    Ready. The Express example is a real repository, not sample data.
    -
    How this taste test works

    We read up to 24 matching files from the default branch, including nested manifests and CI files; check up to 12 dependencies; and keep source links and timestamps. Exact npm lockfile / Python pins can be checked against OSV. Ranges are declarations, not proof of installed versions. Docker tags and Action refs are inventoried; their vulnerability coverage is unknown. Refresh compares the inventory with your previous scan in this tab. Close the tab and monitoring stops.

    -
    Follow the experiment

    Free: this browser monitor. Hosted alerts and team monitoring are early-access ideas, with no checkout or paid service yet.

    Email is stored privately by NotPlanned for experiment updates.

    -
    +UpToDate — Know what your stack needs next +
    ↗ UpToDateby NotPlannedMonitor a repo ↗
    +

    LESS NOISE. MORE CONTEXT.

    Your code stays put.
    The world doesn’t.

    Catch upstream releases, deprecated dependencies, and published security advisories before they become your next surprise.

    Monitor a repo ↗

    Free first scan · Public GitHub repos · No signup

    +

    01 / TAKE A LOOK

    Start with one repository.

    No account needed

    Paste a public repository URL to get your first check-in.

    Monitoring runs only while this tab is open. Close it and checks stop.

    + +

    MONITOR FIRST. MAINTAIN WHEN YOU’RE READY.

    Context before changes.

    UpToDate reads declared stack files and checks live upstream sources. It never changes your code. Exact npm lockfile versions and Python pins can be checked against OSV; version ranges aren’t proof of what’s installed.

    What this scan covers

    Up to 24 matching files and 12 unique dependencies on the default branch. Docker and Actions are inventory only. Unsupported parsers, unavailable APIs and rate limits appear as unknowns. This page is public; private repositories and unattended monitoring are unavailable. Hosted monitoring is an early-access request, not an active service.

    +
    diff --git a/ventures/up-to-date/site/style.css b/ventures/up-to-date/site/style.css new file mode 100644 index 0000000..3275204 --- /dev/null +++ b/ventures/up-to-date/site/style.css @@ -0,0 +1 @@ +:root{font-family:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:#172f36;background:#f7f8f6;font-synthesis:none}*{box-sizing:border-box}html{scroll-behavior:smooth;scroll-padding-top:24px}body{margin:0}a{color:inherit}header,main,footer{max-width:1180px;margin:auto}header{display:flex;align-items:center;justify-content:space-between;padding:25px 32px;border-bottom:1px solid #dce3df}.brand{font-size:24px;font-weight:750;text-decoration:none;letter-spacing:-1px}.brand span{display:block;font-size:11px;letter-spacing:1px;color:#607570;margin:4px 0 0 25px}main{padding:0 32px}.hero{display:grid;grid-template-columns:1.25fr 1fr;gap:70px;align-items:center;padding:74px 0 68px}.eyebrow{font-size:11px;font-weight:750;letter-spacing:2px;color:#52756a}h1{font-size:clamp(42px,5.3vw,65px);line-height:1.08;letter-spacing:-3px;margin:24px 0}h1 em{font-style:normal;color:#4d796b}h2{font-size:30px;letter-spacing:-1px;line-height:1.2;margin:12px 0 20px}p{line-height:1.65}.lede{font-size:18px;color:#566b6e;max-width:520px;margin-bottom:28px}.button,button{display:inline-block;text-decoration:none;background:#b9ef72;color:#18392d;border:1px solid #addc6b;border-radius:8px;padding:16px 23px;font:650 15px inherit;font-family:inherit;font-size:15px;font-weight:650;cursor:pointer}.small{padding:11px 17px;font-size:13px}.meta,small{font-size:12px;color:#667976;line-height:1.6}.preview{background:#173c37;color:#edf3e9;border-radius:16px;padding:27px 30px;box-shadow:0 18px 45px #183d3712}.preview h2{font-size:32px;margin-top:28px}.preview-top{font-size:10px;letter-spacing:1.5px;display:flex;align-items:center;gap:8px}.preview-top span:last-child{margin-left:auto}.dot{width:7px;height:7px;border-radius:100%;background:#b9ef72}.preview-row{display:flex;align-items:center;gap:16px;border-top:1px solid #ffffff24;padding:19px 0;font-size:14px}.preview-row b{color:#b9ef72;font-size:11px}.preview-row span:last-child{margin-left:auto;color:#b9ef72}.preview small{display:block;color:#b5c9bd;font-size:11px}.preview .meta{color:#b5c9bd;margin-bottom:0}.scan-panel{border:1px solid #d8e2db;border-radius:14px;padding:30px;background:white;scroll-margin-top:20px}.section-heading{display:flex;justify-content:space-between;align-items:center}.badge{display:inline-block;font-size:11px;font-weight:600;padding:7px 10px;border-radius:5px;background:#e8f0e4;color:#385c49}label{font-size:13px;display:block;margin:12px 0 8px}input,select{font:inherit;font-size:16px;background:#fff;border:1px solid #becdc5;border-radius:7px;padding:14px;color:#172f36;max-width:100%;min-width:0}.input-row{display:flex;gap:10px}.input-row input{flex:1}.text-button{background:none;border:0;padding:14px 0;color:#496b5f;font-size:13px}.bar{display:flex;gap:16px;align-items:center;flex-wrap:wrap}.bar label{margin:0;font-size:12px}.bar select{font-size:12px;padding:8px}.secondary{background:transparent;border:1px solid #cad6cf;font-size:12px;padding:9px}#status{font-size:13px;margin:7px 0 18px;overflow-wrap:anywhere}button:disabled{opacity:.5;cursor:wait}#results{margin:35px 0}#summary{font-size:13px;padding:10px 0}.onboarding{display:grid;grid-template-columns:1fr 1fr;gap:45px;padding:30px;background:#edf2e7;border:1px solid #d5e0cd;border-radius:14px;margin:15px 0 35px}.onboarding p{font-size:14px}.onboarding select{width:100%;font-size:14px}.consent{display:flex;align-items:flex-start;gap:9px;font-size:12px;line-height:1.6;margin:18px 0}.consent input{flex:none;margin-top:3px;width:17px;height:17px}.onboarding button{width:100%}.onboarding .meta{font-size:11px}article{background:white;border:1px solid #d8e2db;border-radius:10px;padding:20px;margin:12px 0;font-size:14px}article.alert{border-left:4px solid #b46c31}article p{color:#586b68}article a{color:#39725f}details{border-top:1px solid #dce3df;margin:20px 0;padding-top:18px}summary{cursor:pointer;font-size:14px;font-weight:600}.table-wrap{overflow:auto}table{border-collapse:collapse;width:100%;font-size:12px}th,td{padding:12px 8px;text-align:left;border-bottom:1px solid #dce3df;overflow-wrap:anywhere;vertical-align:top}th{font-size:10px;text-transform:uppercase}#gaps{font-size:13px;line-height:1.8;overflow-wrap:anywhere}.explain{max-width:650px;padding:65px 0 50px}.explain p{font-size:14px;color:#586b68}footer{display:flex;align-items:center;justify-content:space-between;gap:20px;border-top:1px solid #dce3df;padding:25px 32px;font-size:11px;color:#667976}footer .brand{font-size:19px;color:#172f36}:focus-visible{outline:3px solid #6f9f51;outline-offset:3px}[hidden]{display:none!important}@media(max-width:700px){header{padding:20px}.brand{font-size:21px}main{padding:0 20px}.hero{grid-template-columns:1fr;gap:30px;padding:40px 0}h1{letter-spacing:-2px}.preview{padding:24px}.scan-panel{padding:21px}.section-heading{display:block}.section-heading .badge{margin-bottom:15px}.input-row{flex-direction:column}.input-row button{width:100%}.onboarding{grid-template-columns:1fr;gap:8px;padding:22px}h2{font-size:27px}.explain{padding:40px 0}footer{padding:22px 20px;flex-wrap:wrap}table{min-width:580px}}