gen-cordis-catalog.ts 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /**
  2. * Generate committed Cordis artifacts from the Typert catalog projector and
  3. * the independent vendored-core projector.
  4. */
  5. import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'
  6. import { dirname, resolve } from 'node:path'
  7. import {
  8. projectCordisCatalog,
  9. renderEvents,
  10. renderServices,
  11. } from '@deepseek-ai/dsh-typert-generator'
  12. import type { CordisCatalogPolicy } from '@deepseek-ai/dsh-typert-generator'
  13. import { renderCordisCoreApiPages } from './cordis-core-api.ts'
  14. const root = resolve(import.meta.dirname, '..')
  15. const OUT_EVENTS = 'docs/cordis-catalog/events.md'
  16. const OUT_SERVICES = 'docs/cordis-catalog/services.md'
  17. const OUT_RUNTIME_API = 'packages/cordis/tool-cordis/src/api-catalog.ts'
  18. /** One primary core-data-structures page per project type used by a generated signature. */
  19. export const LINK_MAP: Readonly<Record<string, string>> = {
  20. Agent: 'core.md',
  21. AgentCancelCause: 'core.md',
  22. AgentOptions: 'core.md',
  23. AgentStatus: 'core.md',
  24. ContentBlock: 'core.md',
  25. ContinuationDecision: 'core.md',
  26. ContinuationStop: 'core.md',
  27. GenerateOptions: 'core.md',
  28. InboxItem: 'core.md',
  29. InboxPlacement: 'core.md',
  30. MessageId: 'core.md',
  31. HookContext: 'core.md',
  32. SettleReason: 'core.md',
  33. AdapterRegistrationHandle: 'core.md',
  34. LlmCallConfig: 'core.md',
  35. LlmModelContext: 'core.md',
  36. LlmModelReasoningInfo: 'core.md',
  37. LlmResolvedModelInfo: 'core.md',
  38. LlmFailure: 'llm-streaming.md',
  39. LlmModelInfo: 'core.md',
  40. LlmProviderInfo: 'core.md',
  41. LlmConfigurableProvider: 'core.md',
  42. ResolvedRetryPolicy: 'llm-streaming.md',
  43. Message: 'core.md',
  44. MessageSource: 'core.md',
  45. UserMessage: 'session.md',
  46. PromptDecision: 'core.md',
  47. RequestError: 'core.md',
  48. RequestErrorAction: 'core.md',
  49. PreparedReferencedMessage: 'session-reference.md',
  50. SessionReferenceCandidate: 'session-reference.md',
  51. SessionReferenceInput: 'session-reference.md',
  52. SessionEvent: 'core.md',
  53. SessionId: 'core.md',
  54. SessionStartSource: 'core.md',
  55. SessionLogSnapshot: 'session-query.md',
  56. SessionSurfaceSnapshot: 'session-query.md',
  57. ApprovalOutcome: 'approval.md',
  58. ApprovalPolicy: 'approval.md',
  59. ApprovalRequest: 'approval.md',
  60. ApprovalService: 'approval.md',
  61. BashExecRequest: 'bash.md',
  62. BashExecSpec: 'bash.md',
  63. BashProcess: 'bash.md',
  64. BashRunResult: 'bash.md',
  65. DshEnvironment: 'subprocess.md',
  66. SubprocessHandle: 'subprocess.md',
  67. SubprocessOutcome: 'subprocess.md',
  68. SubprocessOutputRead: 'subprocess.md',
  69. SubprocessOutputReader: 'subprocess.md',
  70. SubprocessSpawnSpec: 'subprocess.md',
  71. CodeRunRequest: 'code-runtime.md',
  72. CodeRunResult: 'code-runtime.md',
  73. CompactionResult: 'compaction.md',
  74. CompactionTrigger: 'compaction.md',
  75. PruneResult: 'compaction.md',
  76. FileReadOutcome: 'filesystem.md',
  77. FsDirEntry: 'filesystem.md',
  78. FsEditOutcome: 'filesystem.md',
  79. FsEditRequest: 'filesystem.md',
  80. FsInfo: 'filesystem.md',
  81. FsPathInfo: 'filesystem.md',
  82. FsPolicyExec: 'filesystem.md',
  83. FsTarget: 'filesystem.md',
  84. FsVersion: 'filesystem.md',
  85. FsWriteIntent: 'filesystem.md',
  86. FsWriteOutcome: 'filesystem.md',
  87. CreateGoalRequest: 'goal.md',
  88. EditGoalRequest: 'goal.md',
  89. GoalBlockReason: 'goal.md',
  90. GoalChanged: 'goal.md',
  91. GoalRef: 'goal.md',
  92. GoalView: 'goal.md',
  93. CommandDefinition: 'commands.md',
  94. CommandDescriptor: 'commands.md',
  95. CommandResult: 'commands.md',
  96. CommandSurface: 'commands.md',
  97. LlmAdapter: 'llm-streaming.md',
  98. PreparedLlmCall: 'llm-streaming.md',
  99. LlmService: 'llm-streaming.md',
  100. StreamChunk: 'llm-streaming.md',
  101. SkillProviderControl: 'skills.md',
  102. CreateSessionOptions: 'persistence.md',
  103. SessionHeader: 'persistence.md',
  104. SessionLocation: 'persistence.md',
  105. SessionPersistenceSnapshot: 'persistence.md',
  106. ConfinedArgv: 'sandbox.md',
  107. SandboxExecutionPolicy: 'sandbox.md',
  108. SandboxMode: 'sandbox.md',
  109. SandboxPolicy: 'sandbox.md',
  110. PtyBackend: 'pty.md',
  111. PtyReadRequest: 'pty.md',
  112. PtyReadResult: 'pty.md',
  113. PtySendOperation: 'pty.md',
  114. PtySendRequest: 'pty.md',
  115. PtySessionId: 'pty.md',
  116. PtySessionSnapshot: 'pty.md',
  117. PtySignal: 'pty.md',
  118. PtySignalResult: 'pty.md',
  119. PtySpawnRequest: 'pty.md',
  120. PtySpawnResult: 'pty.md',
  121. SandboxPolicyRequest: 'sandbox.md',
  122. ScopeKey: 'scope.md',
  123. Scoped: 'scope.md',
  124. EpochHeader: 'session.md',
  125. Session: 'session.md',
  126. SessionEventMap: 'session.md',
  127. TurnEndReason: 'session.md',
  128. TurnTrigger: 'session.md',
  129. SessionEventReadRequest: 'session-query.md',
  130. SessionEventRecord: 'session-query.md',
  131. SessionEventResultFilter: 'session-query.md',
  132. SessionEventSearchDocument: 'session-query.md',
  133. SessionEventSearchHit: 'session-query.md',
  134. SessionEventSearchPage: 'session-query.md',
  135. SessionEventSearchRequest: 'session-query.md',
  136. SessionEventTrace: 'session-query.md',
  137. SessionEventTraceObservation: 'session-query.md',
  138. SessionEventTraceRequest: 'session-query.md',
  139. SessionEventWindow: 'session-query.md',
  140. SessionLineageTrace: 'session-query.md',
  141. SessionRecord: 'session-query.md',
  142. SessionResultFilter: 'session-query.md',
  143. SessionSearchExecContext: 'session-query.md',
  144. SessionSearchHit: 'session-query.md',
  145. SessionSearchPage: 'session-query.md',
  146. SessionSearchRequest: 'session-query.md',
  147. SessionTitleObservation: 'session-query.md',
  148. SessionTitleObservationResult: 'session-query.md',
  149. SessionTitleProvider: 'session-title.md',
  150. SessionTitleSnapshot: 'session-title.md',
  151. SkillCatalogSnapshot: 'skills.md',
  152. SkillDefinition: 'skills.md',
  153. SkillLookupOptions: 'skills.md',
  154. SkillProvider: 'skills.md',
  155. SkillProviderObservation: 'skills.md',
  156. SkillRegistration: 'skills.md',
  157. SkillSummary: 'skills.md',
  158. SaveTextSpill: 'spill.md',
  159. SpillRef: 'spill.md',
  160. ContinuableCreateRequest: 'subagent.md',
  161. ContinuableCreateSpec: 'subagent.md',
  162. ContinuableSetupContribution: 'subagent.md',
  163. ContinuableStart: 'subagent.md',
  164. ContinuableStartSpec: 'subagent.md',
  165. CoordinatorMessageSource: 'subagent.md',
  166. SubagentFollowupOptions: 'subagent.md',
  167. SubagentListEntry: 'subagent.md',
  168. SubagentProvider: 'subagent.md',
  169. SubagentReportDelivery: 'subagent.md',
  170. SubagentReportMessageSource: 'subagent.md',
  171. SubagentReportOptions: 'subagent.md',
  172. SubagentRun: 'subagent.md',
  173. SubagentService: 'subagent.md',
  174. SubagentStartRequest: 'subagent.md',
  175. AssembleContext: 'system-prompt.md',
  176. PromptContext: 'system-prompt.md',
  177. PromptSection: 'system-prompt.md',
  178. SystemPrompt: 'system-prompt.md',
  179. ToolProviderResult: 'system-prompt.md',
  180. TaskDoneListener: 'tasks.md',
  181. TaskId: 'tasks.md',
  182. TaskRead: 'tasks.md',
  183. TaskSnapshot: 'tasks.md',
  184. TaskStart: 'tasks.md',
  185. TokenMeasurement: 'token-meter.md',
  186. CodeDispatchLog: 'tools.md',
  187. PostToolDecision: 'tools.md',
  188. PreToolDecision: 'tools.md',
  189. ToolDefinition: 'tools.md',
  190. ToolExecution: 'tools.md',
  191. ToolDispatchExecution: 'tools.md',
  192. ToolExecutionInput: 'tools.md',
  193. ToolExecutionMode: 'tools.md',
  194. ToolExecutionResult: 'tools.md',
  195. ToolExecutionToken: 'tools.md',
  196. ToolGuard: 'tools.md',
  197. ToolRegistry: 'tools.md',
  198. ToolRestriction: 'tools.md',
  199. ToolSchema: 'tools.md',
  200. SettingsNamespace: 'settings.md',
  201. SettingsRegisterOptions: 'settings.md',
  202. SettingsScope: 'settings.md',
  203. SettingsDescriptor: 'settings.md',
  204. SettingsPathOp: 'settings.md',
  205. SettingsDescribeOptions: 'settings.md',
  206. SettingsUpdateSource: 'settings.md',
  207. CredentialRef: 'credentials.md',
  208. CredentialInfo: 'credentials.md',
  209. ResolvedCredential: 'credentials.md',
  210. AskUserQuestionAnswer: 'user-interaction.md',
  211. AskUserQuestionRequest: 'user-interaction.md',
  212. UserInteractionProvider: 'user-interaction.md',
  213. WebFetchProvider: 'web.md',
  214. WebFetchRequest: 'web.md',
  215. WebFetchResult: 'web.md',
  216. WebSearchProvider: 'web.md',
  217. WebSearchRequest: 'web.md',
  218. WebSearchResult: 'web.md',
  219. WorkflowRun: 'workflow.md',
  220. WorkflowRunInfo: 'workflow.md',
  221. WorkflowStartRequest: 'workflow.md',
  222. }
  223. /** TypeScript lib and pinned framework types with no repository-owned data page. */
  224. export const FOUNDATION_TYPE_NAMES: ReadonlySet<string> = new Set([
  225. 'AbortSignal',
  226. 'AsyncIterable',
  227. 'Context',
  228. 'Error',
  229. 'Map',
  230. 'Partial',
  231. 'Pick',
  232. 'Promise',
  233. 'Readonly',
  234. ])
  235. /** Project types deliberately documented outside the core-data catalog. */
  236. export const TYPE_LINK_EXEMPTIONS: Readonly<Record<string, string>> = {
  237. AgentFactory: 'agent creation seam is owned by packages/core/agent/README.md',
  238. z: 'schemastery schema constructor is owned by vendor/schemastery (vendored upstream)',
  239. BeginCommandRequest: 'event-local request contract is owned by packages/client/ui-slash/src/types.ts',
  240. InsertReferenceRequest: 'event-local request contract is owned by packages/client/ui-slash/src/types.ts',
  241. ConsumeTokenRequest: 'event-local request contract is owned by packages/client/ui-slash/src/types.ts',
  242. InsertTextRequest: 'event-local request contract is owned by packages/client/ui-slash/src/types.ts',
  243. AgentHandle: 'agent ownership handle is owned by packages/core/agent/README.md',
  244. BashEnvContributor: 'service-local extension type is owned by packages/bash/tool-bash/src/index.ts',
  245. BashEnvVariableInfo: 'service-local metadata type is owned by packages/bash/tool-bash/src/index.ts',
  246. CompactAgentContext: 'compaction service input is owned by packages/compact/compact/src/index.ts',
  247. ManualCompactAgentContext: 'manual compaction service input is owned by packages/compact/compact/src/index.ts',
  248. DirectoryPickerCapability: 'picker interaction contract is owned by packages/host/directory-picker/README.md',
  249. CreateAgentOptions: 'agent creation contract is owned by packages/core/agent/README.md',
  250. Domain: 'domain interface is owned by packages/storage/storage-domain/README.md',
  251. DomainChanged: 'event-local snapshot is owned by packages/storage/storage-domain/src/events.ts',
  252. DomainFacility: 'domain form facility is owned by packages/storage/storage-domain/README.md',
  253. DomainImpl: 'domain implementation contract is owned by packages/storage/storage-domain/README.md',
  254. DomainSpec: 'domain declaration contract is owned by packages/storage/storage-domain/README.md',
  255. StorageBackend: 'backend contract is owned by packages/storage/storage/src/backend.ts',
  256. StorageForms: 'merge-extensible form map is owned by packages/storage/storage/src/index.ts',
  257. ProjectionDefinition: 'projection unit contract is owned by packages/session-projection/session-projection/README.md',
  258. SessionProjectionMap: 'merge-extensible projection key map is owned by packages/session-projection/session-projection/src/types.ts',
  259. ProjectionChangeListener: 'change-feed listener contract is owned by packages/session-projection/session-projection/src/index.ts',
  260. ProjectionSnapshot: 'watermark snapshot shape is owned by packages/session-projection/session-projection/src/index.ts',
  261. ProjectionCheckpoint: 'persisted checkpoint row map is owned by packages/session-projection/session-projection/src/index.ts',
  262. CommandExecution: 'executor return contract is owned by packages/ui/commands/src/index.ts',
  263. TypertContribution: 'registry contribution contract is owned by packages/typert/registry/README.md',
  264. TypertFace: 'registry face identity is owned by packages/typert/registry/README.md',
  265. TypertPackageFilter: 'registry package query filter is owned by packages/typert/registry/README.md',
  266. TypertPackageRecord: 'registry package record is owned by packages/typert/registry/README.md',
  267. TypertSchemaFilter: 'registry schema query filter is owned by packages/typert/registry/README.md',
  268. TypertSchemaRecord: 'registry schema record is owned by packages/typert/registry/README.md',
  269. 'z.core.JSONSchema.BaseSchema': 'zod projection output is owned by the zod v4 API',
  270. 'z.core.ToJSONSchemaParams': 'zod projection parameters are owned by the zod v4 API',
  271. InvariantInstaller: 'service-local contribution contract is owned by packages/support/invariants/README.md',
  272. LocaleDict: 'service-local dictionary shape is owned by packages/client/i18n/src/index.ts',
  273. WebBootGraph: 'web boot graph wire shape is owned by packages/client/modules/src/client/index.ts',
  274. WebRoute: 'route registration contract is owned by packages/host/webserver/src/index.ts',
  275. WebUpgradeRoute:
  276. 'upgrade route registration contract is owned by packages/host/webserver/src/index.ts',
  277. ThemeTokens: 'service-local token dictionary is owned by packages/client/ui-theme/src/index.ts',
  278. Translate: 'service-local bound translator is owned by packages/client/i18n/src/index.ts',
  279. InvariantRegistration: 'service-local lifecycle handle is owned by packages/support/invariants/README.md',
  280. PresetOption: 'deployment menu metadata is owned by packages/ui/permission/README.md',
  281. PresetSpec: 'deployment preset composition is owned by packages/ui/permission/README.md',
  282. KnobState: 'projection unit state shape is owned by packages/ui/permission/README.md',
  283. PermissionSelect: 'permissions projection payload is owned by packages/ui/permission/src/types.ts',
  284. PromptAssembly: 'assembly result is owned by packages/core/system-prompt/README.md',
  285. ResumeAgentOptions: 'agent resume contract is owned by packages/core/agent/README.md',
  286. SessionForkSource: 'service-local fork input is owned by packages/core/session/src/index.ts',
  287. SubagentRunEndInfo: 'event payload contract is owned by packages/subagent/subagent/src/types.ts',
  288. SubagentRunInfo: 'event payload contract is owned by packages/subagent/subagent/src/types.ts',
  289. TelemetryRecord: 'seam-local record contract is owned by packages/telemetry/session-telemetry/src/index.ts',
  290. WorkflowAgentEndInfo: 'event-local snapshot is owned by packages/workflow/workflow/src/index.ts',
  291. WorkflowAgentInfo: 'event-local snapshot is owned by packages/workflow/workflow/src/index.ts',
  292. WorkflowResultInfo: 'event-local snapshot is owned by packages/workflow/workflow/src/index.ts',
  293. Workspace: 'workspace entity contract is owned by packages/workspace/workspace/README.md',
  294. WorkspaceId: 'branded id is owned by packages/workspace/workspace/README.md',
  295. }
  296. /** Repository data policy consumed by the Cordis catalog projector. */
  297. export const CORDIS_CATALOG_POLICY: CordisCatalogPolicy = {
  298. linkedTypePages: LINK_MAP,
  299. foundationTypeNames: FOUNDATION_TYPE_NAMES,
  300. typeLinkExemptions: TYPE_LINK_EXEMPTIONS,
  301. inheritedEvents: [
  302. { name: 'internal/plugin', summary: 'A plugin fiber was created.', source: 'vendor/cordis/src/events.ts:328' },
  303. { name: 'internal/status', summary: 'A fiber changed lifecycle state.', source: 'vendor/cordis/src/events.ts:330' },
  304. { name: 'internal/service', summary: 'Interception hook for a service binding (no core producer).', source: 'vendor/cordis/src/events.ts:332' },
  305. { name: 'internal/update', summary: 'Waterfall: a fiber config update is being applied.', source: 'vendor/cordis/src/events.ts:334' },
  306. { name: 'internal/get', summary: 'Waterfall: a service is being read from the store.', source: 'vendor/cordis/src/events.ts:336' },
  307. { name: 'internal/set', summary: 'Waterfall: a service is being written to the store.', source: 'vendor/cordis/src/events.ts:338' },
  308. { name: 'internal/listener', summary: 'A listener was registered.', source: 'vendor/cordis/src/events.ts:340' },
  309. { name: 'internal/dispatch', summary: 'An event is being dispatched to listeners.', source: 'vendor/cordis/src/events.ts:342' },
  310. { name: 'hmr/change', summary: 'A watched source file changed on disk.', source: 'vendor/hmr/src/index.ts:20' },
  311. { name: 'hmr/reload', summary: 'Plugins are being reloaded after a change.', source: 'vendor/hmr/src/index.ts:22' },
  312. { name: 'hmr/config-update-failed', summary: 'A watched config-file refresh failed.', source: 'vendor/hmr/src/index.ts:29' },
  313. { name: 'exit', summary: 'The process is exiting on a signal.', source: 'vendor/loader/src/index.ts:23' },
  314. { name: 'loader/config-update', summary: 'The loader config tree changed.', source: 'vendor/loader/src/index.ts:24' },
  315. { name: 'loader/entry-init', summary: 'A config entry is being initialized.', source: 'vendor/loader/src/index.ts:25' },
  316. { name: 'loader/partial-dispose', summary: 'An entry is being partially disposed on reload.', source: 'vendor/loader/src/index.ts:26' },
  317. { name: 'loader/patch-context', summary: 'A context is being patched during a reload.', source: 'vendor/loader/src/index.ts:27' },
  318. ],
  319. inheritedServices: [
  320. { name: 'ctx.on / ctx.once', summary: 'Register an event listener (disposable).', source: 'vendor/cordis/src/events.ts:34' },
  321. { name: 'ctx.emit / ctx.parallel / ctx.serial / ctx.bail / ctx.waterfall', summary: 'Dispatch an event (sync / awaited / first-bail / veto-chain).', source: 'vendor/cordis/src/events.ts:34' },
  322. { name: 'ctx.plugin / ctx.inject', summary: 'Load a plugin / declare required services.', source: 'vendor/cordis/src/registry.ts:164' },
  323. { name: 'ctx.effect', summary: 'Register a disposable side effect tied to the fiber.', source: 'vendor/cordis/src/fiber.ts:9' },
  324. { name: 'ctx.get / ctx.set / ctx.provide / ctx.accessor / ctx.mixin', summary: 'Low-level service-store access and binding.', source: 'vendor/cordis/src/reflect.ts:7' },
  325. { name: 'ctx.extend / ctx.isolate / ctx.intercept', summary: 'Derive a child context (scoped services / isolation / interception).', source: 'vendor/cordis/src/context.ts:42' },
  326. { name: 'ctx.root / ctx.scope / ctx.fiber / ctx.registry / ctx.reflect / ctx.events / ctx.logger', summary: 'Ambient handles onto the running context graph.', source: 'vendor/cordis/src/context.ts:16' },
  327. { name: 'ctx.timer (+ interval / timeout / throttle / debounce / setTimeout / setInterval)', summary: 'Disposable timer helpers. The `timer` key is provided at runtime; the six helpers are mixed onto ctx directly (declared via Pick).', source: 'vendor/timer/src/index.ts:4' },
  328. { name: 'ctx.loader', summary: 'The config Loader that booted the app (present under the loader).', source: 'vendor/loader/src/index.ts:30' },
  329. { name: 'ctx.hmr', summary: 'The hot-module-reload watcher (present under the hmr plugin).', source: 'vendor/hmr/src/index.ts:15' },
  330. ],
  331. }
  332. /** CLI entry: default writes every artifact; `--check` reports stale files.
  333. * @returns nothing; writes files or reports freshness through the process.
  334. */
  335. export function main(): void {
  336. const { projector, model } = projectCordisCatalog(root, CORDIS_CATALOG_POLICY)
  337. const outputs: [string, string][] = [
  338. [OUT_EVENTS, renderEvents([...model.events], CORDIS_CATALOG_POLICY)],
  339. [OUT_SERVICES, renderServices([...model.services], CORDIS_CATALOG_POLICY)],
  340. [OUT_RUNTIME_API, projector.renderRuntimeApi(model)],
  341. ...renderCordisCoreApiPages(),
  342. ]
  343. if (process.argv.includes('--check')) {
  344. const stale: string[] = []
  345. for (const [out, content] of outputs) {
  346. let committed: string | null = null
  347. try {
  348. committed = readFileSync(resolve(root, out), 'utf8')
  349. } catch {
  350. // Only ENOENT is expected; either read failure has the same remedy.
  351. committed = null
  352. }
  353. if (committed !== content) stale.push(out)
  354. }
  355. if (stale.length === 0) {
  356. console.log(`gen-cordis-catalog: ${outputs.length} generated file(s) are up to date.`)
  357. process.exit(0)
  358. }
  359. console.error(`gen-cordis-catalog: ${stale.join(' and ')} ${stale.length === 1 ? 'is' : 'are'} stale. Run \`pnpm run gen-cordis-catalog\` and commit the result.`)
  360. process.exit(1)
  361. }
  362. for (const [out, content] of outputs) {
  363. const destination = resolve(root, out)
  364. mkdirSync(dirname(destination), { recursive: true })
  365. writeFileSync(destination, content)
  366. }
  367. console.log(`gen-cordis-catalog: wrote ${outputs.length} generated file(s).`)
  368. }
  369. if (process.argv[1] && import.meta.filename === resolve(process.argv[1])) main()