Skip to content

CLI Reference

tdsl is a command-line tool for compiling, validating, formatting, and rendering .tdsl files. This reference covers the global options, exit codes, and the arguments and options of the main subcommands.

tdsl [OPTIONS] <COMMAND>

--wikidata-timeout is a global option, so it can be placed either before or after the subcommand (e.g. tdsl --wikidata-timeout 60 build sample.tdsl).

OptionDescriptionDefault
--wikidata-timeout <SECONDS>HTTP timeout (in seconds) for Wikidata requests30
-h, --helpShow help
-V, --versionShow version
CodeMeaning
0Success
1Error (parse failure, validation failure, IO error, etc.)

tdsl check and tdsl fmt --check can be used as CI gates. They return exit code 1 when there is a diff or an error, so a pipeline can rely on the exit code directly to decide pass or fail.

SubcommandDescription
buildCompile .tdsl to IR JSON
mergeMerge multiple .tdsl files and output IR JSON
checkRun a syntax and semantic error check
astDump the parsed AST (for debugging)
fetchFetch and display data for a Wikidata entity
searchSearch for Wikidata entities by keyword
inspectAnalyze a Wikidata entity in detail and suggest a mapping strategy
resolveResolve a Wikipedia article URL to a Wikidata QID
scaffoldGenerate a .tdsl template from Wikidata entities
renderRender .tdsl to a standalone HTML/SVG/PNG/PDF timeline
initGenerate a minimal .tdsl template for manual editing
import-csvImport timeline items from CSV
export-csvExport IR to CSV (symmetric with import-csv)
fmtFormat .tdsl files to the canonical style
lintLint .tdsl files and apply automatic fixes
cacheManage the local Wikidata cache
decompileDecompile JSON IR back to .tdsl source
completionsGenerate shell completion scripts
lspStart the LSP server over stdio (Diagnostics + Completion + Hover + Goto Definition + Code Action + Document Symbols + Find References + Rename + Formatting)

Compiles .tdsl files to IR JSON (intermediate representation JSON). When multiple files are given, they are merged before being compiled.

tdsl build [OPTIONS] [FILE]...
ArgumentDescription
[FILE]...Path(s) to the input .tdsl file(s) (merged in order when multiple are given). Optional when --json-schema is used
OptionDescriptionDefault
-o, --output <OUTPUT>Path to the output JSON filestdout
--prettyPretty-print the JSON output
--offlineSkip Wikidata fetching and process only statically defined items
--no-cacheBypass the local cache and call the API directly
--cache-ttl <CACHE_TTL>Cache expiry in seconds; 0 disables caching86400 (24h)
--json-schemaWrite the JSON Schema for the IR to stdout (no input file required)
Terminal window
# Compile offline and print pretty-printed JSON
tdsl build examples/china_dynasties.tdsl --pretty
# Compile with Wikidata integration and save to a file
tdsl build examples/china_with_import.tdsl --output out.json --pretty
# Offline build (recommended during development)
tdsl build examples/china_with_import.tdsl --offline --pretty
# Merge multiple files and compile
tdsl build part1.tdsl part2.tdsl --output merged.json --pretty
# Print the JSON Schema for the IR (no input file required)
tdsl build --json-schema
# Pretty-print the JSON Schema and save it to a file
tdsl build --json-schema --pretty --output timeline-ir.schema.json

Checks a .tdsl file for syntax errors and semantic errors (undefined lane references, inconsistent date ranges, etc.). Returns exit code 0 when there are no errors.

tdsl check [OPTIONS] <FILE>...
ArgumentDescription
<FILE>...Path(s) to input .tdsl file(s) or directories (directories are searched recursively for *.tdsl). Multiple allowed (v2.0.0+)
OptionDescriptionDefault
--offlineMake it explicit that Wikidata resolution is skipped (currently the only behavior either way)
--format <FORMAT>Output format (text / json). json prints machine-readable diagnostics including code / severity / line / message (v2.0.0+)text
--deny-warningsExit non-zero when any warning is reported. By default, warnings alone still succeed (v2.0.0+)

