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
34 changes: 26 additions & 8 deletions site/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ const T = {
docs: {
title: 'Documentation', menu: 'Menu', on: 'On this page', prev: 'Previous', next: 'Next',
onlyOther: 'This page is only available in Chinese so far.', homeIntro: 'Start here, then dive into the features you need.',
sections: { 'getting-started': 'Getting Started', core: 'Core Capabilities', domains: 'Domain Guides', 'advanced-setup': 'Advanced Setup', reference: 'Reference', 'developer-docs': 'Developer Documentation' }
sections: { 'getting-started': 'Getting Started', core: 'Core Capabilities', domains: 'Domain Guides', 'setup-reference': 'More Features and Configuration' }
}
},
zh: {
Expand Down Expand Up @@ -240,22 +240,27 @@ const T = {
docs: {
title: '文档', menu: '目录', on: '本页内容', prev: '上一篇', next: '下一篇',
onlyOther: '本页暂时只有英文版。', homeIntro: '从这里开始,再深入你需要的功能。',
sections: { 'getting-started': '快速开始', core: '核心功能', domains: '领域教程', 'advanced-setup': '高级配置', reference: '参考', 'developer-docs': '开发者文档' }
sections: { 'getting-started': '快速开始', core: '核心功能', domains: '领域教程', 'setup-reference': '更多功能与配置' }
}
}
};

// The product documentation owns these six reader-facing groups. Listed pages keep
// The product documentation owns these reader-facing groups. Listed pages keep
// a useful reading order; new pages in the same directory are appended automatically.
const DOC_GROUPS = [
['getting-started', ['getting-started/deployment', 'getting-started/quick-start']],
['core', ['core/README', 'core/evolve', 'core/execution-workspaces', 'core/idea-tree']],
['domains', ['domains/README', 'domains/evolve-a-solution', 'domains/run-an-evolution-search', 'domains/literature-research']],
['advanced-setup', ['advanced-setup/README', 'advanced-setup/configure-custom-mcp', 'advanced-setup/configure-network-proxy', 'advanced-setup/science-memory-setup']],
['reference', ['reference/README', 'reference/configuration', 'reference/rest-api', 'reference/runtime-behavior', 'reference/builtin-tools', 'reference/web-tools', 'reference/jiuwenswarm-migration-status']],
['developer-docs', ['developer-docs/README', 'developer-docs/architecture', 'developer-docs/control-plane', 'developer-docs/agent', 'developer-docs/runner', 'developer-docs/sandbox-execution', 'developer-docs/science-memory', 'developer-docs/subagent-orchestration', 'developer-docs/skill-progressive-disclosure', 'developer-docs/science-connectors', 'developer-docs/web-frontend']]
['setup-reference', [
'advanced-setup/README', 'advanced-setup/configure-custom-mcp', 'advanced-setup/configure-network-proxy', 'advanced-setup/science-memory-setup',
'reference/README', 'reference/configuration', 'reference/rest-api', 'reference/runtime-behavior', 'reference/builtin-tools', 'reference/web-tools', 'reference/jiuwenswarm-migration-status'
]]
];

// Implementation notes are still built and linked from the core pages, but they are no longer a
// reader-facing group, so neither the sidebar nor the documentation index lists them.
const DOC_HIDDEN_GROUPS = ['developer-docs'];

// A panel that shows a screenshot is sized from the picture itself: the stylesheet multiplies the
// height left for the image by this ratio, so the dialog hugs the image instead of sitting in a
// wide empty box. Read straight from the PNG header (IHDR), so replacing the file is enough.
Expand Down Expand Up @@ -310,9 +315,13 @@ for (const lang of LANGS) {
}
const keyFor = (k) => (k === 'README' ? 'index' : k.replace(/\/README$/, '/index'));
const outPath = (k) => keyFor(k) + '.html';
// A group normally maps to one documentation directory; setup-reference folds two of them into a
// single rail entry, so it needs both prefixes to discover the pages that are not listed by name.
const GROUP_PREFIXES = { 'setup-reference': ['advanced-setup', 'reference'] };
const prefixesOf = (group) => GROUP_PREFIXES[group] || [group];
function groupItems(group) {
const listed = DOC_GROUPS.find(([name]) => name === group)?.[1] || [];
const available = Object.keys(sources).filter((k) => k.startsWith(group + '/'));
const available = Object.keys(sources).filter((k) => prefixesOf(group).some((p) => k.startsWith(p + '/')));
return [...listed.filter((k) => sources[k]), ...available.filter((k) => !listed.includes(k)).sort()];
}

