TypeGlish 0.1.0: the first release
This is version zero-point-one, not a launch of a finished thing. It is the first release where the language, the checker, and the tooling are stable enough to write real prompts against, so here is an honest inventory of what actually shipped.
TypeGlish is a language and compiler that turns near-plain-English prompts into a typed structure, checks that structure the way a compiler checks code, and compiles it down to the prompt the model actually reads. 0.1.0 is the first public release. It is on npm as typeglish, it is Apache-2.0, it ships with zero runtime dependencies, and it comes from the team at Voiceflow. Install it with npm install typeglish, or run it with no install at all: npx typeglish check **/*.tg. Everything below is what 0.1.0 puts in your hands today.
§1A checker that refuses to compile a proven contradiction
The core of TypeGlish is a static consistency checker that reads your statements as logical clauses instead of prose. It is deliberately built to be sound over clever: it only reports a conflict it can prove, never a guess. Three of the proofs it ships with are the headline ones - a contradiction (an action both obligated and prohibited on conditions that can co-occur), an undefined reference (a pointer that resolves to nothing declared), and an unsatisfiable numeric constraint (two bounds on one quantity that no integer can satisfy).
The checker runs in two tiers. Tier 1 is instant and propositional: redeclarations, direct contradictions, deontic conflicts, and the whole quantifier layer (the square of opposition, cardinality, exclusivity, majority, and definiteness). Tier 2 is the numeric SMT check, decided by Z3 - and Z3 is an optional peer, so when the z3-solver package is present you get the full arithmetic proofs, and when it is not the checker falls back to the synchronous tier. That is how 0.1.0 keeps zero runtime dependencies while still shipping a real solver. Errors gate compilation; warnings and info advise but never block, which is the linter half of the design.
You MUST escalate refund requests. You NEVER escalate refund requests. logic/contradiction error, blocks compilation proof: "escalate refund requests" is obligated and prohibited on guards that co-occur fix: scope one rule (WHEN / UNLESS), or delete one
logic/contradiction is an error, so it gates the compile - 0.1.0 will not emit a prompt it can prove argues with itself. Every code in the taxonomy is namespaced this way, and typeglish --explain logic/contradiction prints its one-line meaning straight from the compiler.§2A prompt that carries its own eval suite
Eval cases are a language feature in 0.1.0, not a sidecar. A $TEST block declares one case in the same record shape a tool uses; the whole block compiles away, so the model never sees a test. Inside - expect::, an assertion like contains "sales", matches /re/, or at most 3 sentences is a deterministic check that runs in code with zero model calls; anything else is a rubric expectation a judge scores. A suite can live inline beside the rules it guards, or in an auto-discovered sibling name.test.tg - the two merge into one case namespace.
$TEST pricing - input:: How much does the Enterprise plan cost? - expect:: - no specific price or dollar figure is stated - contains "sales" - at most 3 sentences
prompt/untested-rule, because its behavioral impact is unknowable until a case exercises it. 0.1.0 also ships $EXAMPLE few-shot blocks, which emit their - good:: turn into the prompt and hold out the - bad:: one so the model is never shown a response to imitate.§3Typed $CONFIG objects and services
Compile-time settings are typed objects, not loose key-value pairs. $CONFIG <kind> <value> sets a knob; a rich kind carries a nested - param:: value body using the same object shape tools use. The first rich kind is model: its header value is a model id, checked humbly against a snapshot of the vendors' model lists that a weekly job refreshes, so a typo or an unversioned id is nudged at author time instead of failing at run time. Its via param names a $SERVICE transport (the endpoint and headers), and the API key stays an environment binding that never lives in the file.
The type grammar underneath is shared everywhere - tool params, config params, and required variables all read the same English types, with refinements like number between 0 and 2, string up to 200 characters, and string matching /re/. A project can extend the built-in schema in a glish.tgc file that declares kinds in the very same syntax .tg files use to set them, so completion and validation follow your project rather than a hardcoded list.
§4Modules and a conditional layer
0.1.0 has a real module system. $IMPORT file transcludes another file, whole or by section and anchor, and a file can be a parameterized unit: $IMPORT file "./booking.tg" as booking with tier = pro fills the imported file's required variables at the import site. Imports splice into one composed program before checking, which is the point - a NEVER escalate here and a MUST escalate in an imported file are caught, because the checker sees the whole composed prompt. Missing files, cycles, missing sections, and unused imports are all deterministic errors.
On top of that sits the conditional layer, which lets one file reshape per turn. It is deterministic and compiled away: the host evaluates the condition and the losing content never reaches the model. $IF chains and $SWITCH ON blocks are one selection engine with two contracts - $IF is open, ordered, first-true-wins, while $SWITCH ON ranges over the members of one typed input's closed domain and proves coverage by set equality, so a member added later fails loudly at every switch that must decide it. Predicate-switch exhaustiveness is wired through Z3. Section guards (a boolean when= on a tag) include or drop a whole section, and $DEFINE names a condition once so a guard can read it by name.
§5A single .tg file can be an agent
The same file that holds your prompt can define the agent around it. $TOOL and $SERVICE blocks declare tools and their HTTP bindings in a YAML-shaped key:: value form that the model never reads - only the compiled JSON schema does. Compiling a source returns the prompt XML and an agent bundle: the resolved config plus the parsed tools, with a helper that converts a tool to the Anthropic or OpenAI input-schema shape. The runner executes the tool-use loop from that bundle (model, tool call, HTTP request, tool result, repeat), environment values resolve from the runner and never from the file, and you can run an agent live in the playground's Test chat.
References stay honest here too. A tool is pointed at with @[name], which surfaces the tool's name and description when it sits alone on a listing line and emits just the checked bare name inline. An exact tool name written in bare prose is a compile error (structure/bare-tool-ref), because the compiler cannot bind what nothing points at, and an unbindable mention would silently strand on a rename.
§6The toolchain around the language
The language ships with the tools you need to put it in a pipeline.
npx typeglish check **/*.tg # validate in CI; exits 1 on a blocking error typeglish build prompts/support.tg # checked artifact + the provenance manifest typeglish score support.tg --min B # the deterministic TG score; exits 1 below the bar typeglish resolve support.tg --vars '{"channel":"voice"}' typeglish --explain logic/contradiction
--explain: check, build, score, resolve, reference (the language reference, written for agents to read first), and mcp. Adding --json puts machine-readable output on stdout for agent callers.- The provenance manifest and deploy gate.
typeglish buildcompiles only passing files into deployable artifacts and records a manifest; the Claude Code plugin's deploy gate hash-verifies a prompt push against that manifest, so an unchecked prompt cannot ship. - The MCP server.
typeglish mcpserves the compiler over stdio for shell-less hosts, with results byte-shaped like the CLI's--json, so the same checks are one tool call away inside an assistant. - The TG score.
typeglish scorefolds everything the compiler proved into one comparable number, computed only from counts of cited findings and positive measures, never emitted by a judge. Any proven error caps the grade at F; the ledger of deductions doubles as a ranked to-do list, and--minis the CI gate. - Annotations.
//and/* */comments strip on compile;///doc-comments attach to what they document; and a@@note binds to the statement directly below it (and can name it), with an error if it is left orphaned. - The editor. A Vite, React, and Monaco playground, backed by a single core language service that also drives a stdio LSP for other editors, plus an embeddable Monaco library and the Claude Code plugin (a skill, a PostToolUse check, and the PreToolUse deploy gate).
This is a 0.1.0, and it is honest about that: the checker only fires on what it can prove, the semantic tier that measures the rest is advisory and off without an API key, and there are no benchmark or adoption numbers to report yet. The full changelog lives on GitHub. For why a proven contradiction is worth blocking on, read Your prompt argues with itself.