For the list of diagnostic codes (e.g. W204), see Errors. In text output, each diagnostic is prefixed with its code and line number, e.g. Warning [W204] line 2: ... (v2.0.0+).

Behavior for multiple files/directories is shared with lint and fmt (v2.0.0+):

  • A directory is processed recursively for *.tdsl files
  • If any input fails, the command exits non-zero, but it doesn’t stop at the first failure — it processes every input and then prints a N of M file(s) failed: ... summary
  • When 2 or more targets are given, each is preceded by a === <path> === heading (single-file output stays unchanged)
  • Inputs are processed in path-sorted order
  • Zero matched files is an error (so a mistyped path is never silently reported as “no problems”)
Terminal window
# Run a syntax and semantic check
tdsl check examples/china_dynasties.tdsl
# Use it in CI (returns a non-zero exit code on error)
tdsl check my_timeline.tdsl && echo "OK"
# Recursively check a directory
tdsl check examples
# Check multiple files
tdsl check a.tdsl b.tdsl
# Fail on warnings too (for CI)
tdsl check my_timeline.tdsl --deny-warnings
# JSON output for CI
tdsl check my_timeline.tdsl --format json

Parses a .tdsl file and dumps its AST (abstract syntax tree) to stdout. This command is for grammar debugging and is not part of the normal workflow.

tdsl ast [OPTIONS] <FILE>
ArgumentDescription
<FILE>Path to the input .tdsl file
Terminal window
# Dump the AST
tdsl ast examples/china_dynasties.tdsl
# View it through a pager
tdsl ast examples/china_with_import.tdsl | less

Reads multiple .tdsl files and outputs a merged IR JSON. Metadata (title, unit, range) from the first file takes precedence.

tdsl merge [OPTIONS] <FILE> <FILE>...
ArgumentDescription
<FILE> <FILE>...Paths to the input .tdsl files (at least 2 required, merged in order)
OptionDescriptionDefault
-o, --output <OUTPUT>Path to the output JSON filestdout
--prettyPretty-print the JSON output
--offlineSkip Wikidata fetching and process only statically defined items
--no-cacheBypass the local cache and call the API directly
--cache-ttl <CACHE_TTL>Cache expiry in seconds; 0 disables caching86400 (24h)
Terminal window
# Merge two files and print pretty-printed output
tdsl merge china_dynasties.tdsl world_wars.tdsl --pretty
# Save to a file
tdsl merge base.tdsl extension.tdsl --output combined.json --pretty

Reverse-generates .tdsl source code from a JSON IR file. Useful when the JSON was produced by another tool, or when you want to recover source from an existing IR. Second precision and UTC offsets (Z / ±HH:MM) in start / end / time also round-trip without loss (v1.27.0+; earlier versions silently dropped them).

tdsl decompile [OPTIONS] [INPUT]
ArgumentDescription
[INPUT]Path to the input JSON file (reads stdin if omitted)
OptionDescriptionDefault
-o, --output <OUTPUT>Path to the output .tdsl filestdout
Terminal window
# Decompile a JSON IR to .tdsl
tdsl decompile out.json
# Save to a file
tdsl decompile out.json --output recovered.tdsl
# Via a pipeline (from stdin)
tdsl build examples/china_dynasties.tdsl --pretty | tdsl decompile --output recovered.tdsl

