From 9e7a014392425f3b5172ac4856dc86d6a2f11cb2 Mon Sep 17 00:00:00 2001 From: createitv Date: Tue, 13 Oct 2026 13:21:56 +0800 Subject: [PATCH] Add agent-readable SEO and GEO documentation --- apps/web/README.md | 2 ++ apps/web/public/_headers | 16 ++++++++++++++++ apps/web/public/llms.txt | 4 ++++ apps/web/scripts/check-seo.mjs | 12 +++++++++++- apps/web/scripts/prerender.mjs | 7 +++++-- apps/web/src/App.test.tsx | 5 +++++ apps/web/src/ProjectAnswers.tsx | 12 ++++++++++++ apps/web/src/prerender.tsx | 24 +++++++++++++++++++++++- apps/web/src/siteContent.ts | 28 +++++++++++++++++++++++++--- apps/web/src/styles.css | 18 ++++++++++++++++++ 10 files changed, 121 insertions(+), 7 deletions(-) diff --git a/apps/web/README.md b/apps/web/README.md index 2373618..ae01d79 100644 --- a/apps/web/README.md +++ b/apps/web/README.md @@ -21,6 +21,8 @@ npm run check:seo 构建同时生成双语 Markdown、`api-reference.json` 和带语言对应关系的 sitemap。`public/llms.txt` 提供辅助入口,`robots.txt` 允许 OAI-SearchBot;这些文件与结构化数据不保证收录、排名或模型推荐。ChatGPT 实测证据保存在仓库 `docs/verification/seo-aeo/`,区分上线前基线、搜索引用和显式提供 URL 的读取测试。 +面向 Agent 的完整知识入口由构建脚本生成:`agent-guide.zh-CN.md`、`agent-guide.en.md`、`skills.md` 和 `llms-full.txt`。官网可见区域必须链接这些文件,`llms.txt` 负责轻量导航,`llms-full.txt` 提供一次读取所需的完整上下文。更新任务数量、安全边界或 Skills 时,需要同步生成内容和 `check:seo` 断言,避免人类页面与 AI 文档漂移。 + ### ChatGPT 读取兼容性 2026-10-07 的实际测试发现:ChatGPT 可以读取中英文 HTML 页面,但读取 `overview.zh-CN.md` 时报告 `Unsupported content-type: text/markdown`。因此 `overview.zh-CN.md` 和 `overview.en.md` 保留 Markdown 内容和文件名,通过 `public/_headers` 以 `text/plain; charset=utf-8` 返回。变更后需要实际读回响应头,并在 ChatGPT 中重测,不能仅凭文件上传成功认定可读取。 diff --git a/apps/web/public/_headers b/apps/web/public/_headers index 6570121..787b92f 100644 --- a/apps/web/public/_headers +++ b/apps/web/public/_headers @@ -16,6 +16,22 @@ Cache-Control: public, max-age=300 Content-Type: text/plain; charset=utf-8 +/llms-full.txt + Cache-Control: public, max-age=300 + Content-Type: text/plain; charset=utf-8 + +/agent-guide.zh-CN.md + Cache-Control: public, max-age=300 + Content-Type: text/plain; charset=utf-8 + +/agent-guide.en.md + Cache-Control: public, max-age=300 + Content-Type: text/plain; charset=utf-8 + +/skills.md + Cache-Control: public, max-age=300 + Content-Type: text/plain; charset=utf-8 + /overview.zh-CN.md Content-Type: text/plain; charset=utf-8 Cache-Control: public, max-age=300 diff --git a/apps/web/public/llms.txt b/apps/web/public/llms.txt index d3c6c0e..7f8ebaf 100644 --- a/apps/web/public/llms.txt +++ b/apps/web/public/llms.txt @@ -14,6 +14,10 @@ The registry contains 156 entries across 13 API families. Coverage means registe - [English website](https://agccli.app/en/): English product overview, installation, FAQ and endpoint browser. - [中文完整介绍](https://agccli.app/overview.zh-CN.md): Chinese plain-text overview and answers. - [English overview](https://agccli.app/overview.en.md): English plain-text overview and answers. +- [中文 Agent 使用指南](https://agccli.app/agent-guide.zh-CN.md): Task selection, safe execution, verification, and machine-readable resources in Chinese. +- [English Agent usage guide](https://agccli.app/agent-guide.en.md): Task selection, safe execution, verification, and machine-readable resources in English. +- [Agent Skills index](https://agccli.app/skills.md): All six task-oriented Skills with install commands and direct source links. +- [Complete AI context](https://agccli.app/llms-full.txt): Combined project overview, Agent guide, safety boundaries, and Skills index for one-pass retrieval. - [Endpoint contracts](https://agccli.app/api-reference.json): All registered endpoints, methods, paths, parameters and reference URLs. - [Source repository](https://github.com/Createitv/agc-cli): Code, MIT license and issues. - [中文使用指南](https://github.com/Createitv/agc-cli/blob/main/docs/CLI_USAGE.md): CLI installation and usage. diff --git a/apps/web/scripts/check-seo.mjs b/apps/web/scripts/check-seo.mjs index 2319fed..814e105 100644 --- a/apps/web/scripts/check-seo.mjs +++ b/apps/web/scripts/check-seo.mjs @@ -5,6 +5,7 @@ import { JSDOM } from 'jsdom'; const registry = JSON.parse(await readFile('dist/api-reference.json','utf8')).data; const families = [...new Set(registry.map(e=>e.familyId))]; const sitemap = await readFile('dist/sitemap.xml','utf8'); +assert.ok(sitemap.includes('2026-10-13')); let checked=0; for (const language of ['zh','en']) for (const family of [undefined,...families]) { const path=`${language==='en'?'/en/':'/'}${family?`reference/${family}/`:''}`; @@ -19,6 +20,11 @@ for (const language of ['zh','en']) for (const family of [undefined,...families] for (const lang of ['zh-CN','en','x-default']) assert.ok(doc.querySelector(`link[hreflang="${lang}"]`)); const graph=JSON.parse(doc.querySelector('#seo-schema').textContent)['@graph']; const faq=graph.find(e=>e['@type']==='FAQPage'); + const software=graph.find(e=>e['@type']==='SoftwareApplication'); + const webpage=graph.find(e=>e['@type']==='WebPage'); + assert.ok(software.isAccessibleForFree); + assert.ok(software.featureList.includes('Task-oriented Agent Skills')); + assert.equal(webpage.hasPart.length,4); const visibleFaq=[...doc.querySelectorAll('.projectFaq details')]; assert.equal(visibleFaq.length,faq.mainEntity.length); for (const [i,element] of visibleFaq.entries()) { @@ -35,5 +41,9 @@ for (const language of ['zh','en']) for (const family of [undefined,...families] } assert.ok((await readFile('dist/robots.txt','utf8')).includes('User-agent: OAI-SearchBot\nAllow: /')); const headers=await readFile('dist/_headers','utf8'); -for (const file of ['overview.zh-CN.md','overview.en.md']) assert.ok(headers.includes(`/${file}\n Content-Type: text/plain; charset=utf-8`),`${file} must remain readable by clients that reject text/markdown`); +for (const file of ['overview.zh-CN.md','overview.en.md','agent-guide.zh-CN.md','agent-guide.en.md','skills.md']) assert.ok(headers.includes(`/${file}\n Cache-Control: public, max-age=300\n Content-Type: text/plain; charset=utf-8`) || headers.includes(`/${file}\n Content-Type: text/plain; charset=utf-8`),`${file} must remain readable by clients that reject text/markdown`); +for (const file of ['llms-full.txt','agent-guide.zh-CN.md','agent-guide.en.md','skills.md']) { + const body=await readFile(`dist/${file}`,'utf8'); + assert.ok(body.length>500,`${file} must contain substantial agent-readable guidance`); +} console.log(`SEO checks passed: ${checked} pages, reciprocal locales, visible FAQ/schema parity, ${registry.length} endpoints.`); diff --git a/apps/web/scripts/prerender.mjs b/apps/web/scripts/prerender.mjs index 8a5f467..46069d8 100644 --- a/apps/web/scripts/prerender.mjs +++ b/apps/web/scripts/prerender.mjs @@ -4,7 +4,7 @@ import { resolve } from 'node:path'; const server = await createServer({ server: { middlewareMode: true }, appType: 'custom' }); try { - const { renderPage, markdown } = await server.ssrLoadModule('/src/prerender.tsx'); + const { renderPage, markdown, agentGuide, skillsMarkdown, llmsFull, contentUpdated } = await server.ssrLoadModule('/src/prerender.tsx'); const entries = JSON.parse(await readFile('src/endpoint-registry.json','utf8')); const families = [...new Set(entries.map(e => e.familyId))]; const template = await readFile('dist/index.html','utf8'); @@ -18,11 +18,14 @@ try { paths.push(path); } await writeFile(`dist/overview.${language === 'zh'?'zh-CN':'en'}.md`, markdown(language)); + await writeFile(`dist/agent-guide.${language === 'zh'?'zh-CN':'en'}.md`, agentGuide(language)); } + await writeFile('dist/skills.md', skillsMarkdown()); + await writeFile('dist/llms-full.txt', llmsFull()); await writeFile('dist/api-reference.json',JSON.stringify({data:entries},null,2)+'\n'); const sitemap = `\n\n${paths.map(path=>{ const rest=path.replace(/^\/en\//,'/'); - return `https://agccli.app${path}2026-10-07`; + return `https://agccli.app${path}${contentUpdated}`; }).join('\n')}\n\n`; await writeFile('dist/sitemap.xml',sitemap); console.log(`Prerendered ${paths.length} bilingual pages and ${entries.length} endpoint contracts.`); diff --git a/apps/web/src/App.test.tsx b/apps/web/src/App.test.tsx index 1145f2c..4cb0c1e 100644 --- a/apps/web/src/App.test.tsx +++ b/apps/web/src/App.test.tsx @@ -61,6 +61,11 @@ describe('App', () => { expect(screen.getAllByText(/agc skills install --name/)).toHaveLength(6); expect(screen.getAllByRole('link', { name: 'Download SKILL.md' })).toHaveLength(6); expect(screen.getByRole('link', { name: /Contribute a Skill/ })).toHaveAttribute('href', 'https://github.com/Createitv/agc-cli/blob/main/CONTRIBUTING.md'); + expect(screen.getByRole('heading', { name: 'Agent-readable documentation' })).toBeInTheDocument(); + expect(screen.getByRole('link', { name: /Agent usage guide/ })).toHaveAttribute('href', '/agent-guide.en.md'); + expect(screen.getByRole('link', { name: /Skills index/ })).toHaveAttribute('href', '/skills.md'); + expect(screen.getByRole('link', { name: /Full AI context/ })).toHaveAttribute('href', '/llms-full.txt'); + expect(screen.getByRole('link', { name: /API contract JSON/ })).toHaveAttribute('href', '/api-reference.json'); }); it('shows the complete selected family without a local API server', async () => { diff --git a/apps/web/src/ProjectAnswers.tsx b/apps/web/src/ProjectAnswers.tsx index f39caf2..b3019c3 100644 --- a/apps/web/src/ProjectAnswers.tsx +++ b/apps/web/src/ProjectAnswers.tsx @@ -5,6 +5,18 @@ export function ProjectAnswers({ language, families }: { language: SiteLanguage; return