Expand Down Expand Up @@ -399,6 +408,10 @@ function renderDoc(md, srcFile, lang, pagePath) {
}
const r = relative(ROOT, abs).split(sep).join('/');
if (r.startsWith('..')) return href;
// Sample data and screenshots are published with the site, so a link to them must not send
// the reader to GitHub for a file that is already served from this origin.
const inDocs = relative(DOCS, abs).split(sep).join('/');
if (!inDocs.startsWith('..') && /^(examples|images)\//.test(inDocs)) return rel(pagePath, 'docs/' + inDocs) + frag;
const isDir = existsSync(abs) && statSync(abs).isDirectory();
return `${GH}/${isDir ? 'tree' : 'blob'}/${BRANCH}/${r}${frag}`;
},
Expand Down Expand Up @@ -630,7 +643,7 @@ function indexDoc(lang, k, title, html) {

function docNav(lang, activeKey) {
const t = T[lang], S = t.docs.sections;
const groupIcons = { 'getting-started': 'book', core: 'tree', domains: 'flask', 'advanced-setup': 'plug', reference: 'task', 'developer-docs': 'graph' };
const groupIcons = { 'getting-started': 'book', core: 'tree', domains: 'flask', 'setup-reference': 'plug' };
const linkFor = (k, text, fromPath) => `<a href="${rel(fromPath, pathOf(lang, 'docs/' + outPath(k)))}"${k === activeKey ? ' class="active" aria-current="page"' : ''}>${esc(text)}</a>`;
return (fromPath) => {
return DOC_GROUPS.map(([group]) => {
Expand Down Expand Up @@ -721,11 +734,15 @@ cpSync(join(HERE, 'src', 'media'), join(DIST, 'media'), { recursive: true });
mkdirSync(join(DIST, 'vendor', 'molstar'), { recursive: true });
for (const f of ['molstar.css', 'molstar.js']) cpSync(join(ROOT, 'node_modules', 'molstar', 'build', 'viewer', f), join(DIST, 'vendor', 'molstar', f));
cpSync(join(DOCS, 'images'), join(DIST, 'docs', 'images'), { recursive: true });
// The walkthrough links the sample data it asks readers to upload, so it has to ship with the page.
if (existsSync(join(DOCS, 'examples'))) cpSync(join(DOCS, 'examples'), join(DIST, 'docs', 'examples'), { recursive: true });
write('favicon.svg', `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" rx="8" fill="#2563eb"/><g transform="translate(6 6) scale(.83)" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${IC.brand}</g></svg>`);
write('.nojekyll', '');
write('404.html', '<meta charset="utf-8"><meta http-equiv="refresh" content="0;url=./"><a href="./">ScienceDiscovery</a>');

const order = DOC_GROUPS.flatMap(([group]) => groupItems(group));
// Each hidden group pages only against itself, so no pager link sends a reader into it.
const hiddenOrder = DOC_HIDDEN_GROUPS.flatMap((group) => groupItems(group));

let pages = 0;
for (const lang of LANGS) {
Expand All @@ -734,6 +751,7 @@ for (const lang of LANGS) {
write(pathOf(lang, 'download/index.html'), legacyRedirect(lang, 'download/index.html', 'index.html', 'home'), false);
write(pathOf(lang, 'docs/index.html'), docsHome(lang, order));
for (const k of order) { write(pathOf(lang, 'docs/' + outPath(k)), docPage(k, lang, order)); pages++; }
for (const k of hiddenOrder) { write(pathOf(lang, 'docs/' + outPath(k)), docPage(k, lang, hiddenOrder), false); pages++; }
write(pathOf(lang, 'search-index.json'), JSON.stringify(INDEX[lang]));
}

Expand Down
8 changes: 5 additions & 3 deletions site/src/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,9 @@ a.file:hover { border-color: var(--accent-border-soft); background: var(--accent
.hidden { display: none !important; }

/* ---------- docs ---------- */
.docs { display: grid; grid-template-columns: 280px minmax(0, 1fr) 210px; max-width: 1400px; margin: 0 auto; align-items: start; }
/* The reader column is the point of this page, so the shell is wider than the marketing ones and
the two rails stay fixed: on a 1440px screen the article gets about 950px instead of 800px. */
.docs { display: grid; grid-template-columns: 268px minmax(0, 1fr) 200px; max-width: 1680px; margin: 0 auto; align-items: start; }
.docs-nav { position: sticky; top: var(--nav-h); height: calc(100vh - var(--nav-h)); overflow-y: auto; padding: 18px 12px 32px; border-right: 1px solid var(--border); background: var(--surface-subtle); }
.docs-nav-group { margin: 4px 0; border: 1px solid transparent; border-radius: 12px; }
.docs-nav-group[open] { border-color: var(--border); background: var(--surface); box-shadow: var(--shadow-1); }
Expand All @@ -390,14 +392,14 @@ a.file:hover { border-color: var(--accent-border-soft); background: var(--accent
.docs-nav-links a:hover { background: var(--surface-hover); color: var(--text-strong); text-decoration: none; }
.docs-nav-links a.active { background: var(--accent-softer); color: var(--accent-deep); font-weight: 650; }
.docs-nav-links a.active::before { position: absolute; top: 6px; bottom: 6px; left: -14px; width: 2px; border-radius: 2px; background: var(--accent); content: ''; }
.article { min-width: 0; padding: 48px 52px 24px; font-family: var(--serif); }
.article { min-width: 0; padding: 46px 44px 24px; font-family: var(--serif); }
.article > *:first-child { margin-top: 0; }
.article h1 { margin: 0 0 24px; color: var(--text-strong); font-size: clamp(32px, 3.1vw, 40px); line-height: 1.18; letter-spacing: -.045em; }
.article h2 { margin: 48px 0 16px; padding-top: 16px; border-top: 1px solid var(--border); color: var(--text-strong); font-size: 25px; letter-spacing: -.035em; }
.article h3 { margin: 32px 0 10px; color: var(--text-strong); font-size: 19px; letter-spacing: -.02em; }
.article h4 { margin: 22px 0 6px; color: var(--text-heading); font-size: 15px; }
.article p, .article li { color: var(--text); font-size: 16px; line-height: 1.78; }
.article > p, .article > ul, .article > ol, .article > blockquote { max-width: 76ch; }
.article > p, .article > ul, .article > ol, .article > blockquote { max-width: 96ch; }
.article li { margin: 4px 0; }
.article a { text-decoration: underline; text-decoration-color: var(--accent-border-soft); text-underline-offset: 2px; }
.article a:hover { text-decoration-color: var(--accent-strong); }
Expand Down
Loading