gen-cordis-catalog.ts 19 KB

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