Limitation (comments are not preserved): Since decompile starts from a JSON IR, comments (// and /* */) that existed in the original .tdsl source cannot be restored. The IR does not carry any comment information, which is a permanent design constraint of treating the IR as the single source of truth.

Formats .tdsl files to the canonical style (2-space indentation, one blank line between blocks). By default, the formatted result is written to stdout. Use --write to overwrite the file in place, or --check to exit non-zero when there is a diff (for CI). --check and --write cannot be specified together.

Comments (// and /* */) are preserved. Top-level leading/trailing comments keep their position; comments inside a block keep their content but may be moved to the canonical position.

tdsl fmt [OPTIONS] <FILE>...
ArgumentDescription
<FILE>...Path(s) to input .tdsl file(s) or directories (directories are searched recursively for *.tdsl). Multiple allowed (v2.0.0+). Multi-input behavior is shared with check
OptionDescriptionDefault
--checkExit non-zero when formatting is needed (the file is left unchanged); for CI
--writeOverwrite the file with the formatted result
Terminal window
# Print the formatted result to stdout
tdsl fmt examples/china_dynasties.tdsl
# Overwrite the file
tdsl fmt examples/china_dynasties.tdsl --write
# Check for formatting diffs in CI (exits 1 if there is a diff)
tdsl fmt examples/china_dynasties.tdsl --check
# Recursively check a directory
tdsl fmt examples --check

Runs a quality check on a .tdsl file and applies automatic fixes for fixable issues with --fix.

tdsl lint [OPTIONS] <FILE>...
ArgumentDescription
<FILE>...Path(s) to input .tdsl file(s) or directories (directories are searched recursively for *.tdsl). Multiple allowed (v2.0.0+). Multi-input behavior is shared with check
OptionDescriptionDefault
--fixApply safe fixes directly to the file
--format <FORMAT>Output format (text / json)text
Terminal window
# Lint check only
tdsl lint examples/china_dynasties.tdsl
# Apply automatic fixes
tdsl lint examples/china_dynasties.tdsl --fix
# JSON output for CI
tdsl lint examples/china_dynasties.tdsl --format json
# Recursively check a directory
tdsl lint examples

Fetches and displays the label, description, and properties of a Wikidata entity (given a QID). Use this to inspect an entity’s data before writing an import block.

tdsl fetch [OPTIONS] <QID>
ArgumentDescription
<QID>A Wikidata QID (e.g. Q7209)
OptionDescriptionDefault
-l, --lang <LANG>Language(s) to fetch labels for (comma-separated)ja,en
Terminal window
# Fetch information for the Han dynasty
tdsl fetch Q7209
# Fetch English and French labels
tdsl fetch Q7209 --lang en,fr

Searches for Wikidata entities by keyword and lists candidate QIDs. Use this to find a QID for use in import.

tdsl search [OPTIONS] <QUERY>
ArgumentDescription
<QUERY>Search query (e.g. "Han dynasty")
OptionDescriptionDefault
-l, --lang <LANG>Language to use for the Wikidata searchja
-n, --limit <LIMIT>Maximum number of results (1-50)10
--jsonOutput as JSON
Terminal window
# Search for "Han dynasty" in English
tdsl search "Han dynasty" --lang en
# Increase the result count
tdsl search "Han dynasty" --lang en --limit 20
# Get JSON output and pipe it to a script
tdsl search "samurai" --json | jq '.[] | .id'

Analyzes a Wikidata entity in detail and suggests a mapping strategy (which properties to use for start/end, etc.). Useful as a preliminary investigation before running scaffold.

tdsl inspect [OPTIONS] <QID>
ArgumentDescription
<QID>A Wikidata QID (e.g. Q7209)
OptionDescriptionDefault
-l, --lang <LANG>Fallback language(s) for labels (comma-separated)ja,en
--jsonOutput as JSON
Terminal window
# Analyze the Tokugawa Ieyasu entity
tdsl inspect Q7243
# Output as JSON for scripted processing
tdsl inspect Q7243 --json | jq '.suggestions'

Resolves a Wikipedia article URL to a Wikidata QID. Use this when you have found an article but don’t know its QID.

tdsl resolve [OPTIONS] <URL>
ArgumentDescription
<URL>A Wikipedia article URL
OptionDescriptionDefault
-l, --lang <LANG>Fallback language(s) for labels (comma-separated)ja,en
--jsonOutput as JSON
Terminal window
# Resolve a QID from an article URL
tdsl resolve "https://ja.wikipedia.org/wiki/%E6%BC%A2"
# Output as JSON
tdsl resolve "https://en.wikipedia.org/wiki/Han_dynasty" --json

Generates a .tdsl template from Wikidata entities. Specify the wikidata subcommand.

tdsl scaffold wikidata [OPTIONS] --qids <QIDS> --timeline <TIMELINE>
OptionDescriptionDefault
--qids <QIDS>Comma-separated list of QIDs (e.g. Q7183,Q7209) required
--timeline <TIMELINE>Display title of the timeline required
-o, --output <OUTPUT>Path to the output .tdsl filestdout
-l, --lang <LANG>Fallback language(s) for labels (comma-separated)ja,en
--target <TARGET>Mapping target strategy (auto / span / event / event-range)auto
--lane-mode <LANE_MODE>Lane assignment strategy (single / per-entity / by-kind)per-entity
--single-lane-label <LABEL>Shared lane label used when --lane-mode single項目
Terminal window
# Scaffold the Western Han and Eastern Han with automatic mapping (Wikidata integration)
tdsl scaffold wikidata \
--qids "Q7209,Q8209" \
--timeline "Han Dynasties" \
--output han_dynasties.tdsl
# Group all entities into a single lane
tdsl scaffold wikidata \
--qids "Q7209,Q8209" \
--timeline "Han Dynasties" \
--lane-mode single \
--single-lane-label "Dynasty"
# Force mapping as span
tdsl scaffold wikidata \
--qids "Q7183,Q7209,Q8209" \
--timeline "Han, Xin, and Eastern Han" \
--target span

Renders a .tdsl file to a standalone HTML / SVG / PNG / PDF timeline. See Commands for the basic usage.

tdsl render [OPTIONS] <FILE>
ArgumentDescription
<FILE>Path to the input .tdsl file

See Commands for --format / --dpi / --png-scale / --orientation / --grid / --show-event-labels / --lane-height / --layout-style / --show-legend / --watch / --show-table. See Styling for --theme / --custom-css.

OptionValueDefaultIntroducedDetails
-o, --output <OUTPUT>Path to the output filestdout
--format <FORMAT>html / svg / png / pdfhtml— (png/pdf since v1.10.0/v1.11.0)Commands
--scale <SCALE>Horizontal pixels per year2Below
--lane-height <LANE_HEIGHT>Height of each lane in pixels60Commands
--left-gutter <LEFT_GUTTER>Width of the left gutter for lane labels120Below
--top-margin <TOP_MARGIN>Top margin above the time axis40Below
--theme <THEME>default / dark / print / pasteldefaultStyling
--custom-css <CUSTOM_CSS>Path to a custom CSS file injected after the theme CSSStyling
--dpi <DPI>PNG output resolution (mutually exclusive with --png-scale)96Commands
--png-scale <PNG_SCALE>Fixed pixel scale for PNG output (mutually exclusive with --dpi)Commands
--interactiveEnable zoom, pan, search, legend, and detail panelsince v1.1.0Below
--color-map <COLOR_MAP>Tag-to-color mapping (e.g. war=#cc0000,dynasty=#3366cc)since v1.1.0Below
--orientation <ORIENTATION>horizontal / verticalhorizontalsince v1.13.0Commands
--grid <GRID>none / decade / year / monthnonesince v1.14.0Commands
--layout-style <LAYOUT_STYLE>timeline / group-bands / gantt / zigzagtimelineCommands
--watchRe-render automatically on file change (html/svg only)Commands
--show-tableAppend a table listing all itemsCommands
--show-event-labelsAlways draw labels near event dots/barsCommands
--pdf-size <SIZE>a4 / a3 / letter (--format pdf only)a4since v1.17.0Below
--pdf-landscapeOutput the PDF in landscape orientation (--format pdf only)since v1.17.0Below
--pdf-margin <MM>Paper margin in mm (--format pdf only)10since v1.17.0Below
--pdf-title <TITLE>Override the PDF document Title metadata (--format pdf only)timeline titlesince v1.17.0Below
--pdf-paginationSplit the item table across multiple pages (requires --show-table, --format pdf only)disabled (single page)since v1.27.0Below
--chart-pagination <N>Split the chart body into multiple pages by lane group, N lanes per page (requires --output, --format svg/pdf only)disabled (single page)since v1.28.0Below
--chart-pagination-range <N>Split the chart body into N pages along the time-range axis (requires --output, exclusive with --chart-pagination, --format svg/pdf only)disabled (single page)since v2.0.0Below

Adjust the layout dimensions of the timeline body. --scale controls the horizontal density (a larger value widens the pixels-per-year), --left-gutter sets the width of the lane label column, and --top-margin sets the top padding above the time axis ticks. Widen --left-gutter when long lane labels wrap.

Terminal window
# Widen to 4px per year and give long lane labels more room
tdsl render examples/china_dynasties.tdsl --scale 4 --left-gutter 160 --output china_wide.html

Generates interactive HTML with zoom, pan, item search, a legend, and a detail panel. Only meaningful with --format html (since v1.1.0).

In addition to the lane toggles, the legend panel shows a “Tags” section with a checkbox for each tag registered in color_map (declared in the timeline block, or overridden via --color-map) (since v2.0.0, all tags checked by default). Tag filtering uses OR semantics: an item is hidden when it has none of the checked tags. Unchecking all tags disables tag filtering entirely, showing all items again. Lane toggles and tag toggles combine with AND, so only items matching both conditions are shown. If color_map is not set, the Tags section is not rendered.

Terminal window
tdsl render examples/china_dynasties.tdsl --interactive --output china_interactive.html

Overrides the color_map declaration inside a timeline block from the CLI, mapping tags to colors (since v1.1.0). Provide a comma-separated list of tag=color.

Terminal window
tdsl render examples/china_dynasties.tdsl \
--color-map "dynasty=#4b7bec,war=#e74c3c" \
--output china.html

--pdf-size / --pdf-landscape / --pdf-margin / --pdf-title are only meaningful with --format pdf, and control the paper size, orientation, margin, and metadata title (since v1.17.0).

Terminal window
# A3 landscape, 15mm margin, and an explicit title
tdsl render examples/china_dynasties.tdsl \
--format pdf --pdf-size a3 --pdf-landscape --pdf-margin 15 --pdf-title "Chinese Dynasties" \
--output china_a3.pdf

--pdf-pagination is only meaningful together with --show-table, and splits the item table across as many pages as fit the paper size and margins (since v1.27.0). The first page remains the timeline body only (scaled down), and the table is split across subsequent pages. Specifying --pdf-pagination without --show-table is an error.

Terminal window
tdsl render examples/china_dynasties.tdsl \
--format pdf --show-table --pdf-pagination \
--output china_paginated.pdf

--chart-pagination <N> splits the chart body (the timeline itself) into multiple pages by lane group (since v1.28.0). Lanes are sorted by (order, id) and then chunked into groups of N. The time axis (meta.range) stays common across all pages, and since every item belongs to exactly one lane, spans / event ranges are never clipped at a page boundary.

With --format svg, output is split into multiple files named <stem>.pageN.<ext> (N zero-padded to the digit width of the total page count). Combined with --show-table, a dedicated table page listing the entire IR is appended after the chart pages (its footer is fixed at 1 / 1; splitting the table itself across multiple pages is not supported in SVG output).

With --format pdf, output is not split into separate files. Instead, a single PDF contains multiple pages in the order “chart pages (by lane group) → table pages”. With --show-table alone, the entire IR is appended as one unsplit table page; combined with --pdf-pagination, the existing row-splitting logic produces the table pages instead. Either way, table page footers count only the table pages, not the preceding chart pages.

--show-legend is drawn independently on each chart page, so the legend content can differ from page to page (each page’s legend reflects that page’s lanes and items — this is intentional).

--output is required (stdout cannot represent multiple files or pages), and --chart-pagination cannot be combined with --watch. If a lane group is split across a page boundary, a warning is printed to stderr, but the output is still generated (see Troubleshooting for details). The Playground runs entirely on WASM in the browser and does not expose tdsl-render’s pagination logic, so --chart-pagination cannot be reproduced there — use the CLI (tdsl render) instead.

Terminal window
# Split the timeline body into multiple SVG pages by lane group
# Produces china.page1.svg / china.page2.svg ...
tdsl render examples/china_dynasties.tdsl --format svg --chart-pagination 2 --output china.svg
# Split the timeline body into multiple PDF pages by lane group
# Produces a single china_chart.pdf with multiple pages (no table)
tdsl render examples/china_dynasties.tdsl --format pdf --chart-pagination 2 --output china_chart.pdf
# Combine chart pagination with table pagination (chart pages, then table pages)
tdsl render examples/china_dynasties.tdsl \
--format pdf --chart-pagination 2 --show-table --pdf-pagination \
--output china_full_paginated.pdf

--chart-pagination-range <N> splits the chart body (the timeline itself) into multiple pages along the time-range axis instead of by lane group (since v2.0.0). meta.range is divided into N contiguous, non-empty integer-year segments, and each segment is rendered as its own page. Unlike lane-group pagination, each page’s TimelineIr keeps every lane and item — only meta.range changes — so a span / event range that straddles a segment boundary is clipped by the existing clamping logic, with a continuation-marker glyph (a triangular role="img" graphic, supporting both horizontal and vertical writing modes) drawn at the clipped edge. As with the lane-boundary warning for --chart-pagination, a warning is also printed to stderr when any item crosses a boundary.

It is mutually exclusive with --chart-pagination (specifying both is an error). Use this flag instead when you want to split along the time-range axis rather than by lane group. It supports both --format svg (multiple files named <stem>.pageN.svg) and --format pdf (multiple pages in a single PDF), and the page-layout rules (table page placement and footer page counts when combined with --show-table / --pdf-pagination) are the same as --chart-pagination. --output is required, and it cannot be combined with --watch. As with --chart-pagination, this cannot be reproduced in the Playground — use the CLI (tdsl render) instead.

Terminal window
# Split the timeline body into multiple SVG pages along the time-range axis
# Produces china.page1.svg / china.page2.svg ...
tdsl render examples/china_dynasties.tdsl --format svg --chart-pagination-range 2 --output china.svg
# Split the timeline body into multiple PDF pages along the time-range axis
# Produces a single china_chart.pdf with multiple pages (no table)
tdsl render examples/china_dynasties.tdsl --format pdf --chart-pagination-range 2 --output china_chart.pdf

Generates a minimal .tdsl template for manual editing. Does not require a Wikidata connection.

tdsl init [OPTIONS]
OptionDescriptionDefault
-o, --output <OUTPUT>Path to the output .tdsl filestdout
--timeline <TIMELINE>Display title of the timeline新しい年表
--range-start <RANGE_START>Start year of the range0
--range-end <RANGE_END>End year of the range2000
--lanes <LANES>Lane labels (comma-separated, e.g. "kingdom,event,person")""
Terminal window
# Generate a minimal template (stdout)
tdsl init
# Save to a file and specify lanes
tdsl init \
--output my_timeline.tdsl \
--timeline "Fantasy World Timeline" \
--range-start 1000 \
--range-end 1500 \
--lanes "kingdom,event,person"

Reads timeline items from a CSV file and converts them into a .tdsl snippet. See Commands for the CSV column spec (header row, time literals, and the source/origin columns).

tdsl import-csv [OPTIONS] <CSV>
ArgumentDescription
<CSV>Path to the input CSV file (UTF-8, with a header row)
OptionDescriptionDefault
-o, --output <OUTPUT>Path to the output .tdsl snippetstdout
--append <APPEND>Append the generated items to an existing .tdsl file
Terminal window
# Convert CSV to a .tdsl snippet (stdout)
tdsl import-csv items.csv
# Save to a file
tdsl import-csv items.csv --output items_snippet.tdsl
# Append to an existing file
tdsl import-csv new_items.csv --append my_timeline.tdsl

Exports IR to CSV. Intended for round-tripping with import-csv; see Commands for the CSV column spec.

tdsl export-csv [OPTIONS] <FILE>
ArgumentDescription
<FILE>The input file: a .tdsl source (lowered to IR) or a .json file (IR loaded directly)
OptionDescriptionDefault
-o, --output <OUTPUT>Path to the output CSV filestdout
--offlineSkip Wikidata fetching (static items only); ignored for .json inputfalse
--no-cacheBypass the local cache and refetchfalse
--cache-ttl <SECONDS>Cache TTL in seconds; 0 disables caching86400
Terminal window
# Export .tdsl to CSV (stdout, static only)
tdsl export-csv my_timeline.tdsl --offline
# Save to a file
tdsl export-csv my_timeline.tdsl --offline --output items.csv
# Export from an IR JSON
tdsl build my_timeline.tdsl --offline --output ir.json
tdsl export-csv ir.json --output items.csv

Manages the local cache of Wikidata fetch results. Specify the status or clear subcommand.

tdsl cache <COMMAND>

Shows cache statistics (file count, total size, oldest/newest entry).

Terminal window
tdsl cache status

Deletes cache entries.

tdsl cache clear [OPTIONS]
OptionDescriptionDefault
--older-than <DAYS>Only delete entries older than this many days— (deletes all)
Terminal window
# Show cache statistics
tdsl cache status
# Delete all cache entries
tdsl cache clear
# Delete entries older than 7 days
tdsl cache clear --older-than 7

Generates a shell completion script for the specified shell. Add the generated script to your shell’s configuration to enable Tab completion for tdsl subcommands and options.

tdsl completions [OPTIONS] <SHELL>
ArgumentDescription
<SHELL>Target shell (bash / elvish / fish / powershell / zsh)
Terminal window
# Generate and install the bash completion script
tdsl completions bash >> ~/.bashrc
source ~/.bashrc
# Install the fish completion script
tdsl completions fish > ~/.config/fish/completions/tdsl.fish
# Install the zsh completion script
tdsl completions zsh > ~/.zfunc/_tdsl
echo 'fpath=(~/.zfunc $fpath)' >> ~/.zshrc
echo 'autoload -Uz compinit && compinit' >> ~/.zshrc
source ~/.zshrc

Starts the LSP (Language Server Protocol) server over stdio. Reads JSON-RPC 2.0 messages from stdin and writes responses to stdout.

tdsl lsp
FeatureDescription
textDocument/publishDiagnosticsReports parse errors, validation warnings, and static reference errors in real time
textDocument/didOpenRuns diagnostics when a document is opened
textDocument/didChangeRe-runs diagnostics on document change (full sync)
textDocument/didCloseClears diagnostics when a document is closed
textDocument/completionReturns DSL keyword completion candidates (context-free, all keywords)
textDocument/hoverlane ID → lane info / QID → cached entity info (offline) / time literal → precision and offset info (v1.27.0+)
textDocument/definitionJumps from a lane reference to its declaration
textDocument/codeActionOffers tdsl lint --fix-equivalent automatic fixes as quick fixes (full-text, offline)
textDocument/documentSymbolReturns a hierarchical symbol tree for timeline / lane / items
textDocument/referencesReturns all reference locations for a lane ID (includeDeclaration toggles the declaration)
textDocument/renameRenames a lane’s declaration and all references at once (explicit as <alias> only)
textDocument/prepareRenameValidates whether a rename target is renameable (rejects lanes without as)
textDocument/formattingReturns a full-text TextEdit that formats the DSL source to the canonical style

import / map / apply blocks are diagnosed via static analysis (offline, no network access), so entity resolution that requires Wikidata fetching is not performed. See Installation for editor setup (VS Code / Neovim / Helix) and detailed usage of each feature.

Terminal window
# Start the LSP server (blocks waiting on stdin)
tdsl lsp
# Sanity-check with a minimal JSON-RPC request (Content-Length header required)
echo -e 'Content-Length: 2\r\n\r\n{}' | tdsl lsp