1
0

docs.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  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. /** Additional repository paths that resolve to this page. */
  38. sourceAliases?: string[]
  39. }
  40. interface MirroredPage {
  41. source: string | Record<DocsLocale, string>
  42. route: string
  43. contentLocale: DocsPage['contentLocale'] | Record<DocsLocale, DocsPage['contentLocale']>
  44. label: Record<DocsLocale, string>
  45. sidebar: Record<DocsLocale, DocsSidebar | null>
  46. section: Record<DocsLocale, string>
  47. order: number
  48. sourceAliases?: string[] | Partial<Record<DocsLocale, string[]>>
  49. }
  50. type PairedPage = Omit<MirroredPage, 'source' | 'contentLocale' | 'sourceAliases'> & {
  51. /** English side of a sibling `foo.md` / `foo.zh.md` pair. */
  52. source: string
  53. /** Language-neutral repository aliases, such as the directory of an index page. */
  54. sourceAliases?: string[]
  55. }
  56. function localized<T>(value: T | Record<DocsLocale, T>, locale: DocsLocale): T {
  57. return typeof value === 'object' && value !== null && !Array.isArray(value)
  58. ? (value as Record<DocsLocale, T>)[locale]
  59. : value
  60. }
  61. function mirroredPages(pages: MirroredPage[]): DocsPage[] {
  62. return pages.flatMap(page => (['root', 'en'] as const).map((locale) => {
  63. const aliases = page.sourceAliases === undefined
  64. ? undefined
  65. : Array.isArray(page.sourceAliases) ? page.sourceAliases : page.sourceAliases[locale]
  66. return {
  67. locale,
  68. contentLocale: localized(page.contentLocale, locale),
  69. source: localized(page.source, locale),
  70. route: locale === 'root' ? page.route : `en/${page.route}`,
  71. label: page.label[locale],
  72. sidebar: page.sidebar[locale],
  73. section: page.section[locale],
  74. order: page.order,
  75. ...(aliases === undefined ? {} : { sourceAliases: aliases }),
  76. }
  77. }))
  78. }
  79. function pairedPages(pages: PairedPage[]): DocsPage[] {
  80. return mirroredPages(pages.map((page) => {
  81. const chineseSource = page.source.replace(/\.md$/, '.zh.md')
  82. const sharedAliases = page.sourceAliases ?? []
  83. return {
  84. ...page,
  85. source: { root: chineseSource, en: page.source },
  86. contentLocale: { root: 'zh-CN', en: 'en-US' },
  87. sourceAliases: {
  88. root: [...sharedAliases, page.source],
  89. en: [...sharedAliases, chineseSource],
  90. },
  91. }
  92. }))
  93. }
  94. const homeAndGuide = pairedPages([
  95. {
  96. source: 'docs/user/index.md',
  97. route: 'index.md',
  98. label: { root: 'DeepSeek Harness', en: 'DeepSeek Harness' },
  99. sidebar: { root: null, en: null },
  100. section: { root: '首页', en: 'Home' },
  101. order: 0,
  102. },
  103. {
  104. source: 'docs/user/guide/index.md',
  105. route: 'guide/index.md',
  106. label: { root: '介绍', en: 'Introduction' },
  107. sidebar: { root: 'zh-guide', en: 'en-guide' },
  108. section: { root: '入门', en: 'Guide' },
  109. order: 1,
  110. sourceAliases: ['docs/user/guide'],
  111. },
  112. {
  113. source: 'docs/user/guide/quickstart.md',
  114. route: 'guide/quickstart.md',
  115. label: { root: '快速开始', en: 'Quick start' },
  116. sidebar: { root: 'zh-guide', en: 'en-guide' },
  117. section: { root: '入门', en: 'Guide' },
  118. order: 2,
  119. },
  120. {
  121. source: 'docs/user/guide/config.md',
  122. route: 'guide/config.md',
  123. label: { root: '配置文件', en: 'Configuration' },
  124. sidebar: { root: 'zh-guide', en: 'en-guide' },
  125. section: { root: '入门', en: 'Guide' },
  126. order: 3,
  127. },
  128. ])
  129. const develop = pairedPages([
  130. {
  131. source: 'docs/user/develop/basic/index.md',
  132. route: 'develop/basic/index.md',
  133. label: { root: '第一个插件', en: 'First plugin' },
  134. sidebar: { root: 'zh-develop', en: 'en-develop' },
  135. section: { root: '基础', en: 'Basics' },
  136. order: 1,
  137. sourceAliases: ['docs/user/develop/basic'],
  138. },
  139. {
  140. source: 'docs/user/develop/basic/tool.md',
  141. route: 'develop/basic/tool.md',
  142. label: { root: '开发一个 Tool', en: 'Build a tool' },
  143. sidebar: { root: 'zh-develop', en: 'en-develop' },
  144. section: { root: '基础', en: 'Basics' },
  145. order: 2,
  146. },
  147. {
  148. source: 'docs/user/develop/basic/config.md',
  149. route: 'develop/basic/config.md',
  150. label: { root: '插件配置', en: 'Plugin configuration' },
  151. sidebar: { root: 'zh-develop', en: 'en-develop' },
  152. section: { root: '基础', en: 'Basics' },
  153. order: 3,
  154. },
  155. {
  156. source: 'docs/user/develop/framework/index.md',
  157. route: 'develop/framework/index.md',
  158. label: { root: '插件与生命周期', en: 'Plugin lifecycle' },
  159. sidebar: { root: 'zh-develop', en: 'en-develop' },
  160. section: { root: '框架能力', en: 'Framework' },
  161. order: 1,
  162. sourceAliases: ['docs/user/develop/framework'],
  163. },
  164. {
  165. source: 'docs/user/develop/framework/service.md',
  166. route: 'develop/framework/service.md',
  167. label: { root: '服务与依赖', en: 'Services and dependencies' },
  168. sidebar: { root: 'zh-develop', en: 'en-develop' },
  169. section: { root: '框架能力', en: 'Framework' },
  170. order: 2,
  171. },
  172. {
  173. source: 'docs/user/develop/framework/events.md',
  174. route: 'develop/framework/events.md',
  175. label: { root: '事件系统', en: 'Event system' },
  176. sidebar: { root: 'zh-develop', en: 'en-develop' },
  177. section: { root: '框架能力', en: 'Framework' },
  178. order: 3,
  179. },
  180. {
  181. source: 'docs/user/develop/practice/index.md',
  182. route: 'develop/practice/index.md',
  183. label: { root: '能力的三层拆分', en: 'Capability layering' },
  184. sidebar: { root: 'zh-develop', en: 'en-develop' },
  185. section: { root: '实战', en: 'Practice' },
  186. order: 1,
  187. sourceAliases: ['docs/user/develop/practice'],
  188. },
  189. {
  190. source: 'docs/user/develop/practice/llm-adapter.md',
  191. route: 'develop/practice/llm-adapter.md',
  192. label: { root: 'LLM 适配器', en: 'LLM adapter' },
  193. sidebar: { root: 'zh-develop', en: 'en-develop' },
  194. section: { root: '实战', en: 'Practice' },
  195. order: 2,
  196. },
  197. ])
  198. const reference = mirroredPages([
  199. ...([
  200. ['docs/architecture.md', 'reference/index.md', '架构', 'Architecture'],
  201. ['docs/cordis-primer.md', 'reference/cordis-primer.md', 'Cordis 入门', 'Cordis primer'],
  202. ['docs/capability-seams.md', 'reference/capability-seams.md', '能力服务', 'Capability services'],
  203. ['docs/agent-lifecycle.md', 'reference/agent-lifecycle.md', 'Agent 生命周期', 'Agent lifecycle'],
  204. ['docs/tool-execution-pipeline.md', 'reference/tool-execution-pipeline.md', 'Tool 执行', 'Tool execution'],
  205. ] as const).map(([source, route, rootLabel, enLabel], order): MirroredPage => ({
  206. source,
  207. route,
  208. contentLocale: 'en-US',
  209. label: { root: rootLabel, en: enLabel },
  210. sidebar: { root: 'zh-reference', en: 'en-reference' },
  211. section: { root: '概念', en: 'Concepts' },
  212. order,
  213. })),
  214. ...([
  215. ['docs/config-catalog.md', 'reference/config-catalog.md', '插件配置', 'Plugin configuration'],
  216. ['docs/tool-catalog.md', 'reference/tool-catalog.md', 'Tool Schema', 'Tool schemas'],
  217. ['docs/cordis-catalog/services.md', 'reference/cordis-catalog/services.md', '服务', 'Services'],
  218. ['docs/cordis-catalog/events.md', 'reference/cordis-catalog/events.md', '事件', 'Events'],
  219. ['docs/persistence-catalog.md', 'reference/persistence-catalog.md', '持久化事件', 'Persistence events'],
  220. ] as const).map(([source, route, rootLabel, enLabel], order): MirroredPage => ({
  221. source,
  222. route,
  223. contentLocale: 'en-US',
  224. label: { root: rootLabel, en: enLabel },
  225. sidebar: { root: 'zh-reference', en: 'en-reference' },
  226. section: { root: '生成参考', en: 'Generated reference' },
  227. order,
  228. })),
  229. ...([
  230. ['context.md', 'Context', 'Context'],
  231. ['events.md', 'Events', 'Events'],
  232. ['fiber.md', 'Fiber', 'Fiber'],
  233. ['registry.md', 'Plugin Registry', 'Plugin Registry'],
  234. ['service.md', 'Service', 'Service'],
  235. ] as const).map(([file, rootLabel, enLabel], order): MirroredPage => ({
  236. source: `docs/cordis-catalog/core/${file}`,
  237. route: `reference/cordis-api/${file}`,
  238. contentLocale: 'en-US',
  239. label: { root: rootLabel, en: enLabel },
  240. sidebar: { root: 'zh-reference', en: 'en-reference' },
  241. section: { root: 'Cordis API', en: 'Cordis Core API' },
  242. order,
  243. })),
  244. ...([
  245. ['core.md', '核心数据结构', 'Core data structures'],
  246. ['scope.md', '作用域', 'Scopes'],
  247. ['session.md', '会话', 'Sessions'],
  248. ['system-prompt.md', '系统提示词', 'System prompts'],
  249. ['tools.md', '工具', 'Tools'],
  250. ['llm-streaming.md', 'LLM 流式响应', 'LLM streaming'],
  251. ['bash.md', 'Bash 执行', 'Bash execution'],
  252. ['filesystem.md', '文件系统', 'Filesystem'],
  253. ['code-runtime.md', '代码运行时', 'Code runtime'],
  254. ['compaction.md', '上下文压缩', 'Compaction'],
  255. ['subagent.md', '子代理', 'Subagents'],
  256. ['workflow.md', '工作流', 'Workflows'],
  257. ['skills.md', '技能', 'Skills'],
  258. ['approval.md', '审批', 'Approvals'],
  259. ['user-interaction.md', '用户交互', 'User interaction'],
  260. ['sandbox.md', '沙箱', 'Sandboxing'],
  261. ['web.md', 'Web 访问', 'Web access'],
  262. ['persistence.md', '会话持久化', 'Session persistence'],
  263. ] as const).map(([file, rootLabel, enLabel], order): MirroredPage => ({
  264. source: `docs/core-data-structures/${file}`,
  265. route: `reference/core-data-structures/${file}`,
  266. contentLocale: 'en-US',
  267. label: { root: rootLabel, en: enLabel },
  268. sidebar: { root: 'zh-reference', en: 'en-reference' },
  269. section: { root: '数据结构', en: 'Data structures' },
  270. order,
  271. ...(file === 'core.md' ? { sourceAliases: ['docs/core-data-structures'] } : {}),
  272. })),
  273. ...([
  274. ['adding-a-package.md', '新增 Package', 'Adding a package'],
  275. ['adding-a-tool.md', '新增 Tool', 'Adding a tool'],
  276. ['adding-an-llm-adapter.md', '新增 LLM Adapter', 'Adding an LLM adapter'],
  277. ['extension-cookbook.md', '扩展模式', 'Extension patterns'],
  278. ] as const).map(([file, rootLabel, enLabel], order): MirroredPage => ({
  279. source: `docs/cookbook/${file}`,
  280. route: `reference/cookbook/${file}`,
  281. contentLocale: 'en-US',
  282. label: { root: rootLabel, en: enLabel },
  283. sidebar: { root: 'zh-reference', en: 'en-reference' },
  284. section: { root: '开发手册', en: 'Cookbook' },
  285. order,
  286. })),
  287. ])
  288. /** Every canonical page published by the documentation website. */
  289. export const docsPages: DocsPage[] = [
  290. ...homeAndGuide,
  291. ...develop,
  292. ...reference,
  293. ]