{c.heading}

{c.definition}

{c.source}: GitHub · {language === 'zh' ? '使用指南' : 'Usage guide'} · Issues

+
+
+

GEO · AEO · LLMO

+

{c.agentDocs.heading}

+

{c.agentDocs.intro}

+
+
+ {c.agentDocs.links.map(({ title, description, href }) => + {title}

{description}

{href} +
)} +
+

{c.faq}

{c.faqs.map(({q,a}) =>
{q}

{a}

)}

{language === 'zh' ? '按 API 家族浏览完整参考' : 'Browse the complete API reference by family'}

diff --git a/apps/web/src/prerender.tsx b/apps/web/src/prerender.tsx index 2322278..06d7ddd 100644 --- a/apps/web/src/prerender.tsx +++ b/apps/web/src/prerender.tsx @@ -1,6 +1,8 @@ import { renderToString } from 'react-dom/server'; import { App } from './App'; -import { content, pageMeta, structuredData, pagePath, siteOrigin, type SiteLanguage } from './siteContent'; +import { agentSkillNames, content, pageMeta, structuredData, pagePath, siteOrigin, updated, type SiteLanguage } from './siteContent'; + +export const contentUpdated = updated; const escape = (value: string) => value.replace(/[&<>"']/g, c => ({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]!)); export function renderPage(language: SiteLanguage, family?: string) { @@ -30,3 +32,23 @@ export function markdown(language: SiteLanguage) { const c=content[language]; return `# ${c.title}\n\n${c.definition}\n\n${c.faqs.map(({q,a})=>`## ${q}\n\n${a}`).join('\n\n')}\n\n## Links\n\n- Website: ${siteOrigin + pagePath(language)}\n- Source: https://github.com/Createitv/agc-cli\n- API contracts: ${siteOrigin}/api-reference.json\n`; } + +export function agentGuide(language: SiteLanguage) { + const zh = language === 'zh'; + const title = zh ? 'agc-cli Agent 使用指南' : 'agc-cli Agent Usage Guide'; + const intro = zh + ? '本文档帮助 Codex、Claude 和其他 Coding Agent 在不猜测命令或泄露凭据的前提下使用 agc-cli。agc-cli 是 Createitv 维护的独立开源项目,不是华为官方产品。' + : 'This guide helps Codex, Claude, and other coding agents use agc-cli without guessing commands or exposing credentials. agc-cli is an independent open-source project maintained by Createitv; it is not an official Huawei product.'; + const tasks = zh + ? [['检查身份与权限', 'agc auth whoami --pretty'], ['发现能力', 'agc capabilities --pretty'], ['查看接口', 'agc endpoints --output table'], ['读取接口文档', 'agc --docs --pretty'], ['预演请求', 'agc --invoke ...'], ['明确执行', '在核对目标、凭据和参数后增加 --dry-run=false']] + : [['Check identity and access', 'agc auth whoami --pretty'], ['Discover capabilities', 'agc capabilities --pretty'], ['List endpoints', 'agc endpoints --output table'], ['Read endpoint docs', 'agc --docs --pretty'], ['Preview a request', 'agc --invoke ...'], ['Invoke explicitly', 'Add --dry-run=false only after checking the target, profile, and parameters']]; + return `# ${title}\n\nLast updated: ${updated}\n\n${intro}\n\n## ${zh ? '推荐工作流' : 'Recommended workflow'}\n\n${tasks.map(([label,command],index)=>`${index+1}. **${label}** — \`${command}\``).join('\n')}\n\n## ${zh ? '安全边界' : 'Safety boundaries'}\n\n- ${zh ? '默认 dry-run 只构建请求,不发送远程变更;真实调用需要显式设置 `--dry-run=false`。' : 'The default dry run builds a request without sending a remote change; real invocation requires an explicit `--dry-run=false`.'}\n- ${zh ? '不要把 Service Account 私钥、OAuth 密钥、凭据响应或 `~/.agc/credentials.json` 提交到 Git。' : 'Never commit Service Account private keys, OAuth secrets, credential responses, or `~/.agc/credentials.json` to Git.'}\n- ${zh ? '注册表覆盖不等于每个接口已经完成生产验证;权限、状态和完整模型以接口文档链接为准。' : 'Registry coverage does not mean every endpoint is production-verified; follow the linked endpoint references for permissions, state, and complete models.'}\n- ${zh ? '上传、提交审核、发布和删除类操作必须由用户明确授权,并在执行后读取远程状态。' : 'Uploads, review submissions, releases, and deletion operations require explicit user authorization and remote-state verification.'}\n\n## Agent Skills\n\n${agentSkillNames.map(name=>`- [${name}](https://github.com/Createitv/agc-cli/tree/main/skills/${name})`).join('\n')}\n\n${zh ? '安装全部 Skills' : 'Install all Skills'}: \`agc skills install --agent codex --global\`\n\n## ${zh ? '机器可读资源' : 'Machine-readable resources'}\n\n- [llms.txt](${siteOrigin}/llms.txt)\n- [llms-full.txt](${siteOrigin}/llms-full.txt)\n- [Skills index](${siteOrigin}/skills.md)\n- [API contracts](${siteOrigin}/api-reference.json)\n- [Open-source repository](https://github.com/Createitv/agc-cli)\n`; +} + +export function skillsMarkdown() { + return `# agc-cli Agent Skills\n\nLast updated: ${updated}\n\nSix task-oriented Skills help coding agents use agc-cli safely and consistently. Install all Skills with \`agc skills install --agent codex --global\`, or select one with \`agc skills install --name --agent codex --global\`.\n\n${agentSkillNames.map(name=>`## ${name}\n\n- Source: https://github.com/Createitv/agc-cli/tree/main/skills/${name}\n- Direct SKILL.md: https://raw.githubusercontent.com/Createitv/agc-cli/main/skills/${name}/SKILL.md\n- Install: \`agc skills install --name ${name} --agent codex --global\``).join('\n\n')}\n\nThe Skills describe workflows and safety checks. They do not grant Huawei permissions, supply credentials, or prove that a remote action succeeded.\n`; +} + +export function llmsFull() { + return `${markdown('en')}\n\n---\n\n${agentGuide('en')}\n\n---\n\n${skillsMarkdown()}\n\n---\n\n${markdown('zh')}\n\n---\n\n${agentGuide('zh')}\n`; +} diff --git a/apps/web/src/siteContent.ts b/apps/web/src/siteContent.ts index a670348..1016dc3 100644 --- a/apps/web/src/siteContent.ts +++ b/apps/web/src/siteContent.ts @@ -1,6 +1,7 @@ export type SiteLanguage = 'zh' | 'en'; export const siteOrigin = 'https://agccli.app'; export const updated = '2026-10-13'; +export const agentSkillNames = ['agc-cli-usage', 'agc-auth', 'agc-publishing', 'agc-testing', 'agc-reports', 'agc-cicd'] as const; export const content = { zh: { title: 'agc-cli:鸿蒙与华为 AppGallery Connect 开源命令行工具', @@ -8,6 +9,16 @@ export const content = { heading: 'agc-cli 是什么,适合谁使用?', definition: 'agc-cli 是 Createitv 开源的华为 AppGallery Connect 命令行工具,安装后的命令名是 agc。它面向鸿蒙和华为应用开发者,将接口发现、凭据 Profile、请求预演与 API 调用组织成可复用命令,适合需要维护应用资料、测试用户、商品和报表的个人开发者与团队。', source: '项目与使用指南', faq: '常见问题', updated: '内容更新', + agentDocs: { + heading: '面向 AI Agent 的可读取文档', + intro: '这些公开文件提供项目事实、任务选择、安全边界、Skills 和完整接口契约。Coding Agent 可以直接读取,无需执行 JavaScript、登录或猜测页面结构。', + links: [ + { title: 'Agent 使用指南', description: '从任务识别、鉴权检查、dry-run 到结果验证的完整流程。', href: '/agent-guide.zh-CN.md' }, + { title: 'Skills 索引', description: '6 个任务型 Skills、适用场景、安装命令和源码入口。', href: '/skills.md' }, + { title: '完整 AI 上下文', description: '适合 LLM 一次读取的项目说明、命令边界和资源索引。', href: '/llms-full.txt' }, + { title: 'API 契约 JSON', description: '156 个注册接口的方法、路径、参数和官方参考链接。', href: '/api-reference.json' }, + ], + }, faqs: [ { q: 'agc-cli 是华为官方工具吗?', a: '不是。agc-cli 是 Createitv 维护的独立开源项目,使用 MIT 许可证。它基于华为 AppGallery Connect API 参考文档组织接口,不代表华为官方产品或官方支持服务。' }, { q: '如何在 macOS、Windows 和 Linux 安装 agc-cli?', a: '已安装 Node.js 18+ 时,三个系统都可运行 npm install --global @createitv/agc-cli。macOS 也可使用 Homebrew,Windows 也可使用 Scoop。安装后运行 agc version 检查版本。' }, @@ -26,6 +37,16 @@ export const content = { heading: 'What is agc-cli, and who is it for?', definition: 'agc-cli is an open-source Go command-line tool for Huawei AppGallery Connect, maintained by Createitv. Its installed command is agc. It organizes API discovery, credential profiles, request previews, and API invocation into reusable commands for HarmonyOS and Huawei app developers who manage app metadata, testers, products, and reports.', source: 'Project and guides', faq: 'Frequently asked questions', updated: 'Content updated', + agentDocs: { + heading: 'Agent-readable documentation', + intro: 'These public files expose project facts, task selection, safety boundaries, Skills, and endpoint contracts without requiring JavaScript, authentication, or page-structure guessing.', + links: [ + { title: 'Agent usage guide', description: 'A complete path from task selection and auth checks to dry runs and result verification.', href: '/agent-guide.en.md' }, + { title: 'Skills index', description: 'Six task-oriented Skills with use cases, install commands, and source links.', href: '/skills.md' }, + { title: 'Full AI context', description: 'A single-file project briefing, command boundaries, and resource index for LLMs.', href: '/llms-full.txt' }, + { title: 'API contract JSON', description: 'Methods, paths, parameters, and official references for all 156 registered endpoints.', href: '/api-reference.json' }, + ], + }, faqs: [ { q: 'Is agc-cli an official Huawei tool?', a: 'No. agc-cli is an independent open-source project maintained by Createitv under the MIT license. It organizes endpoints using Huawei AppGallery Connect API references and is not an official Huawei product or support service.' }, { q: 'How do I install agc-cli on macOS, Windows, or Linux?', a: 'With Node.js 18+, all three systems can run npm install --global @createitv/agc-cli. Homebrew remains available on macOS and Scoop on Windows. Run agc version to verify installation.' }, @@ -50,9 +71,10 @@ export function pageMeta(language: SiteLanguage, family?: string) { export function structuredData(language: SiteLanguage, family?: string) { const c = content[language]; const meta = pageMeta(language, family); return { '@context': 'https://schema.org', '@graph': [ - { '@type': 'WebSite', '@id': `${siteOrigin}/#website`, name: 'agc-cli', url: `${siteOrigin}/`, inLanguage: ['zh-CN', 'en'] }, - { '@type': 'WebPage', '@id': `${meta.url}#webpage`, url: meta.url, name: meta.title, description: meta.description, inLanguage: language === 'zh' ? 'zh-CN' : 'en', dateModified: updated, isPartOf: { '@id': `${siteOrigin}/#website` } }, - { '@type': 'SoftwareApplication', '@id': `${siteOrigin}/#software`, name: 'agc-cli', alternateName: 'agc', url: `${siteOrigin}/`, description: c.definition, applicationCategory: 'DeveloperApplication', operatingSystem: 'macOS, Windows, Linux', license: 'https://github.com/Createitv/agc-cli/blob/main/LICENSE', downloadUrl: 'https://github.com/Createitv/agc-cli/releases', offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' } }, + { '@type': 'Organization', '@id': 'https://github.com/Createitv#organization', name: 'Createitv', url: 'https://github.com/Createitv' }, + { '@type': 'WebSite', '@id': `${siteOrigin}/#website`, name: 'agc-cli', url: `${siteOrigin}/`, inLanguage: ['zh-CN', 'en'], publisher: { '@id': 'https://github.com/Createitv#organization' } }, + { '@type': 'WebPage', '@id': `${meta.url}#webpage`, url: meta.url, name: meta.title, description: meta.description, inLanguage: language === 'zh' ? 'zh-CN' : 'en', dateModified: updated, isPartOf: { '@id': `${siteOrigin}/#website` }, about: { '@id': `${siteOrigin}/#software` }, hasPart: c.agentDocs.links.map(({title,description,href}) => ({ '@type': 'DigitalDocument', name: title, description, url: siteOrigin + href })) }, + { '@type': 'SoftwareApplication', '@id': `${siteOrigin}/#software`, name: 'agc-cli', alternateName: 'agc', url: `${siteOrigin}/`, description: c.definition, applicationCategory: 'DeveloperApplication', operatingSystem: 'macOS, Windows, Linux', license: 'https://github.com/Createitv/agc-cli/blob/main/LICENSE', downloadUrl: 'https://github.com/Createitv/agc-cli/releases', isAccessibleForFree: true, softwareRequirements: 'Node.js 18+ for NPM installation, or a supported native package manager', featureList: ['AppGallery Connect API discovery', 'Credential profiles', 'Dry-run request previews', 'Stable JSON output', 'Task-oriented Agent Skills'], sameAs: ['https://github.com/Createitv/agc-cli', 'https://www.npmjs.com/package/@createitv/agc-cli'], author: { '@id': 'https://github.com/Createitv#organization' }, offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' } }, { '@type': 'SoftwareSourceCode', name: 'agc-cli', codeRepository: 'https://github.com/Createitv/agc-cli', programmingLanguage: 'Go', author: { '@type': 'Person', name: 'Createitv', url: 'https://github.com/Createitv' } }, { '@type': 'FAQPage', '@id': `${meta.url}#faq`, inLanguage: language === 'zh' ? 'zh-CN' : 'en', mainEntity: c.faqs.map(({q,a}) => ({ '@type': 'Question', name: q, acceptedAnswer: { '@type': 'Answer', text: a } })) }, ] }; diff --git a/apps/web/src/styles.css b/apps/web/src/styles.css index 65a6658..7229b10 100644 --- a/apps/web/src/styles.css +++ b/apps/web/src/styles.css @@ -484,6 +484,22 @@ main { min-height: 100vh; overflow: hidden; } .projectSources, .contentUpdated { color: var(--muted); font-size: 12px; line-height: 1.8; } .projectSources a { color: var(--paper); text-decoration: underline; } .projectAnswers h3 { margin: 36px 0 20px; font-size: 23px; } +.agentDocs { + margin: 42px 0 56px; + padding: 30px; + border: 1px solid rgba(101, 213, 218, 0.2); + border-radius: 14px; + background: linear-gradient(135deg, rgba(101, 213, 218, 0.07), rgba(240, 68, 68, 0.035)); +} +.agentDocsIntro { max-width: 780px; } +.agentDocsIntro h3 { margin: 8px 0 12px; } +.agentDocsIntro > p:last-child { color: var(--muted); line-height: 1.7; } +.agentDocsGrid { margin-top: 24px; display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; } +.agentDocsGrid a { min-height: 148px; padding: 20px; display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 10px; background: rgba(8, 8, 9, 0.56); transition: border-color 180ms ease, transform 180ms ease; } +.agentDocsGrid a:hover { border-color: rgba(101, 213, 218, 0.45); transform: translateY(-2px); } +.agentDocsGrid span { font-weight: 700; } +.agentDocsGrid p { margin: 10px 0 18px; color: var(--muted); font-size: 13px; line-height: 1.6; } +.agentDocsGrid code { margin-top: auto; color: var(--cyan); font-size: 10px; overflow-wrap: anywhere; } .projectFaq details { border-top: 1px solid var(--line); padding: 19px 0; } .projectFaq summary { cursor: pointer; font-size: 16px; line-height: 1.6; } .projectFaq p { max-width: 900px; color: var(--muted); font-size: 14px; line-height: 1.85; } @@ -704,6 +720,8 @@ footer { max-width: var(--max); min-height: 160px; margin: 0 auto; padding: 38px .detailHeader { flex-direction: column; } .commandTable > div { grid-template-columns: 78px 1fr; } .detailFooter { align-items: flex-start; flex-direction: column; } + .agentDocs { padding: 22px; } + .agentDocsGrid { grid-template-columns: 1fr; } .quickStep { grid-template-columns: 38px 1fr; gap: 14px; } .consoleMap > div { grid-template-columns: 44px 1fr; padding: 14px; } .consoleMap small { grid-column: 2; }