1
0

docs.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /**
  2. * Canonical publication manifest for the documentation website.
  3. *
  4. * Markdown stays in its owning repository tier. This manifest maps each
  5. * canonical source into matching route trees for both site locales; when a
  6. * translation is absent, both routes intentionally project the available
  7. * source instead of copying Markdown.
  8. */
  9. /** Locale key used by the VitePress site. */
  10. export type DocsLocale = 'root' | 'en'
  11. /** Sidebar collection rendered for one locale and top-level module. */
  12. type DocsSidebar =
  13. | 'zh-guide'
  14. | 'zh-develop'
  15. | 'zh-reference'
  16. | 'en-guide'
  17. | 'en-develop'
  18. | 'en-reference'
  19. /** A page projected into the VitePress source tree. */
  20. export interface DocsPage {
  21. /** VitePress locale whose route tree owns this projection. */
  22. locale: DocsLocale
  23. /** Language of the canonical source currently projected at this route. */
  24. contentLocale: 'zh-CN' | 'en-US'
  25. /** Repository-relative canonical Markdown source. */
  26. source: string
  27. /** VitePress route, including the `.md` suffix. */
  28. route: string
  29. /** Navigation label shown in the sidebar. */
  30. label: string
  31. /** Sidebar collection that owns the page, or null for a locale home page. */
  32. sidebar: DocsSidebar | null
  33. /** Section label within the sidebar. */
  34. section: string
  35. /** Stable order within the section. */
  36. order: number
  37. /** Heading levels included in this page's VitePress outline. */
  38. outline?: number | readonly [number, number] | 'deep' | false
  39. /** Additional repository paths that resolve to this page. */
  40. sourceAliases?: string[]
  41. }
  42. interface MirroredPage {
  43. source: string | Record<DocsLocale, string>
  44. route: string
  45. contentLocale: DocsPage['contentLocale'] | Record<DocsLocale, DocsPage['contentLocale']>
  46. label: Record<DocsLocale, string>
  47. sidebar: Record<DocsLocale, DocsSidebar | null>
  48. section: Record<DocsLocale, string>
  49. order: number
  50. outline?: DocsPage['outline']
  51. sourceAliases?: string[] | Partial<Record<DocsLocale, string[]>>
  52. }
  53. type PairedPage = Omit<MirroredPage, 'source' | 'contentLocale' | 'sourceAliases'> & {
  54. /** English side of a sibling `foo.md` / `foo.zh.md` pair. */
  55. source: string
  56. /** Language-neutral repository aliases, such as the directory of an index page. */
  57. sourceAliases?: string[]
  58. }
  59. function localized<T>(value: T | Record<DocsLocale, T>, locale: DocsLocale): T {
  60. return typeof value === 'object' && value !== null && !Array.isArray(value)
  61. ? (value as Record<DocsLocale, T>)[locale]
  62. : value
  63. }
  64. function mirroredPages(pages: MirroredPage[]): DocsPage[] {
  65. return pages.flatMap(page => (['root', 'en'] as const).map((locale) => {
  66. const aliases = page.sourceAliases === undefined
  67. ? undefined
  68. : Array.isArray(page.sourceAliases) ? page.sourceAliases : page.sourceAliases[locale]
  69. return {
  70. locale,
  71. contentLocale: localized(page.contentLocale, locale),
  72. source: localized(page.source, locale),
  73. route: locale === 'root' ? page.route : `en/${page.route}`,
  74. label: page.label[locale],
  75. sidebar: page.sidebar[locale],
  76. section: page.section[locale],
  77. order: page.order,
  78. ...(page.outline === undefined ? {} : { outline: page.outline }),
  79. ...(aliases === undefined ? {} : { sourceAliases: aliases }),
  80. }
  81. }))
  82. }
  83. function pairedPages(pages: PairedPage[]): DocsPage[] {
  84. return mirroredPages(pages.map((page) => {
  85. const chineseSource = page.source.replace(/\.md$/, '.zh.md')
  86. const sharedAliases = page.sourceAliases ?? []
  87. return {
  88. ...page,
  89. source: { root: chineseSource, en: page.source },
  90. contentLocale: { root: 'zh-CN', en: 'en-US' },
  91. sourceAliases: {
  92. root: [...sharedAliases, page.source],
  93. en: [...sharedAliases, chineseSource],
  94. },
  95. }
  96. }))
  97. }
  98. const homeAndGuide = pairedPages([
  99. {
  100. source: 'docs/user/index.md',
  101. route: 'index.md',
  102. label: { root: 'DeepSeek Harness', en: 'DeepSeek Harness' },
  103. sidebar: { root: null, en: null },
  104. section: { root: '首页', en: 'Home' },
  105. order: 0,
  106. },
  107. {
  108. source: 'docs/user/guide/index.md',
  109. route: 'guide/index.md',
  110. label: { root: '介绍', en: 'Introduction' },
  111. sidebar: { root: 'zh-guide', en: 'en-guide' },
  112. section: { root: '入门', en: 'Guide' },
  113. order: 1,
  114. sourceAliases: ['docs/user/guide'],
  115. },
  116. {
  117. source: 'docs/user/guide/quickstart.md',
  118. route: 'guide/quickstart.md',
  119. label: { root: '快速开始', en: 'Quick start' },
  120. sidebar: { root: 'zh-guide', en: 'en-guide' },
  121. section: { root: '入门', en: 'Guide' },
  122. order: 2,
  123. },
  124. {
  125. source: 'docs/user/guide/providers.md',
  126. route: 'guide/providers.md',
  127. label: { root: '配置模型', en: 'Configure models' },
  128. sidebar: { root: 'zh-guide', en: 'en-guide' },
  129. section: { root: '入门', en: 'Guide' },
  130. order: 3,
  131. },
  132. {
  133. source: 'docs/user/guide/config.md',
  134. route: 'guide/config.md',
  135. label: { root: '配置文件', en: 'Configuration' },
  136. sidebar: { root: 'zh-guide', en: 'en-guide' },
  137. section: { root: '入门', en: 'Guide' },
  138. order: 4,
  139. },
  140. ])
  141. const develop = pairedPages([
  142. {
  143. source: 'docs/user/develop/basic/index.md',
  144. route: 'develop/basic/index.md',
  145. label: { root: '第一个插件', en: 'First plugin' },
  146. sidebar: { root: 'zh-develop', en: 'en-develop' },
  147. section: { root: '基础', en: 'Basics' },
  148. order: 1,
  149. sourceAliases: ['docs/user/develop/basic'],
  150. },
  151. {
  152. source: 'docs/user/develop/basic/tool.md',
  153. route: 'develop/basic/tool.md',
  154. label: { root: '开发一个 Tool', en: 'Build a tool' },
  155. sidebar: { root: 'zh-develop', en: 'en-develop' },
  156. section: { root: '基础', en: 'Basics' },
  157. order: 2,
  158. },
  159. {
  160. source: 'docs/user/develop/basic/config.md',
  161. route: 'develop/basic/config.md',
  162. label: { root: '插件配置', en: 'Plugin configuration' },
  163. sidebar: { root: 'zh-develop', en: 'en-develop' },
  164. section: { root: '基础', en: 'Basics' },
  165. order: 3,
  166. },
  167. {
  168. source: 'docs/user/develop/basic/publish.md',
  169. route: 'develop/basic/publish.md',
  170. label: { root: '打包与安装插件', en: 'Package and install' },
  171. sidebar: { root: 'zh-develop', en: 'en-develop' },
  172. section: { root: '基础', en: 'Basics' },
  173. order: 4,
  174. },
  175. {
  176. source: 'docs/user/develop/framework/index.md',
  177. route: 'develop/framework/index.md',
  178. label: { root: '插件与生命周期', en: 'Plugin lifecycle' },
  179. sidebar: { root: 'zh-develop', en: 'en-develop' },
  180. section: { root: '框架能力', en: 'Framework' },
  181. order: 1,
  182. sourceAliases: ['docs/user/develop/framework'],
  183. },
  184. {
  185. source: 'docs/user/develop/framework/service.md',
  186. route: 'develop/framework/service.md',
  187. label: { root: '服务与依赖', en: 'Services and dependencies' },
  188. sidebar: { root: 'zh-develop', en: 'en-develop' },
  189. section: { root: '框架能力', en: 'Framework' },
  190. order: 2,
  191. },
  192. {
  193. source: 'docs/user/develop/framework/events.md',
  194. route: 'develop/framework/events.md',
  195. label: { root: '事件系统', en: 'Event system' },
  196. sidebar: { root: 'zh-develop', en: 'en-develop' },
  197. section: { root: '框架能力', en: 'Framework' },
  198. order: 3,
  199. },
  200. {
  201. source: 'docs/user/develop/practice/index.md',
  202. route: 'develop/practice/index.md',
  203. label: { root: '能力的三层拆分', en: 'Capability layering' },
  204. sidebar: { root: 'zh-develop', en: 'en-develop' },
  205. section: { root: '实战', en: 'Practice' },
  206. order: 1,
  207. sourceAliases: ['docs/user/develop/practice'],
  208. },
  209. {
  210. source: 'docs/user/develop/practice/llm-adapter.md',
  211. route: 'develop/practice/llm-adapter.md',
  212. label: { root: 'LLM 适配器', en: 'LLM adapter' },
  213. sidebar: { root: 'zh-develop', en: 'en-develop' },
  214. section: { root: '实战', en: 'Practice' },
  215. order: 2,
  216. },
  217. ])
  218. const cordisTutorial = mirroredPages(([
  219. ['index.md', 'Cordis 教程', 'Cordis tutorial'],
  220. ['01-first-plugin.md', '1. 第一个插件', '1. Your first plugin'],
  221. ['02-lifecycle-and-effects.md', '2. 生命周期与副作用', '2. Lifecycle and effects'],
  222. ['03-services.md', '3. 服务', '3. Services'],
  223. ['04-events.md', '4. 事件', '4. Events'],
  224. ['05-config.md', '5. 配置', '5. Configuration'],
  225. ['06-composition-and-hmr.md', '6. 组合与热重载', '6. Composition and HMR'],
  226. ['07-into-the-harness.md', '7. 进入 Harness', '7. Into the harness'],
  227. ] as const).map(([file, rootLabel, enLabel], order): MirroredPage => ({
  228. source: `docs/cordis-tutorial/${file}`,
  229. route: `develop/cordis-tutorial/${file}`,
  230. contentLocale: 'en-US',
  231. label: { root: rootLabel, en: enLabel },
  232. sidebar: { root: 'zh-develop', en: 'en-develop' },
  233. section: { root: 'Cordis 教程', en: 'Cordis tutorial' },
  234. order,
  235. ...(file === 'index.md' ? { sourceAliases: ['docs/cordis-tutorial'] } : {}),
  236. })))
  237. const cordisPrimerReference = pairedPages([
  238. {
  239. source: 'docs/cordis-primer.md',
  240. route: 'reference/cordis-primer.md',
  241. label: { root: 'Cordis 入门', en: 'Cordis primer' },
  242. sidebar: { root: 'zh-reference', en: 'en-reference' },
  243. section: { root: '概念', en: 'Concepts' },
  244. order: 1,
  245. },
  246. ])
  247. const coreDataReference = pairedPages(([
  248. ['core.md', '核心数据结构', 'Core data structures', 0],
  249. ['scope.md', '作用域', 'Scopes', 1],
  250. ['session.md', '会话', 'Sessions', 2],
  251. ['system-prompt.md', '系统提示词', 'System prompts', 4],
  252. ['tools.md', '工具', 'Tools', 5],
  253. ['llm-streaming.md', 'LLM 流式响应', 'LLM streaming', 6],
  254. ['bash.md', 'Bash 执行', 'Bash execution', 7],
  255. ['filesystem.md', '文件系统', 'Filesystem', 9],
  256. ['code-runtime.md', '代码运行时', 'Code runtime', 10],
  257. ['compaction.md', '上下文压缩', 'Compaction', 11],
  258. ['subagent.md', '子代理', 'Subagents', 12],
  259. ['workflow.md', '工作流', 'Workflows', 13],
  260. ['skills.md', '技能', 'Skills', 14],
  261. ['approval.md', '审批', 'Approvals', 15],
  262. ['user-interaction.md', '用户交互', 'User interaction', 16],
  263. ['sandbox.md', '沙箱', 'Sandboxing', 18],
  264. ['web.md', 'Web 访问', 'Web access', 19],
  265. ['persistence.md', '会话持久化', 'Session persistence', 20],
  266. ['settings.md', '用户设置', 'User settings', 21],
  267. ['credentials.md', '用户凭据', 'User credentials', 22],
  268. ] as const).map(([file, rootLabel, enLabel, order]): PairedPage => ({
  269. source: `docs/core-data-structures/${file}`,
  270. route: `reference/core-data-structures/${file}`,
  271. label: { root: rootLabel, en: enLabel },
  272. sidebar: { root: 'zh-reference', en: 'en-reference' },
  273. section: { root: '数据结构', en: 'Data structures' },
  274. order,
  275. ...(file === 'core.md' ? { sourceAliases: ['docs/core-data-structures'] } : {}),
  276. })))
  277. const reference = mirroredPages([
  278. ...([
  279. ['docs/architecture.md', 'reference/index.md', '架构', 'Architecture', 0],
  280. ['docs/capability-seams.md', 'reference/capability-seams.md', '能力服务', 'Capability services', 2],
  281. ['docs/agent-lifecycle.md', 'reference/agent-lifecycle.md', 'Agent 生命周期', 'Agent lifecycle', 3],
  282. ['docs/tool-execution-pipeline.md', 'reference/tool-execution-pipeline.md', 'Tool 执行', 'Tool execution', 4],
  283. ] as const).map(([source, route, rootLabel, enLabel, order]): MirroredPage => ({
  284. source,
  285. route,
  286. contentLocale: 'en-US',
  287. label: { root: rootLabel, en: enLabel },
  288. sidebar: { root: 'zh-reference', en: 'en-reference' },
  289. section: { root: '概念', en: 'Concepts' },
  290. order,
  291. })),
  292. ...([
  293. ['docs/config-catalog.md', 'reference/config-catalog.md', '插件配置', 'Plugin configuration'],
  294. ['docs/tool-catalog.md', 'reference/tool-catalog.md', 'Tool Schema', 'Tool schemas'],
  295. ['docs/cordis-catalog/services.md', 'reference/cordis-catalog/services.md', '服务', 'Services'],
  296. ['docs/cordis-catalog/events.md', 'reference/cordis-catalog/events.md', '事件', 'Events'],
  297. ['docs/persistence-catalog.md', 'reference/persistence-catalog.md', '持久化事件', 'Persistence events', 'deep'],
  298. ] as const).map(([source, route, rootLabel, enLabel, outline], order): MirroredPage => ({
  299. source,
  300. route,
  301. contentLocale: 'en-US',
  302. label: { root: rootLabel, en: enLabel },
  303. sidebar: { root: 'zh-reference', en: 'en-reference' },
  304. section: { root: '生成参考', en: 'Generated reference' },
  305. order,
  306. ...(outline === undefined ? {} : { outline }),
  307. })),
  308. ...([
  309. ['context.md', 'Context', 'Context'],
  310. ['events.md', 'Events', 'Events'],
  311. ['fiber.md', 'Fiber', 'Fiber'],
  312. ['registry.md', 'Plugin Registry', 'Plugin Registry'],
  313. ['service.md', 'Service', 'Service'],
  314. ] as const).map(([file, rootLabel, enLabel], order): MirroredPage => ({
  315. source: `docs/cordis-catalog/core/${file}`,
  316. route: `reference/cordis-api/${file}`,
  317. contentLocale: 'en-US',
  318. label: { root: rootLabel, en: enLabel },
  319. sidebar: { root: 'zh-reference', en: 'en-reference' },
  320. section: { root: 'Cordis API', en: 'Cordis Core API' },
  321. order,
  322. })),
  323. ...([
  324. ['goal.md', '目标', 'Goals', 3],
  325. ['pty.md', 'PTY 会话', 'PTY sessions', 8],
  326. ['commands.md', '命令', 'Human commands', 17],
  327. ] as const).map(([file, rootLabel, enLabel, order]): MirroredPage => ({
  328. source: `docs/core-data-structures/${file}`,
  329. route: `reference/core-data-structures/${file}`,
  330. contentLocale: 'en-US',
  331. label: { root: rootLabel, en: enLabel },
  332. sidebar: { root: 'zh-reference', en: 'en-reference' },
  333. section: { root: '数据结构', en: 'Data structures' },
  334. order,
  335. })),
  336. ...([
  337. ['adding-a-package.md', '新增 Package', 'Adding a package'],
  338. ['adding-a-tool.md', '新增 Tool', 'Adding a tool'],
  339. ['adding-an-llm-adapter.md', '新增 LLM Adapter', 'Adding an LLM adapter'],
  340. ['extension-cookbook.md', '扩展模式', 'Extension patterns'],
  341. ] as const).map(([file, rootLabel, enLabel], order): MirroredPage => ({
  342. source: `docs/cookbook/${file}`,
  343. route: `reference/cookbook/${file}`,
  344. contentLocale: 'en-US',
  345. label: { root: rootLabel, en: enLabel },
  346. sidebar: { root: 'zh-reference', en: 'en-reference' },
  347. section: { root: '开发手册', en: 'Cookbook' },
  348. order,
  349. })),
  350. ])
  351. /** Every canonical page published by the documentation website. */
  352. export const docsPages: DocsPage[] = [
  353. ...homeAndGuide,
  354. ...develop,
  355. ...cordisTutorial,
  356. ...cordisPrimerReference,
  357. ...coreDataReference,
  358. ...reference,
  359. ]