Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/net-routes.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ function searchMarkup(query, local, backfill, webResults, error) {
return `<article class="net-row"><div><h3><a class="inline-link" href="${e(url.href)}" rel="noopener noreferrer">${e(item.title || url.hostname)}</a></h3><p>${e(item.description || item.snippet || '')}</p><p class="net-row-meta">${e(url.hostname)}</p></div></article>`;
}).join('')}</div>`
: '<p class="muted">No Web results were returned.</p>';
return `<section class="page-head compact"><div class="eyebrow">W3BS NET · SEARCH</div><h1>Search the network.</h1><form class="search-bar" action="/search" method="get" role="search"><label class="sr-only" for="net-search">Search W3BS Net and the Web</label><input id="net-search" name="q" type="search" value="${e(query)}" placeholder="Name, namespace or Web query…" maxlength="200" required><button class="button primary" type="submit">Search →</button></form><p>W3BS primary registry first, Moshpit backfill second, and public Web results last.</p></section>${query ? `<section class="net-search-results"><h2>W3BS Net · local first</h2>${links(local)}</section><section class="net-search-results"><h2>Moshpit and peer backfill</h2>${error ? `<p class="net-meta">${e(error)}</p>` : ''}${links(backfill)}</section><section class="net-search-results"><h2>Public Web results</h2>${web}</section>` : '<section class="net-block"><p>Search local registrations and the Moshpit backfill. The query is sent to pit.world only for public Web results.</p></section>'}`;
return `<section class="page-head compact"><div class="eyebrow">W3BS NET · SEARCH</div><h1>Search the network.</h1><form class="search-bar" action="/search" method="get" role="search" toolname="search_network" tooldescription="Open W3BS Net search results for a query." toolautosubmit><label class="sr-only" for="net-search">Search W3BS Net and the Web</label><input id="net-search" name="q" type="search" value="${e(query)}" placeholder="Name, namespace or Web query…" maxlength="200" required><button class="button primary" type="submit">Search →</button></form><p>W3BS primary registry first, Moshpit backfill second, and public Web results last.</p></section>${query ? `<section class="net-search-results"><h2>W3BS Net · local first</h2>${links(local)}</section><section class="net-search-results"><h2>Moshpit and peer backfill</h2>${error ? `<p class="net-meta">${e(error)}</p>` : ''}${links(backfill)}</section><section class="net-search-results"><h2>Public Web results</h2>${web}</section>` : '<section class="net-block"><p>Search local registrations and the Moshpit backfill. The query is sent to pit.world only for public Web results.</p></section>'}`;
}

function operatorMarkup(username) {
Expand Down
2 changes: 1 addition & 1 deletion src/server.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function createApp({
'X-Content-Type-Options': 'nosniff',
'Referrer-Policy': 'strict-origin-when-cross-origin',
'Cache-Control': 'no-store',
'Content-Security-Policy': `default-src 'self'; script-src 'self' https://crawlproof.com ${FOOTER_SCRIPT_SRC}; style-src 'self'; img-src 'self' data: https://built.indie.pit.world https://pwamart.com https://profullstack.com; connect-src 'self' https://crawlproof.com https://pit.world; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self' https://pit.world`,
'Content-Security-Policy': `default-src 'self'; script-src 'self' https://crawlproof.com https://cdn.jsdelivr.net ${FOOTER_SCRIPT_SRC}; style-src 'self'; img-src 'self' data: https://built.indie.pit.world https://pwamart.com https://profullstack.com; connect-src 'self' https://crawlproof.com https://pit.world; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self' https://pit.world`,
'Permissions-Policy': 'camera=(), microphone=(), geolocation=()',
});
const railwayHealth =
Expand Down
8 changes: 4 additions & 4 deletions src/site.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ async function promptCards(store, query) {
(file) => JSON.parse(readFileSync(resolve(ROOT, file), 'utf8')),
);
const categories = new Map(catalog.map((item) => [item.id, item.category]));
return `<section class="page-head"><div class="eyebrow">THE OPEN PROMPT REGISTRY</div><h1>Good instructions<br>should <em>travel.</em></h1><p>Portable, versioned, signed artifacts. Inspect their source, understand their permissions and make them your own.</p></section><form class="search-bar" action="/prompts" role="search"><label class="sr-only" for="prompt-search">Search prompts</label><input id="prompt-search" name="q" type="search" value="${e(query.q || '')}" placeholder="Search by name, topic or URI…"><button class="button dark" type="submit">Search <span aria-hidden="true">→</span></button></form><div class="catalog-heading"><span>${resources.length} ${resources.length === 1 ? 'resource' : 'resources'}</span><span>Open examples · MIT licensed · v1.0.0</span></div><div class="prompt-grid">${resources.map((item) => `<a class="prompt-card" href="${resourceLink(item.id)}"><div class="prompt-top">${pill(categories.get(item.id) || item.type)}<span class="verified-small">${item.verification.valid ? '✓ Signed' : 'Verification failed'}</span></div><h2>${e(item.name)}</h2><p>${e(item.description)}</p><code>${e(item.id.replace('w3bs://', ''))}</code><div class="prompt-bottom"><span>${e(item.publisher.namespace)} <span class="muted">/ ${e(item.version)}</span></span><span aria-hidden="true">↗</span></div></a>`).join('') || '<div class="empty"><h2>No matching resources.</h2><p>Try another phrase or <a href="/prompts">view all prompts</a>.</p></div>'}</div><aside class="callout"><strong>A registry is an implementation, not the standard.</strong><p>Host your own compatible registry. Your resource identity and signed manifest remain portable.</p><a href="/developers">Build with W3BS →</a></aside>`;
return `<section class="page-head"><div class="eyebrow">THE OPEN PROMPT REGISTRY</div><h1>Good instructions<br>should <em>travel.</em></h1><p>Portable, versioned, signed artifacts. Inspect their source, understand their permissions and make them your own.</p></section><form class="search-bar" action="/prompts" role="search" toolname="search_prompts" tooldescription="Open the W3BS prompt registry filtered by name, topic or URI." toolautosubmit><label class="sr-only" for="prompt-search">Search prompts</label><input id="prompt-search" name="q" type="search" value="${e(query.q || '')}" placeholder="Search by name, topic or URI…"><button class="button dark" type="submit">Search <span aria-hidden="true">→</span></button></form><div class="catalog-heading"><span>${resources.length} ${resources.length === 1 ? 'resource' : 'resources'}</span><span>Open examples · MIT licensed · v1.0.0</span></div><div class="prompt-grid">${resources.map((item) => `<a class="prompt-card" href="${resourceLink(item.id)}"><div class="prompt-top">${pill(categories.get(item.id) || item.type)}<span class="verified-small">${item.verification.valid ? '✓ Signed' : 'Verification failed'}</span></div><h2>${e(item.name)}</h2><p>${e(item.description)}</p><code>${e(item.id.replace('w3bs://', ''))}</code><div class="prompt-bottom"><span>${e(item.publisher.namespace)} <span class="muted">/ ${e(item.version)}</span></span><span aria-hidden="true">↗</span></div></a>`).join('') || '<div class="empty"><h2>No matching resources.</h2><p>Try another phrase or <a href="/prompts">view all prompts</a>.</p></div>'}</div><aside class="callout"><strong>A registry is an implementation, not the standard.</strong><p>Host your own compatible registry. Your resource identity and signed manifest remain portable.</p><a href="/developers">Build with W3BS →</a></aside>`;
}
const BROWSE_COMMANDS = [
{
Expand Down Expand Up @@ -335,7 +335,7 @@ async function browse(store, query, browser) {
: result
? browseDetail(result)
: `<div class="resolver-empty"><span class="large-mark">w3bs<span>://</span></span><h2>The URI is canonical.<br>The surface is optional.</h2><p>Try <a href="${resourceLink(canonicalExample)}">the research prompt</a>, a Moshpit name like <a href="${browseLink('chovy.hacker')}">chovy.hacker</a>, or <a href="/prompts">explore the registry</a>.</p></div>`;
return `<section class="page-head compact"><div class="eyebrow">THE BROWSER</div><h1>A window into<br>the <em>Agentic Web.</em></h1><p>Enter a W3BS URI, a Moshpit name like chovy.hacker, a pit.world URL or any https URL. Moshpit names resolve on the server over Moshpit DNS.</p></section><form class="search-bar resolver" action="/browse" role="search"><label class="sr-only" for="resolve-uri">W3BS URI, Moshpit name or URL</label><input id="resolve-uri" name="q" value="${e(q || canonicalExample)}" required spellcheck="false" autocapitalize="off" maxlength="2048"><button class="button primary" type="submit">Browse <span aria-hidden="true">→</span></button></form>${body}${browseExamples()}${browseCli()}`;
return `<section class="page-head compact"><div class="eyebrow">THE BROWSER</div><h1>A window into<br>the <em>Agentic Web.</em></h1><p>Enter a W3BS URI, a Moshpit name like chovy.hacker, a pit.world URL or any https URL. Moshpit names resolve on the server over Moshpit DNS.</p></section><form class="search-bar resolver" action="/browse" role="search" toolname="browse_uri" tooldescription="Open a W3BS URI, Moshpit name, pit.world URL or https URL in the W3BS browser page." toolautosubmit><label class="sr-only" for="resolve-uri">W3BS URI, Moshpit name or URL</label><input id="resolve-uri" name="q" value="${e(q || canonicalExample)}" required spellcheck="false" autocapitalize="off" maxlength="2048"><button class="button primary" type="submit">Browse <span aria-hidden="true">→</span></button></form>${body}${browseExamples()}${browseCli()}`;
}
function resourceDetail(result) {
const { manifest: m, verification: v } = result;
Expand Down Expand Up @@ -388,7 +388,7 @@ async function packagesPage(store, query) {
return `<section class="page-head"><div class="eyebrow">THE W3BS CLI · PACKAGES</div><h1>Install from anywhere.<br><em>Update everything</em> at once.</h1><p><code>w3bs</code> is the W3BS command line, and packages are its first app. Every listed tool installs with its publisher's <code>curl | sh</code>; <code>w3bs packages</code> prints this list and <code>w3bs update</code> keeps everything current. The same CLI resolves, verifies and runs signed <code>w3bs://</code> resources.</p></section>
<section class="section resource-feature"><div><div class="eyebrow">GET STARTED</div><h2>One line.<br>Then one command.</h2><p>The installer downloads the prebuilt <code>w3bs</code> CLI for your machine (Linux or macOS, x86_64 or arm64), checks it, and lets it install itself from the signed W3BS repository. No Node, Python or Rust needed.</p><a class="text-link" href="/docs/package-manager.md">Read the guide <span aria-hidden="true">→</span></a></div><div class="terminal"><div class="terminal-tabs"><span class="terminal-title">install w3bs</span></div><pre><code>${e(INSTALL)}</code></pre><div class="terminal-result">${copy(INSTALL)}<span class="terminal-label">THEN</span><code>w3bs packages</code><code>w3bs install claude-code</code><code>w3bs update</code><code>w3bs ask business "How do I get my first customers?"</code></div></div></section>
<section class="section"><div class="section-heading"><div><div class="eyebrow">THE CATALOG</div><h2>${all.length} tools,<br>one update command.</h2></div><p>Agentic coding tools, MCP servers and the CLIs around them. Search, copy the publisher's own installer, or let <code>w3bs install</code> run it and track it for you.</p></div>
<form class="search-bar" action="/packages" role="search"><label class="sr-only" for="package-search">Search packages</label><input id="package-search" name="q" type="search" value="${e(query.q || '')}" placeholder="Search by name, vendor or command…">${query.show ? `<input type="hidden" name="show" value="${e(query.show)}">` : ''}<button class="button dark" type="submit">Search <span aria-hidden="true">→</span></button></form>
<form class="search-bar" action="/packages" role="search" toolname="search_packages" tooldescription="Open the W3BS package list filtered by name, vendor or command." toolautosubmit><label class="sr-only" for="package-search">Search packages</label><input id="package-search" name="q" type="search" value="${e(query.q || '')}" placeholder="Search by name, vendor or command…">${query.show ? `<input type="hidden" name="show" value="${e(query.show)}">` : ''}<button class="button dark" type="submit">Search <span aria-hidden="true">→</span></button></form>
<div class="catalog-heading"><span>${tab('', 'All', all.length)} ${tab('agentic', 'Agentic', all.filter((x) => x.agentic).length)} ${tab('ours', 'Profullstack', all.filter((x) => x.publisher === 'profullstack').length)}</span><span>${items.length} shown · curl installers only</span></div>
<div class="prompt-grid">${
items
Expand Down Expand Up @@ -1066,5 +1066,5 @@ export function pageShell({
canonical = '',
}) {
const share = `<meta property="og:type" content="website"><meta property="og:site_name" content="W3BS"><meta property="og:title" content="${e(title)} — W3BS"><meta property="og:description" content="${e(description)}">${canonical ? `<meta property="og:url" content="${e(canonical)}">` : ''}<meta name="twitter:card" content="summary"><meta name="twitter:title" content="${e(title)} — W3BS"><meta name="twitter:description" content="${e(description)}">`;
return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${e(title)} — W3BS</title><meta name="description" content="${e(description)}">${robots ? `<meta name="robots" content="${e(robots)}">` : ''}${canonical ? `<link rel="canonical" href="${e(canonical)}">` : ''}${share}<meta name="theme-color" content="#f6f4ed"><link rel="icon" type="image/svg+xml" href="/assets/mark.svg"><link rel="manifest" href="/manifest.webmanifest"><link rel="stylesheet" href="/assets/style.css"><script type="module" src="/assets/app.js"></script>${scripts}${track ? tracker(trackerSite()) : ''}</head><body>${header(active)}<main id="main">${content}</main>${footer()}<div id="toast" class="toast" role="status" aria-live="polite" hidden></div></body></html>`;
return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${e(title)} — W3BS</title><meta name="description" content="${e(description)}">${robots ? `<meta name="robots" content="${e(robots)}">` : ''}${canonical ? `<link rel="canonical" href="${e(canonical)}">` : ''}${share}<meta name="theme-color" content="#f6f4ed"><link rel="icon" type="image/svg+xml" href="/assets/mark.svg"><link rel="manifest" href="/manifest.webmanifest"><link rel="stylesheet" href="/assets/style.css"><script type="module" src="/assets/app.js"></script><script type="module" data-webmcp src="https://cdn.jsdelivr.net/npm/@profullstack/webmcp@0/src/embed.js" data-mcp="/mcp" data-mcp-exclude="w3bs_publish,w3bs_revoke" data-search="/search?q={query}" data-search-description="Search W3BS Net: packages, prompts, Moshpit names and pages across the network." data-pages='{"packages":"/packages","prompts":"/prompts","browse":"/browse","specs":"/specs","search":"/search","desktop":"/desktop","training":"/training","developers":"/developers"}'></script>${scripts}${track ? tracker(trackerSite()) : ''}</head><body>${header(active)}<main id="main">${content}</main>${footer()}<div id="toast" class="toast" role="status" aria-live="polite" hidden></div></body></html>`;
}
2 changes: 1 addition & 1 deletion test/site.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ test('CrawlProof: only for https://w3bs.org, never on pages that can carry accou
const home = await fetch(`${t.base}/`);
assert.ok((await home.text()).includes(tag));
const csp = home.headers.get('content-security-policy');
assert.match(csp, /script-src 'self' https:\/\/crawlproof\.com 'sha256-[A-Za-z0-9+/=]+';/);
assert.match(csp, /script-src 'self' https:\/\/crawlproof\.com https:\/\/cdn\.jsdelivr\.net 'sha256-[A-Za-z0-9+/=]+';/);
assert.match(csp, /connect-src 'self' https:\/\/crawlproof\.com https:\/\/pit\.world;/);
for (const path of ['/pricing', '/signup', '/login', '/login?next=%2Ffleet'])
assert.ok((await (await fetch(`${t.base}${path}`)).text()).includes(tag), path);
Expand Down
Loading