{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://codoc.dev/schema/v1",
"title": "Codoc Unified Documentation Schema",
"description": "A unified schema for documenting Ruby and TypeScript codebases",
"definitions": {
"SourceLocation": {
"type": "object",
"description": "Location in source code",
"properties": {
"file": { "type": "string", "description": "Relative file path" },
"line": { "type": "integer", "description": "Line number (1-indexed)" },
"column": { "type": "integer", "description": "Column number (0-indexed)" }
},
"required": ["file", "line"]
},
"TypeReference": {
"type": "object",
"description": "Reference to a type (can be simple, generic, union, or array)",
"properties": {
"name": { "type": "string", "description": "Type name (e.g., 'String', 'Array', 'MyClass')" },
"kind": {
"type": "string",
"enum": ["simple", "generic", "union", "intersection", "array", "tuple", "literal", "function", "unknown"],
"description": "Kind of type reference"
},
"args": {
"type": "array",
"items": { "$ref": "#/definitions/TypeReference" },
"description": "Generic type arguments (e.g., Array<String> -> args: [{name: 'String'}])"
},
"members": {
"type": "array",
"items": { "$ref": "#/definitions/TypeReference" },
"description": "Union/intersection/tuple members"
},
"value": {
"description": "Literal value for literal types"
},
"nullable": {
"type": "boolean",
"description": "Whether this type can be null/nil"
},
"ref": {
"type": "string",
"description": "Reference ID to a documented entity (for internal linking)"
},
"package": {
"type": "string",
"description": "External package/gem name (for external linking via externalLinks mappings)"
},
"qualifiedName": {
"type": "string",
"description": "Fully qualified name for external symbol resolution (e.g., 'HTMLElement', 'ActiveRecord::Base')"
}
},
"required": ["name", "kind"]
},
"Example": {
"type": "object",
"description": "A code example",
"properties": {
"title": { "type": "string", "description": "Optional title for the example" },
"code": { "type": "string", "description": "The example code" },
"language": { "type": "string", "description": "Language hint (ruby, typescript, etc.)" }
},
"required": ["code"]
},
"Parameter": {
"type": "object",
"description": "A function/method parameter",
"properties": {
"name": { "type": "string" },
"type": { "$ref": "#/definitions/TypeReference" },
"description": { "type": "string" },
"default": { "type": "string", "description": "Default value as string representation" },
"optional": { "type": "boolean" },
"rest": { "type": "boolean", "description": "Whether this is a rest/splat parameter" },
"options": {
"type": "array",
"items": { "$ref": "#/definitions/OptionEntry" },
"description": "For Hash/object parameters, the accepted options"
}
},
"required": ["name"]
},
"OptionEntry": {
"type": "object",
"description": "An entry in a Hash/object options parameter (from @option tags)",
"properties": {
"name": { "type": "string", "description": "Option key name" },
"type": { "$ref": "#/definitions/TypeReference" },
"description": { "type": "string" },
"required": { "type": "boolean" },
"default": { "type": "string" }
},
"required": ["name"]
},
"Throws": {
"type": "object",
"description": "An exception/error that can be thrown",
"properties": {
"type": { "$ref": "#/definitions/TypeReference" },
"description": { "type": "string" }
}
},
"Deprecation": {
"type": "object",
"description": "Deprecation notice",
"properties": {
"message": { "type": "string" },
"since": { "type": "string", "description": "Version when deprecated" },
"replacement": { "type": "string", "description": "Suggested replacement" }
}
},
"SeeReference": {
"type": "object",
"description": "Cross-reference to related documentation",
"properties": {
"text": { "type": "string", "description": "Display text" },
"ref": { "type": "string", "description": "Reference ID or URL" }
},
"required": ["text"]
},
"YieldBlock": {
"type": "object",
"description": "Block/callback parameter documentation (Ruby yield, TS callback)",
"properties": {
"description": { "type": "string" },
"params": {
"type": "array",
"items": { "$ref": "#/definitions/Parameter" }
},
"returns": { "$ref": "#/definitions/TypeReference" }
}
},
"Documentation": {
"type": "object",
"description": "Common documentation fields shared by all entities",
"properties": {
"summary": { "type": "string", "description": "Brief one-line summary" },
"description": { "type": "string", "description": "Full description (may contain markdown)" },
"examples": {
"type": "array",
"items": { "$ref": "#/definitions/Example" }
},
"see": {
"type": "array",
"items": { "$ref": "#/definitions/SeeReference" }
},
"notes": {
"type": "array",
"items": { "type": "string" },
"description": "Important notes (@note tags)"
},
"todos": {
"type": "array",
"items": { "type": "string" },
"description": "TODO items (@todo tags)"
},
"deprecated": { "$ref": "#/definitions/Deprecation" },
"since": { "type": "string", "description": "Version when introduced" },
"tags": {
"type": "object",
"additionalProperties": { "type": "string" },
"description": "Custom tags not covered by standard fields"
}
}
},
"Visibility": {
"type": "string",
"enum": ["public", "protected", "private", "internal"],
"description": "Visibility/access level"
},
"BaseEntity": {
"type": "object",
"description": "Base properties shared by all documented entities",
"properties": {
"id": { "type": "string", "description": "Unique identifier for cross-referencing" },
"name": { "type": "string", "description": "Entity name" },
"kind": { "type": "string", "description": "Entity kind (class, module, method, etc.)" },
"location": { "$ref": "#/definitions/SourceLocation" },
"docs": { "$ref": "#/definitions/Documentation" },
"visibility": { "$ref": "#/definitions/Visibility" },
"isPrivateApi": { "type": "boolean", "description": "Marked with @private tag" }
},
"required": ["id", "name", "kind"]
},
"Property": {
"allOf": [
{ "$ref": "#/definitions/BaseEntity" },
{
"type": "object",
"properties": {
"kind": { "const": "property" },
"type": { "$ref": "#/definitions/TypeReference" },
"default": { "type": "string" },
"readonly": { "type": "boolean" },
"static": { "type": "boolean" },
"optional": { "type": "boolean" },
"getter": { "type": "boolean", "description": "Whether this property has a getter accessor" },
"setter": { "type": "boolean", "description": "Whether this property has a setter accessor" }
}
}
]
},
"Constant": {
"allOf": [
{ "$ref": "#/definitions/BaseEntity" },
{
"type": "object",
"properties": {
"kind": { "const": "constant" },
"type": { "$ref": "#/definitions/TypeReference" },
"value": { "type": "string", "description": "String representation of the value" }
}
}
]
},
"Callable": {
"allOf": [
{ "$ref": "#/definitions/BaseEntity" },
{
"type": "object",
"properties": {
"kind": { "enum": ["method", "function", "constructor"] },
"params": {
"type": "array",
"items": { "$ref": "#/definitions/Parameter" }
},
"returns": { "$ref": "#/definitions/TypeReference" },
"returnsDescription": { "type": "string" },
"throws": {
"type": "array",
"items": { "$ref": "#/definitions/Throws" }
},
"yields": { "$ref": "#/definitions/YieldBlock" },
"async": { "type": "boolean" },
"static": { "type": "boolean" },
"abstract": { "type": "boolean" },
"generator": { "type": "boolean" },
"typeParams": {
"type": "array",
"items": { "$ref": "#/definitions/TypeParameter" }
},
"overloads": {
"type": "array",
"items": { "$ref": "#/definitions/Callable" },
"description": "Method overloads (TypeScript)"
}
}
}
]
},
"TypeParameter": {
"type": "object",
"description": "Generic type parameter",
"properties": {
"name": { "type": "string" },
"constraint": { "$ref": "#/definitions/TypeReference" },
"default": { "$ref": "#/definitions/TypeReference" },
"description": { "type": "string" }
},
"required": ["name"]
},
"TypeAlias": {
"allOf": [
{ "$ref": "#/definitions/BaseEntity" },
{
"type": "object",
"properties": {
"kind": { "const": "type" },
"type": { "$ref": "#/definitions/TypeReference" },
"typeParams": {
"type": "array",
"items": { "$ref": "#/definitions/TypeParameter" }
}
}
}
]
},
"Interface": {
"allOf": [
{ "$ref": "#/definitions/BaseEntity" },
{
"type": "object",
"properties": {
"kind": { "const": "interface" },
"extends": {
"type": "array",
"items": { "$ref": "#/definitions/TypeReference" }
},
"typeParams": {
"type": "array",
"items": { "$ref": "#/definitions/TypeParameter" }
},
"properties": {
"type": "array",
"items": { "$ref": "#/definitions/Property" }
},
"methods": {
"type": "array",
"items": { "$ref": "#/definitions/Callable" }
},
"callSignatures": {
"type": "array",
"items": { "$ref": "#/definitions/Callable" },
"description": "For callable interfaces"
},
"indexSignatures": {
"type": "array",
"items": {
"type": "object",
"properties": {
"keyType": { "$ref": "#/definitions/TypeReference" },
"valueType": { "$ref": "#/definitions/TypeReference" },
"readonly": { "type": "boolean" }
}
}
}
}
}
]
},
"Enum": {
"allOf": [
{ "$ref": "#/definitions/BaseEntity" },
{
"type": "object",
"properties": {
"kind": { "const": "enum" },
"members": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"value": { "description": "Enum member value" },
"docs": { "$ref": "#/definitions/Documentation" }
},
"required": ["name"]
}
}
}
}
]
},
"Class": {
"allOf": [
{ "$ref": "#/definitions/BaseEntity" },
{
"type": "object",
"properties": {
"kind": { "const": "class" },
"extends": { "$ref": "#/definitions/TypeReference" },
"implements": {
"type": "array",
"items": { "$ref": "#/definitions/TypeReference" }
},
"includes": {
"type": "array",
"items": { "$ref": "#/definitions/TypeReference" },
"description": "Included modules (Ruby)"
},
"prepends": {
"type": "array",
"items": { "$ref": "#/definitions/TypeReference" },
"description": "Prepended modules (Ruby)"
},
"typeParams": {
"type": "array",
"items": { "$ref": "#/definitions/TypeParameter" }
},
"abstract": { "type": "boolean" },
"constructor": { "$ref": "#/definitions/Callable" },
"properties": {
"type": "array",
"items": { "$ref": "#/definitions/Property" }
},
"methods": {
"type": "array",
"items": { "$ref": "#/definitions/Callable" }
},
"staticProperties": {
"type": "array",
"items": { "$ref": "#/definitions/Property" }
},
"staticMethods": {
"type": "array",
"items": { "$ref": "#/definitions/Callable" }
},
"constants": {
"type": "array",
"items": { "$ref": "#/definitions/Constant" }
},
"nested": {
"type": "array",
"items": { "$ref": "#/definitions/Entity" },
"description": "Nested classes, modules, etc."
}
}
}
]
},
"Module": {
"allOf": [
{ "$ref": "#/definitions/BaseEntity" },
{
"type": "object",
"properties": {
"kind": { "const": "module" },
"extends": {
"type": "array",
"items": { "$ref": "#/definitions/TypeReference" },
"description": "Extended modules (Ruby module extension)"
},
"includes": {
"type": "array",
"items": { "$ref": "#/definitions/TypeReference" },
"description": "Included modules (Ruby)"
},
"functions": {
"type": "array",
"items": { "$ref": "#/definitions/Callable" }
},
"properties": {
"type": "array",
"items": { "$ref": "#/definitions/Property" }
},
"constants": {
"type": "array",
"items": { "$ref": "#/definitions/Constant" }
},
"classes": {
"type": "array",
"items": { "$ref": "#/definitions/Class" }
},
"modules": {
"type": "array",
"items": { "$ref": "#/definitions/Module" }
},
"interfaces": {
"type": "array",
"items": { "$ref": "#/definitions/Interface" }
},
"types": {
"type": "array",
"items": { "$ref": "#/definitions/TypeAlias" }
},
"enums": {
"type": "array",
"items": { "$ref": "#/definitions/Enum" }
},
"isConcern": {
"type": "boolean",
"description": "Whether this is an ActiveSupport::Concern (Ruby)"
},
"instanceMethods": {
"type": "array",
"items": { "$ref": "#/definitions/Callable" },
"description": "Methods added to including class (Ruby modules)"
},
"classMethods": {
"type": "array",
"items": { "$ref": "#/definitions/Callable" },
"description": "Class methods from ClassMethods module (Ruby concerns)"
}
}
}
]
},
"Entity": {
"oneOf": [
{ "$ref": "#/definitions/Module" },
{ "$ref": "#/definitions/Class" },
{ "$ref": "#/definitions/Interface" },
{ "$ref": "#/definitions/TypeAlias" },
{ "$ref": "#/definitions/Enum" },
{ "$ref": "#/definitions/Callable" },
{ "$ref": "#/definitions/Property" },
{ "$ref": "#/definitions/Constant" }
]
},
"ExternalLinkMapping": {
"type": "object",
"description": "Configuration for linking to external documentation",
"properties": {
"baseUrl": {
"type": "string",
"description": "Base URL for documentation (e.g., 'https://ruby-doc.org/core-3.2.0')"
},
"urlTemplate": {
"type": "string",
"description": "URL template with placeholders: {name}, {qualifiedName}, {anchor}. Example: '{baseUrl}/{qualifiedName}.html#{anchor}'"
},
"symbols": {
"type": "object",
"description": "Explicit URL overrides for specific symbols",
"additionalProperties": { "type": "string" }
},
"transform": {
"type": "object",
"description": "Transform rules for symbol names",
"properties": {
"nameSeparator": {
"type": "string",
"description": "How to transform :: or . in qualified names (e.g., '/' for URLs)"
},
"methodPrefix": {
"type": "string",
"description": "Prefix for instance method anchors (e.g., 'method-i-' for Ruby docs)"
},
"classMethodPrefix": {
"type": "string",
"description": "Prefix for class method anchors (e.g., 'method-c-' for Ruby docs)"
},
"lowercase": {
"type": "boolean",
"description": "Whether to lowercase the symbol name in URLs"
}
}
}
}
},
"SymbolEntry": {
"type": "object",
"description": "Entry in the symbol table for linking",
"properties": {
"id": { "type": "string", "description": "Unique identifier (same as entity id)" },
"name": { "type": "string", "description": "Short name" },
"qualifiedName": { "type": "string", "description": "Fully qualified name (e.g., 'MyApp::Component#render')" },
"kind": { "type": "string", "description": "Entity kind" },
"parent": { "type": "string", "description": "Parent entity ID (for nesting context)" },
"file": { "type": "string", "description": "Source file path" },
"line": { "type": "integer", "description": "Line number" },
"signature": { "type": "string", "description": "Short signature for methods (e.g., 'render(options = {})')" }
},
"required": ["id", "name", "qualifiedName", "kind"]
}
},
"type": "object",
"properties": {
"schema": {
"type": "string",
"const": "codoc/v1",
"description": "Schema version identifier"
},
"metadata": {
"type": "object",
"properties": {
"name": { "type": "string", "description": "Project/package name" },
"version": { "type": "string", "description": "Project version" },
"language": {
"type": "string",
"enum": ["ruby", "typescript"],
"description": "Source language"
},
"generatedAt": { "type": "string", "format": "date-time" },
"sourceRoot": { "type": "string", "description": "Root directory for source files" },
"idPrefix": {
"type": "string",
"description": "Prefix for all entity IDs (e.g., 'js:', 'ruby:'). Useful when combining docs from multiple sources."
},
"files": {
"type": "array",
"items": { "type": "string" },
"description": "List of parsed files"
},
"externalLinks": {
"type": "object",
"description": "External symbol link mappings by package/gem name",
"additionalProperties": {
"$ref": "#/definitions/ExternalLinkMapping"
}
}
},
"required": ["name", "language", "generatedAt"]
},
"entities": {
"type": "array",
"items": { "$ref": "#/definitions/Entity" },
"description": "Top-level documented entities"
},
"symbols": {
"type": "array",
"items": { "$ref": "#/definitions/SymbolEntry" },
"description": "Flat symbol table for quick lookups and linking (auto-generated from entities)"
},
"unresolvedReferences": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string", "description": "Unresolved type/symbol name" },
"qualifiedName": { "type": "string", "description": "Attempted qualified name" },
"package": { "type": "string", "description": "Package hint if available" },
"referencedFrom": {
"type": "array",
"items": { "type": "string" },
"description": "Entity IDs that reference this unresolved symbol"
}
},
"required": ["name", "referencedFrom"]
},
"description": "Symbols referenced but not found in entities or external mappings (for debugging/completeness)"
}
},
"required": ["schema", "metadata", "entities", "symbols"]
}