Driver API
github.com/samchon/ttsc/packages/ttsc/driver is the Go façade plugin authors should call instead of building a tsgo Program themselves. Every shipped third-party-shaped consumer in this repo — every command under packages/ttsc/cmd/, packages/lint/linthost/host.go, packages/wasm/host/api.go, and the tests/projects/go-source-plugin* fixtures — uses it.
This page is the curated, plugin-relevant surface. For the raw shim path (custom checker pool, in-memory-only Program, no tsconfig.json), see AST & Checker → If you cannot use the driver.
Program lifecycle
import "github.com/samchon/ttsc/packages/ttsc/driver"
prog, parseDiags, err := driver.LoadProgram(cwd, "tsconfig.json", driver.LoadProgramOptions{
ForceEmit: false,
ForceNoEmit: false,
OutDir: "",
SourcePreamble: "",
})
if err != nil { /* parse-time failure */ }
if len(parseDiags) > 0 { /* tsconfig errors */ }
defer prog.Close() // releases the leased Checker back to the pool
for _, file := range prog.SourceFiles() { /* walk */ }
diags := prog.Diagnostics() // pre-deduped, pre-filtered
checker := prog.Checker // type-aware queriesLoadProgram:
- parses
tsconfig.json(relative paths resolve againstcwd). - applies
LoadProgramOptionsoverrides —ForceEmit/ForceNoEmitflip the emit decision;OutDiroverrides the parsedoutDir;SourcePreambleoverlays a JSDoc preamble before parsing (the seam@ttsc/banneruses). - builds the tsgo
Programthroughshim/compiler.NewProgramand leases a*shimchecker.Checkerfrom the pool. - returns a
*driver.Programcarrying the parsed config, the host, the FS, and the lease release function.
Program.SourceFiles() filters declaration files for you. Program.Diagnostics() runs GetDiagnosticsOfAnyProgram + SortAndDeduplicateDiagnostics and drops the unused-overload-signature noise that tsgo emits internally. Always defer prog.Close() — without it the checker pool fills up and subsequent loads stall.
Emit
// Build-stage: tsgo owns JS, d.ts, and source-map printing.
emitted, emitDiags, err := prog.EmitAllRaw(nil)
// Transform-stage: render per-file source through the printer to drive
// downstream callers (bundlers, in-memory transformers).
text := shimprinter.EmitSourceFile(printer, file)| Function | Use it when… |
|---|---|
EmitAllRaw | You want tsgo’s full output (JS, d.ts, source maps) with default write-file handling. |
EmitAll(rs, fn) | You want to layer a *RewriteSet over emit and intercept each write through fn. |
EmitFile(...) | You only need one file’s emit (rarely used outside the utility host). |
DefaultWriteFile | The default WriteFileFunc — writes through the program’s FS. Pass to EmitAll when you don’t need interception. |
For the transform subcommand, the host treats typescript[fileName] as opaque text — see Plugin protocol → Transform. Run a printer before placing AST-mutated source in the map.
Diagnostics
// Three-line canonical lint-style flow.
var diags []driver.Diagnostic
diags = append(diags, driver.NewLintDiagnostic(
file, start, end,
/*code*/ 9001, driver.SeverityError,
"[my-rule] explanation here",
))
driver.WritePrettyDiagnostics(os.Stderr, diags, cwd)
if driver.CountErrors(diags) > 0 { os.Exit(1) }| Symbol | Notes |
|---|---|
NewLintDiagnostic(file, pos, end, code, sev, msg) | Wraps the offset pair into a Diagnostic with the file’s path. |
Diagnostic | The struct the host’s renderer accepts. |
Severity + SeverityError / SeverityWarning | Constants the host’s exit-code logic understands. SeverityError fails the build; SeverityWarning prints with warning coloring but keeps the exit code at zero. |
CountErrors(diags []Diagnostic) int | Returns the number of diagnostics that should fail the build (every diagnostic except explicit warnings). |
WritePrettyDiagnostics(w io.Writer, diags, cwd) | Renders to w using the same colorful format ttsc itself uses. No return value. |
Rewrites
rs := driver.NewRewriteSet()
rs.Add(driver.Rewrite{
File: file, // *ast.SourceFile from prog.SourceFiles()
RootName: "console",
Method: "log",
Replacement: "/* console.log */",
})
prog.EmitAll(rs, driver.DefaultWriteFile)RewriteSet is the path the engine uses to splice replacements over plugin-owned call expressions in the emitted JavaScript text. Pair with EmitAll; pass DefaultWriteFile unless you need to intercept. The RewriteSentinel constant (/* @ttsc-rewritten */) is the idempotency marker inserted at the top of a patched file so re-emitting an already-rewritten file is a no-op.
Source preambles
text = driver.ApplySourcePreamble(text, "/* @license MIT */")ApplySourcePreamble keeps a BOM or hashbang at the physical start of the file while inserting generated text after it. @ttsc/banner computes the preamble through driver.SourcePreamblePlugin; the generic host applies it when source text or declaration output needs the banner.
Linked Plugins
Non-main transform packages register with the driver instead of owning a process:
func init() {
driver.RegisterPlugin(plugin{})
}
type plugin struct{}
func (plugin) ApplyProgram(prog *driver.Program, ctx driver.PluginContext) error {
// mutate prog.SourceFiles()
return nil
}Implement SourcePreamble(ctx) when the plugin needs text before parsing, and ApplyProgram(prog, ctx) when it mutates the loaded Program. ctx.Entry.Config is the original compilerOptions.plugins[] object for this linked entry.
Hosting ttscserver
These symbols are for embedders of ttscserver, not for plugin authors. Skip this section unless you are building a ttsc-aware editor extension.
ttscserver is a process wrapper around the project-selected tsgo --lsp --stdio binary. Resolve @typescript/native-preview in the user project, pass its absolute executable path as TsgoBinary, and keep plugin diagnostics/code actions in your PluginSource.
err := driver.RunLSPServer(context.Background(), driver.LSPServerOptions{
In: os.Stdin,
Out: os.Stdout,
Err: os.Stderr,
Cwd: projectRoot,
TsgoBinary: tsgoBinary,
Source: source, // your driver.PluginSource impl
})| Symbol | Purpose |
|---|---|
PluginSource interface, NullPluginSource | The seam downstream pipelines implement to feed ttsc plugins into the LSP. |
RunLSPServer, LSPServerOptions, ErrCommandNotHandled | Host-side entry points. |
LSPDocumentVersion, LSPDiagnostic, LSPCodeAction, LSPRange, LSPWorkspaceEdit | Wire types in the LSP envelope. |
DenyNpmInstall remains for older in-process embedders, but the shipped ttscserver no longer embeds tsgo and cannot override tsgo’s internal ATA callback.
Lower-level helpers
Use when LoadProgram’s defaults don’t fit.
| Symbol | Notes |
|---|---|
DefaultFS() | The OS-backed VFS wrapped with the bundled library files. |
DefaultHost(cwd, fs) | A tsgo compiler host pre-wired with the FS and the bundled lib.*.d.ts paths. |
ParseTSConfig(path, host) | Parses a tsconfig.json without building a Program. |
CreateProgramFromConfig(...) | Builds a Program from a parsed config without going through LoadProgram’s convenience overrides. |
Stability
The driver surface is the closest thing ttsc has to a stable plugin SDK. Symbols listed here have Go doc-comments and are exercised by the in-repo test suite on every CI run. Lower-level shim symbols may move between releases; the driver insulates plugin authors from that churn. When you must reach below the driver, see AST & Checker for the supported escape hatches.