Expanded the built-in llm package to expose the inference daemon's model profiles, tool-call helpers, protocol controls, and health to Jade programs. The package stays decoupled from the daemon — the Unix socket (~/.jade/llm.sock) is the only contract; jadelang implements the wire format itself, drift-guarded by a golden-bytes test
Added model profile introspection — llm.model() returns the active model name; llm.profile() returns the model's token/tool vocabulary (tool-call delimiters, name field, special-token spans) as a dict. Profiles are selected by the model name the daemon reports
Added tool-call helpers — llm.find_tool_call(text) returns the first tool call in a response as {name, args} (or nil); llm.find_tool_calls(text) returns all of them; llm.tool_grammar() returns the canonical tool-call GBNF. All resolve tool-call delimiters from the active model's profile, so they work across models. The canonical grammar is checked in at grammars/tool_call.gbnf
Added protocol controls — the wire request now carries keep_anchors (toggle via llm.keep_anchors(b), making tool-span boundaries observable in-band) and trust (prompt provenance), matching the daemon's request schema
Added daemon lifecycle — llm.health() returns a daemon health snapshot (status, model, model_loaded, uptime_secs, protocol_version) via a new health op and structured-JSON response frame
Improved type inference for values read out of a dict. A let-bound homogeneous dict literal now records its value type, so indexing it (d["k"]) infers that concrete type instead of Unknown. This lets the native (AOT) backend pick the right print/format codegen for, e.g., bool values stored in a dict; the VM is unaffected (it dispatches on runtime tags)
Fixed a regression in unary ! type inference. The v1.1.10 logical-operator fix typed every!expr as bool, which incorrectly accepted ! on a known non-bool operand such as !1 (this should be a TypeError). !x now short-circuits to bool only when the operand type is Unknown (e.g. !method_call(x) on an untyped value, where native codegen emits an i1); a known non-bool operand once again reports a TypeError. && and || are unaffected — they continue to yield bool whenever an operand is Unknown
Fixed a native build failure (LLVM verification error) when a function returns a logical expression with an untyped operand — !x, a && b, and a || b are now always typed as bool (matching the i1 codegen emits), even when an operand is Unknown such as a method call on an untyped parameter. Previously these inferred int, mismatching the generated function signature. Mirrors the earlier comparison-operator fix
Breaking: module-path imports now use :: as the separator instead of . — use std::math, from std::math use floor, use utils::math for [lib] libraries. The . form is no longer accepted in module-path position (. is reserved for field and method access on values); use std.math is now a parse error
Namespaced decorators also use :: — @tools::register instead of @tools.register
Quoted file-path imports (use "lib.jde" as lib) are unchanged
Added null as a third spelling of nil — nil, None, and null are interchangeable aliases for the same value; they compare equal and may be used as literals, default parameter values, and type annotations
Native code generation moved out of the jade binary — jade build now runs the language frontend (lex → parse → type-infer → typed IR) and hands the typed program to the build daemon over $HOME/.jade/build.sock, which performs import resolution, code generation, and linking. The in-process LLVM backend and the llvm Cargo feature were removed; jade env now reports build-daemon reachability instead of LLVM status
Stdlib package imports must now use dot notation — use std.math, use std.fs, etc.; string-literal forms (use "std/math") are now a compile-time error. Applies to both use and from … use forms
File-path imports now require an alias — use "lib.jde" as lib; bare string imports without as name are now a compile-time error
Native packages declared in jade.toml [native] now require an alias field specifying the global binding name
Fixed: functions exported from imported modules can now access stdlib packages the module imported (e.g. use std.fs in a module is visible when module functions are called in the parent scope)
Improved error messages — type errors now include the actual type of the offending value; heterogeneous array literals, nested function definitions, and non-string prompt struct fields each emit a dedicated error
Added std/sh package — execute shell commands from Jade via sh.exec, sh.run, and sh.output
Added std/json package — parse JSON strings into Jade values and serialize Jade values back to JSON with json.parse, json.stringify, and json.stringify_pretty
Added std/env package — read and write environment variables (env.get, env.set), inspect command-line arguments (env.args), and get the working directory (env.cwd)
Added std/random package — random number generation with random.int, random.float, random.choice, random.shuffle, and a seedable global RNG via random.seed
Added input(prompt?) built-in — reads a line from stdin; the optional prompt argument prints to stdout without a trailing newline before reading. Returns an empty string on EOF.
Added write(str) built-in — prints to stdout without a trailing newline and flushes immediately (complements print, which adds \n)
Fixed array mutation semantics — mutations to an array are now visible through all aliases (reference semantics); previously mutations did not propagate to other variables pointing at the same array
Added llm.set_max_tokens(n) via use "llm" — configure the maximum token limit for LLM inference at runtime
Extended LLVM native codegen: typed try/catch arms and struct method calls (obj.method(args)) now compile and run correctly in native binaries
Added official install script at https://jadelang.org/install.sh — detects OS and architecture, downloads the correct prebuilt binary, and installs to /usr/local/bin/jade
Added Windows prebuilt binary: jade-windows-x86_64.exe available from the GitHub Releases page
Updated documentation installation page to document the install script and Windows download path
Added try/catch/raise exception handling — raise any value as an exception, catch by struct type name or with a catch-all arm, nested try/catch blocks, built-in runtime errors (division by zero, type errors, etc.) are automatically catchable