/** * Generate committed Cordis artifacts from the Typert catalog projector and * the independent vendored-core projector. */ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs' import { dirname, resolve } from 'node:path' import { projectCordisCatalog, renderEvents, renderServices, } from '@deepseek-ai/dsh-typert-generator' import type { CordisCatalogPolicy } from '@deepseek-ai/dsh-typert-generator' import { renderCordisCoreApiPages } from './cordis-core-api.ts' const root = resolve(import.meta.dirname, '..') const OUT_EVENTS = 'docs/cordis-catalog/events.md' const OUT_SERVICES = 'docs/cordis-catalog/services.md' const OUT_RUNTIME_API = 'packages/cordis/tool-cordis/src/api-catalog.ts' /** One primary core-data-structures page per project type used by a generated signature. */ export const LINK_MAP: Readonly> = { Agent: 'core.md', AgentCancelCause: 'core.md', AgentOptions: 'core.md', AgentStatus: 'core.md', ContentBlock: 'core.md', ContinuationDecision: 'core.md', ContinuationStop: 'core.md', GenerateOptions: 'core.md', MessageId: 'core.md', HookContext: 'core.md', SettleReason: 'core.md', AdapterRegistrationHandle: 'core.md', LlmCallConfig: 'core.md', LlmModelContext: 'core.md', LlmModelReasoningInfo: 'core.md', LlmResolvedModelInfo: 'core.md', LlmFailure: 'llm-streaming.md', LlmModelInfo: 'core.md', LlmProviderInfo: 'core.md', LlmConfigurableProvider: 'core.md', ResolvedRetryPolicy: 'llm-streaming.md', Message: 'core.md', MessageSource: 'core.md', UserMessage: 'session.md', PreStepDecision: 'core.md', PreStepContext: 'core.md', RequestErrorAction: 'core.md', RequestFailureContext: 'core.md', PreparedReferencedMessage: 'session-reference.md', SessionReferenceCandidate: 'session-reference.md', SessionReferenceInput: 'session-reference.md', SessionEvent: 'core.md', SessionId: 'core.md', SessionStartSource: 'core.md', SessionLogSnapshot: 'session-query.md', SessionSurfaceSnapshot: 'session-query.md', ApprovalOutcome: 'approval.md', ApprovalPolicy: 'approval.md', ApprovalRequest: 'approval.md', ApprovalService: 'approval.md', BashExecRequest: 'bash.md', BashExecSpec: 'bash.md', BashProcess: 'bash.md', BashRunResult: 'bash.md', DshEnvironment: 'subprocess.md', SubprocessHandle: 'subprocess.md', SubprocessOutcome: 'subprocess.md', SubprocessOutputRead: 'subprocess.md', SubprocessOutputReader: 'subprocess.md', SubprocessSpawnSpec: 'subprocess.md', CodeRunRequest: 'code-runtime.md', CodeRunResult: 'code-runtime.md', CompactionResult: 'compaction.md', CompactionTrigger: 'compaction.md', PruneResult: 'compaction.md', FileReadOutcome: 'filesystem.md', FsDirEntry: 'filesystem.md', FsEditOutcome: 'filesystem.md', FsEditRequest: 'filesystem.md', FsInfo: 'filesystem.md', FsPathInfo: 'filesystem.md', FsPolicyExec: 'filesystem.md', FsTarget: 'filesystem.md', FsVersion: 'filesystem.md', FsWriteIntent: 'filesystem.md', FsWriteOutcome: 'filesystem.md', CreateGoalRequest: 'goal.md', EditGoalRequest: 'goal.md', GoalBlockReason: 'goal.md', GoalChanged: 'goal.md', GoalRef: 'goal.md', GoalView: 'goal.md', CommandDefinition: 'commands.md', CommandDescriptor: 'commands.md', CommandResult: 'commands.md', CommandSurface: 'commands.md', LlmAdapter: 'llm-streaming.md', PreparedLlmCall: 'llm-streaming.md', LlmService: 'llm-streaming.md', StreamChunk: 'llm-streaming.md', SkillProviderControl: 'skills.md', CreateSessionOptions: 'persistence.md', SessionHeader: 'persistence.md', SessionLocation: 'persistence.md', SessionPersistenceSnapshot: 'persistence.md', ConfinedArgv: 'sandbox.md', SandboxExecutionPolicy: 'sandbox.md', SandboxMode: 'sandbox.md', SandboxPolicy: 'sandbox.md', PtyBackend: 'pty.md', PtyReadRequest: 'pty.md', PtyReadResult: 'pty.md', PtySendOperation: 'pty.md', PtySendRequest: 'pty.md', PtySessionId: 'pty.md', PtySessionSnapshot: 'pty.md', PtySignal: 'pty.md', PtySignalResult: 'pty.md', PtySpawnRequest: 'pty.md', PtySpawnResult: 'pty.md', SandboxPolicyRequest: 'sandbox.md', ScopeKey: 'scope.md', Scoped: 'scope.md', EpochHeader: 'session.md', Session: 'session.md', SessionEventMap: 'session.md', TurnEndReason: 'session.md', TurnTrigger: 'session.md', SessionEventReadRequest: 'session-query.md', SessionEventRecord: 'session-query.md', SessionEventResultFilter: 'session-query.md', SessionEventSearchDocument: 'session-query.md', SessionEventSearchHit: 'session-query.md', SessionEventSearchPage: 'session-query.md', SessionEventSearchRequest: 'session-query.md', SessionEventTrace: 'session-query.md', SessionEventTraceObservation: 'session-query.md', SessionEventTraceRequest: 'session-query.md', SessionEventWindow: 'session-query.md', SessionLineageTrace: 'session-query.md', SessionRecord: 'session-query.md', SessionResultFilter: 'session-query.md', SessionSearchExecContext: 'session-query.md', SessionSearchHit: 'session-query.md', SessionSearchPage: 'session-query.md', SessionSearchRequest: 'session-query.md', SessionTitleObservation: 'session-query.md', SessionTitleObservationResult: 'session-query.md', SessionTitleProvider: 'session-title.md', SessionTitleSnapshot: 'session-title.md', SkillCatalogSnapshot: 'skills.md', SkillDefinition: 'skills.md', SkillLookupOptions: 'skills.md', SkillProvider: 'skills.md', SkillProviderObservation: 'skills.md', SkillRegistration: 'skills.md', SkillSummary: 'skills.md', SaveTextSpill: 'spill.md', SpillRef: 'spill.md', ContinuableCreateRequest: 'subagent.md', ContinuableCreateSpec: 'subagent.md', ContinuableSetupContribution: 'subagent.md', ContinuableStart: 'subagent.md', ContinuableStartSpec: 'subagent.md', CoordinatorMessageSource: 'subagent.md', SubagentFollowupOptions: 'subagent.md', SubagentListEntry: 'subagent.md', SubagentProvider: 'subagent.md', SubagentReportDelivery: 'subagent.md', SubagentReportMessageSource: 'subagent.md', SubagentReportOptions: 'subagent.md', SubagentRun: 'subagent.md', SubagentService: 'subagent.md', SubagentStartRequest: 'subagent.md', AssembleContext: 'system-prompt.md', PromptContext: 'system-prompt.md', PromptSection: 'system-prompt.md', SystemPrompt: 'system-prompt.md', ToolProviderResult: 'system-prompt.md', TaskDoneListener: 'tasks.md', TaskId: 'tasks.md', TaskRead: 'tasks.md', TaskSnapshot: 'tasks.md', TaskStart: 'tasks.md', TokenMeasurement: 'token-meter.md', CodeDispatchLog: 'tools.md', PostToolDecision: 'tools.md', PreToolDecision: 'tools.md', ToolDefinition: 'tools.md', ToolExecution: 'tools.md', ToolDispatchExecution: 'tools.md', ToolExecutionInput: 'tools.md', ToolExecutionMode: 'tools.md', ToolExecutionResult: 'tools.md', ToolExecutionToken: 'tools.md', ToolGuard: 'tools.md', ToolRegistry: 'tools.md', ToolRestriction: 'tools.md', ToolSchema: 'tools.md', SettingsNamespace: 'settings.md', SettingsRegisterOptions: 'settings.md', SettingsScope: 'settings.md', SettingsDescriptor: 'settings.md', SettingsPathOp: 'settings.md', SettingsDescribeOptions: 'settings.md', SettingsUpdateSource: 'settings.md', CredentialRef: 'credentials.md', CredentialInfo: 'credentials.md', ResolvedCredential: 'credentials.md', AskUserQuestionAnswer: 'user-interaction.md', AskUserQuestionRequest: 'user-interaction.md', UserInteractionProvider: 'user-interaction.md', WebFetchProvider: 'web.md', WebFetchRequest: 'web.md', WebFetchResult: 'web.md', WebSearchProvider: 'web.md', WebSearchRequest: 'web.md', WebSearchResult: 'web.md', WorkflowRun: 'workflow.md', WorkflowRunInfo: 'workflow.md', WorkflowStartRequest: 'workflow.md', } /** TypeScript lib and pinned framework types with no repository-owned data page. */ export const FOUNDATION_TYPE_NAMES: ReadonlySet = new Set([ 'AbortSignal', 'AsyncIterable', 'Context', 'Error', 'Map', 'Partial', 'Pick', 'Promise', 'Readonly', ]) /** Project types deliberately documented outside the core-data catalog. */ export const TYPE_LINK_EXEMPTIONS: Readonly> = { AgentFactory: 'agent creation seam is owned by packages/core/agent/README.md', z: 'schemastery schema constructor is owned by vendor/schemastery (vendored upstream)', BeginCommandRequest: 'event-local request contract is owned by packages/client/ui-slash/src/types.ts', InsertReferenceRequest: 'event-local request contract is owned by packages/client/ui-slash/src/types.ts', ConsumeTokenRequest: 'event-local request contract is owned by packages/client/ui-slash/src/types.ts', InsertTextRequest: 'event-local request contract is owned by packages/client/ui-slash/src/types.ts', AgentHandle: 'agent ownership handle is owned by packages/core/agent/README.md', BashEnvContributor: 'service-local extension type is owned by packages/bash/tool-bash/src/index.ts', BashEnvVariableInfo: 'service-local metadata type is owned by packages/bash/tool-bash/src/index.ts', CompactAgentContext: 'compaction service input is owned by packages/compact/compact/src/index.ts', ManualCompactAgentContext: 'manual compaction service input is owned by packages/compact/compact/src/index.ts', DirectoryPickerCapability: 'picker interaction contract is owned by packages/host/directory-picker/README.md', CreateAgentOptions: 'agent creation contract is owned by packages/core/agent/README.md', Domain: 'domain interface is owned by packages/storage/storage-domain/README.md', DomainChanged: 'event-local snapshot is owned by packages/storage/storage-domain/src/events.ts', DomainFacility: 'domain form facility is owned by packages/storage/storage-domain/README.md', DomainImpl: 'domain implementation contract is owned by packages/storage/storage-domain/README.md', DomainSpec: 'domain declaration contract is owned by packages/storage/storage-domain/README.md', StorageBackend: 'backend contract is owned by packages/storage/storage/src/backend.ts', StorageForms: 'merge-extensible form map is owned by packages/storage/storage/src/index.ts', ProjectionDefinition: 'projection unit contract is owned by packages/session-projection/session-projection/README.md', SessionProjectionMap: 'merge-extensible projection key map is owned by packages/session-projection/session-projection/src/types.ts', ProjectionChangeListener: 'change-feed listener contract is owned by packages/session-projection/session-projection/src/index.ts', ProjectionSnapshot: 'watermark snapshot shape is owned by packages/session-projection/session-projection/src/index.ts', ProjectionCheckpoint: 'persisted checkpoint row map is owned by packages/session-projection/session-projection/src/index.ts', CommandExecution: 'executor return contract is owned by packages/ui/commands/src/index.ts', TypertContribution: 'registry contribution contract is owned by packages/typert/registry/README.md', TypertFace: 'registry face identity is owned by packages/typert/registry/README.md', TypertPackageFilter: 'registry package query filter is owned by packages/typert/registry/README.md', TypertPackageRecord: 'registry package record is owned by packages/typert/registry/README.md', TypertSchemaFilter: 'registry schema query filter is owned by packages/typert/registry/README.md', TypertSchemaRecord: 'registry schema record is owned by packages/typert/registry/README.md', 'z.core.JSONSchema.BaseSchema': 'zod projection output is owned by the zod v4 API', 'z.core.ToJSONSchemaParams': 'zod projection parameters are owned by the zod v4 API', InvariantInstaller: 'service-local contribution contract is owned by packages/support/invariants/README.md', LocaleDict: 'service-local dictionary shape is owned by packages/client/i18n/src/index.ts', WebBootGraph: 'web boot graph wire shape is owned by packages/client/modules/src/client/index.ts', WebRoute: 'route registration contract is owned by packages/host/webserver/src/index.ts', WebUpgradeRoute: 'upgrade route registration contract is owned by packages/host/webserver/src/index.ts', ThemeTokens: 'service-local token dictionary is owned by packages/client/ui-theme/src/index.ts', Translate: 'service-local bound translator is owned by packages/client/i18n/src/index.ts', InvariantRegistration: 'service-local lifecycle handle is owned by packages/support/invariants/README.md', PresetOption: 'deployment menu metadata is owned by packages/ui/permission/README.md', PresetSpec: 'deployment preset composition is owned by packages/ui/permission/README.md', KnobState: 'projection unit state shape is owned by packages/ui/permission/README.md', PermissionSelect: 'permissions projection payload is owned by packages/ui/permission/src/types.ts', PromptAssembly: 'assembly result is owned by packages/core/system-prompt/README.md', ResumeAgentOptions: 'agent resume contract is owned by packages/core/agent/README.md', SessionForkSource: 'service-local fork input is owned by packages/core/session/src/index.ts', SubagentRunEndInfo: 'event payload contract is owned by packages/subagent/subagent/src/types.ts', SubagentRunInfo: 'event payload contract is owned by packages/subagent/subagent/src/types.ts', TelemetryRecord: 'seam-local record contract is owned by packages/telemetry/session-telemetry/src/index.ts', WorkflowAgentEndInfo: 'event-local snapshot is owned by packages/workflow/workflow/src/index.ts', WorkflowAgentInfo: 'event-local snapshot is owned by packages/workflow/workflow/src/index.ts', WorkflowResultInfo: 'event-local snapshot is owned by packages/workflow/workflow/src/index.ts', Workspace: 'workspace entity contract is owned by packages/workspace/workspace/README.md', WorkspaceId: 'branded id is owned by packages/workspace/workspace/README.md', } /** Repository data policy consumed by the Cordis catalog projector. */ export const CORDIS_CATALOG_POLICY: CordisCatalogPolicy = { linkedTypePages: LINK_MAP, foundationTypeNames: FOUNDATION_TYPE_NAMES, typeLinkExemptions: TYPE_LINK_EXEMPTIONS, inheritedEvents: [ { name: 'internal/plugin', summary: 'A plugin fiber was created.', source: 'vendor/cordis/src/events.ts:328' }, { name: 'internal/status', summary: 'A fiber changed lifecycle state.', source: 'vendor/cordis/src/events.ts:330' }, { name: 'internal/service', summary: 'Interception hook for a service binding (no core producer).', source: 'vendor/cordis/src/events.ts:332' }, { name: 'internal/update', summary: 'Waterfall: a fiber config update is being applied.', source: 'vendor/cordis/src/events.ts:334' }, { name: 'internal/get', summary: 'Waterfall: a service is being read from the store.', source: 'vendor/cordis/src/events.ts:336' }, { name: 'internal/set', summary: 'Waterfall: a service is being written to the store.', source: 'vendor/cordis/src/events.ts:338' }, { name: 'internal/listener', summary: 'A listener was registered.', source: 'vendor/cordis/src/events.ts:340' }, { name: 'internal/dispatch', summary: 'An event is being dispatched to listeners.', source: 'vendor/cordis/src/events.ts:342' }, { name: 'hmr/change', summary: 'A watched source file changed on disk.', source: 'vendor/hmr/src/index.ts:20' }, { name: 'hmr/reload', summary: 'Plugins are being reloaded after a change.', source: 'vendor/hmr/src/index.ts:22' }, { name: 'hmr/config-update-failed', summary: 'A watched config-file refresh failed.', source: 'vendor/hmr/src/index.ts:29' }, { name: 'exit', summary: 'The process is exiting on a signal.', source: 'vendor/loader/src/index.ts:23' }, { name: 'loader/config-update', summary: 'The loader config tree changed.', source: 'vendor/loader/src/index.ts:24' }, { name: 'loader/entry-init', summary: 'A config entry is being initialized.', source: 'vendor/loader/src/index.ts:25' }, { name: 'loader/partial-dispose', summary: 'An entry is being partially disposed on reload.', source: 'vendor/loader/src/index.ts:26' }, { name: 'loader/patch-context', summary: 'A context is being patched during a reload.', source: 'vendor/loader/src/index.ts:27' }, ], inheritedServices: [ { name: 'ctx.on / ctx.once', summary: 'Register an event listener (disposable).', source: 'vendor/cordis/src/events.ts:34' }, { 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' }, { name: 'ctx.plugin / ctx.inject', summary: 'Load a plugin / declare required services.', source: 'vendor/cordis/src/registry.ts:164' }, { name: 'ctx.effect', summary: 'Register a disposable side effect tied to the fiber.', source: 'vendor/cordis/src/fiber.ts:9' }, { 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' }, { name: 'ctx.extend / ctx.isolate / ctx.intercept', summary: 'Derive a child context (scoped services / isolation / interception).', source: 'vendor/cordis/src/context.ts:42' }, { 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' }, { 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' }, { name: 'ctx.loader', summary: 'The config Loader that booted the app (present under the loader).', source: 'vendor/loader/src/index.ts:30' }, { name: 'ctx.hmr', summary: 'The hot-module-reload watcher (present under the hmr plugin).', source: 'vendor/hmr/src/index.ts:15' }, ], } /** CLI entry: default writes every artifact; `--check` reports stale files. * @returns nothing; writes files or reports freshness through the process. */ export function main(): void { const { projector, model } = projectCordisCatalog(root, CORDIS_CATALOG_POLICY) const outputs: [string, string][] = [ [OUT_EVENTS, renderEvents([...model.events], CORDIS_CATALOG_POLICY)], [OUT_SERVICES, renderServices([...model.services], CORDIS_CATALOG_POLICY)], [OUT_RUNTIME_API, projector.renderRuntimeApi(model)], ...renderCordisCoreApiPages(), ] if (process.argv.includes('--check')) { const stale: string[] = [] for (const [out, content] of outputs) { let committed: string | null = null try { committed = readFileSync(resolve(root, out), 'utf8') } catch { // Only ENOENT is expected; either read failure has the same remedy. committed = null } if (committed !== content) stale.push(out) } if (stale.length === 0) { console.log(`gen-cordis-catalog: ${outputs.length} generated file(s) are up to date.`) process.exit(0) } console.error(`gen-cordis-catalog: ${stale.join(' and ')} ${stale.length === 1 ? 'is' : 'are'} stale. Run \`pnpm run gen-cordis-catalog\` and commit the result.`) process.exit(1) } for (const [out, content] of outputs) { const destination = resolve(root, out) mkdirSync(dirname(destination), { recursive: true }) writeFileSync(destination, content) } console.log(`gen-cordis-catalog: wrote ${outputs.length} generated file(s).`) } if (process.argv[1] && import.meta.filename === resolve(process.argv[1])) main()