Skip to content

v0.4.0

Latest

Choose a tag to compare

@github-actions github-actions released this 31 Jul 12:00
· 13 commits to main since this release
0f4eea8

ctx 0.4.0

Added

  • ctx lsp command group for community-registry LSP management: ctx lsp add <language> installs a curated [lsp.<language>] entry into
    .ctx/config.toml after confirmation (--yes/-y for non-interactive use,
    --server <NAME> to override the recommended server), ctx lsp list
    shows configured servers (--available lists the registry), ctx lsp update refreshes entries carrying source = "registry" provenance with a
    per-key diff while preserving user-added keys (timeout_ms, env, ...),
    and ctx lsp doctor health-checks every configured server (PATH lookup,
    initialize handshake, capability diff; a malformed config file or invalid
    [lsp.*] blocks are reported as failures; exit 1 on failures). All four
    support the global --json flag.
  • Pluggable LSP extraction backend: any stdio language server can be registered
    declaratively under [lsp.<language>] in .ctx/config.toml, with per-language
    backend selection (tree-sitter (default) / lsp / hybrid), lazy server
    startup, cross-file reference resolution via textDocument/definition, a
    .ctx/lsp_status.json run sidecar, and graceful fallback to tree-sitter —
    server failures never fail an indexing run.
  • Rust indexing now records statically resolvable bare or module-qualified free functions passed as
    callback values (such as spawn(worker::run_main) and .map(transform)) as uses relationships
    without treating them as calls (#62). A reference resolves only when exactly one Rust free
    function matches; references that stay unresolved are discarded rather than kept as unverified
    evidence, because nothing in the syntax distinguishes a function value from a constant or unit
    variant in the same position.
  • Added full Zig .zig indexing across symbols, calls, literal imports, architecture checks,
    watch mode, context selection, and normalized duplicate detection. .zon remains unparsed
    context content.
  • Added full C and C++ indexing across conventional source/header extensions, dual-grammar
    .h classification, symbols, calls, includes, architecture checks, watch mode, context
    selection, source retrieval, and normalized duplicate detection.

Fixed

  • Made ctx diff and ctx review token-budget selection deterministic by ordering equally ranked
    files by repository-relative path before greedy packing (#60).
  • Global --count-only, --encoding, and --stats now apply to ctx smart and ctx diff;
    counts cover only the files selected by the requested token budget, and summaries remain on stderr (#59).
  • BREAKING: Caller lookup now reports only resolved calls edges to the selected symbol, while
    preserving conservative same-language unresolved evidence in a separate section instead of mixing
    in cross-language or same-name false positives (#61). The documented callers JSON array narrows
    in meaning: entries that previously appeared through bare name matching now surface under
    unresolved_callers or not at all, so consumers reading callers see fewer, higher-confidence
    entries than before.
  • BREAKING: ctx query callers and ctx query deps now honor --depth with cycle-safe
    breadth-first traversal, shortest-distance identity deduplication, explicit JSON distances, and
    distance-grouped human output while keeping unresolved relationships as non-recursive evidence
    leaves (#58). --depth was previously parsed and discarded, so both commands returned direct
    relationships only. The documented default of 3 now takes effect: existing invocations that pass
    no flags return transitive results grouped under new Distance N: headings, where they
    previously returned direct relationships. Pass --depth 1 to retain the old output.
  • BREAKING: ctx query impact --json now reports indexed qualified names and source line ranges
    while keeping same-named symbols distinct by identity (#63). line_start and line_end were
    previously always 0 and qualified_name always null; both now carry real indexed values.
    Consumers that treated 0 as "no location" must read the value rather than the sentinel.
  • BREAKING: ctx index now honors positional file patterns and paths (ctx index src,
    ctx index src/**), scoping the index exactly like -p/--pattern (AGE-13). Previously the
    positional arguments were accepted but silently ignored, so the whole repository was
    indexed at full cost. The indexing banner now echoes the effective scope
    (Indexing codebase (scoped to: src)...) and file discovery warns when include
    patterns match no files. ctx index now also refuses to update the index when an
    explicit scope matches nothing: a mistyped -p pattern previously exited 0 and silently
    emptied an existing index, and now exits non-zero leaving the index untouched. Scripts
    that relied on an empty scope succeeding must handle the new failure.
  • Positional file, directory, and glob patterns now scope ctx smart, ctx similar, and ctx diff
    as advertised, including semantic seeds, graph expansion, and renamed or deleted diff paths (#57).
    A scope that matches no changed files reports an empty result and warns, rather than failing as an
    operational error.
  • BREAKING: ctx explain now separates calls from other relationships for every language, not only
    Rust (#62). Calls (N) previously counted and listed every outgoing edge, so an import or a trait
    implementation was reported under a heading that said "Calls"; extends, implements, imports,
    and uses edges now appear under a new Relationships (N) section and Calls (N) counts calls
    alone. The documented callers_count JSON field narrows in the same way as ctx query callers
    (#61): it now counts only callers resolved by symbol identity, not bare name matches.
  • BREAKING: The index schema version is now 3 (#62). No table changed, but the Rust parser emits
    uses edges an older index does not contain, and content hashing would otherwise let unchanged
    files keep a stale edge set indefinitely. Existing indexes report the usual schema mismatch and
    are rebuilt with ctx index --force.
  • BREAKING: The public Language enum (re-exported in the crate prelude) is now
    #[non_exhaustive] so future language additions stay backward compatible for library
    consumers (#72). Code that uses ctx as a library and matches on Language exhaustively
    must add a wildcard arm. This is a Rust library-API change only: the CLI, its --help
    contract, and all JSON output are unchanged.

Documentation

  • Documented the pluggable LSP support: a ctx lsp command reference
    (docs/commands/lsp.md), an "Add a Language via LSP" guide covering manual
    [lsp.<language>] authoring, backend modes, fallback behavior, and
    troubleshooting (docs/lsp-languages.md), the full [lsp.<language>] key
    reference in docs/configuration.md, and the LSP path in
    docs/language-support.md — all mirrored to the documentation site.
  • Updated verified cookbook guidance for snapshot backfill coverage, semantic context completeness,
    harness regeneration after binary upgrades, and unresolved map focus behavior (#64).
  • Added symptom-first cookbook routing, per-recipe quick paths, canonical cross-cutting concepts,
    pinned worked-example provenance, and an authoring contract that preserves verified limitations.
  • Added verified recipes for fork-safe ctx analysis and recovery from disputed findings,
    operational gate failures, and stale indexes without weakening policy.
  • Expanded the downloadable ctx skill and llms.txt so agents can route directly from engineering
    symptoms to the complete cookbook workflow.
  • Started Cookbook v2 with a source-verified unfamiliar-codebase orientation workflow that distinguishes ranked structural leads from real entry points and documents static-analysis uncertainty.
  • Added a verified smallest-useful-context recipe that tests smart selection at multiple budgets, audits omitted consumers and contracts, and separates compact symbol investigation from complete implementation context.
  • Added a reuse-discovery recipe that compares semantic, signature-like, and keyword retrieval, traces matching primitives into their composed workflow, and verifies ownership semantics from tests before recommending reuse.
  • Added a blast-radius recipe that bounds graph traversal, verifies transitive relationships from source, supplements incomplete edges with exact contract search, and turns persisted, generated, public, and behavioral impact into a validation plan.
  • Added an evidence-backed implementation recipe that baselines the owning boundary, tests the compiled interface, refreshes contracts and code intelligence after editing, audits context omissions, and interprets structural deltas before completion.
  • Added a focused failing-test debugging recipe that reproduces the symptom, traces test dependencies into production code, compares neighboring behavior, and proves one causal correction with widening validation.
  • Added a large-branch review recipe that inventories the complete change, separates review streams, routes attention with scoped metrics, rejects false graph expansion, and verifies policy intent against enforcement and CI wiring.
  • Added an outcome-driven cookbook with a real ctx-on-ctx case study for capturing codebase-health snapshots in CI, normalizing longitudinal metrics, and investigating trends without treating high complexity or duplication as automatic defects.
  • Added a delta-focused pull-request governance recipe that separates informational metrics, human-review signals, explicit blocking policy, and safe analysis of fork contributions.
  • Added an architectural-drift recipe that combines reviewed dependency rules, pull-request scoping, longitudinal coupling signals, and policy-history interpretation.
  • Added a chronic-hotspots recipe that combines current churn-complexity rankings, normalized historical evidence, change history, and ownership-focused investigation.
  • Added an intentional-complexity recipe that separates fan-in from fan-out, tests responsibility coherence, and records why complex shared primitives, parsers, and dispatchers may remain intact.
  • Added a duplication-trajectory recipe that distinguishes current, changed-file, and newly introduced pairs while normalizing history and requiring ownership analysis before reuse.
  • Completed the first cookbook set with a release-health reporting workflow that combines immutable comparisons, provenance, normalized metrics, focused investigations, uncertainty, and owned actions.

Internal

  • Refreshed the root and performance-harness dependency locks together, including
    the bundled SQLite runtime, so both independently locked Cargo packages resolve
    the same reviewed dependency set.
  • Made the breaking-change policy gate reachable and enforced it by label.
    check-contracts.py pr-policy required a breaking-change label for removed CLI
    contracts, but no such label existed in the repository, so the requirement could
    never be satisfied. The BREAKING: changelog requirement now fires on the label
    itself rather than only on contract removal, since an exit-code or JSON-meaning
    change removes nothing yet still breaks. The matching version increase moved from
    the pull request to the release cut, where governance/releasing.md places it:
    acknowledged breaks accumulate under Unreleased, and version.py refuses to
    release them under an insufficient bump.
  • Exempted release-preparation pull requests from that gate's "add a - BREAKING:
    entry" requirement. A release relocates already-acknowledged BREAKING entries from
    Unreleased into the dated section rather than introducing new ones, so it adds no new
    marker line; the release side stays enforced by version.py's bump check. Without this,
    every release carrying accumulated breaks failed its own contract gate.
  • Made CI report its checks on every pull request so branch protection can require them. The
    workflow-level paths-ignore meant a docs-only pull request never ran CI, and a check that never
    runs never reports -- so any required check would have stayed pending forever and blocked the
    merge. Docs-only runs now skip the expensive jobs individually via a changes filter, which
    reports a skipped status that branch protection accepts.
  • Added an internal LSP registry client (lsp_registry) and a format-preserving
    .ctx/config.toml writer (config_edit) as groundwork for the future ctx lsp
    commands. Internal only: no CLI surface, config contract, or documented behavior
    changes yet.
  • Made the local CI and canonical plugin lockstep checks honor Cargo's configured target directory while validating the standalone downloadable ctx skill against its harness template.
  • Constrained fastembed to the last ONNX Runtime dependency line that still publishes Intel macOS
    binaries, and told Dependabot to leave it alone. The exact pin was there to hold ort-sys at
    2.0.0-rc.10, but a grouped dependency update rewrote the pin itself to fastembed 5.17.3, pulling
    ort-sys 2.0.0-rc.12 and breaking two release targets: no prebuilt ONNX Runtime exists for
    x86_64-apple-darwin, and the Linux prebuilt needs glibc >= 2.38 symbols the pinned ubuntu-22.04
    builder cannot link. --no-default-features does not avoid this, because fastembed is a required
    dependency.
  • Supplied the Debian source stanza required for release-package dependency discovery.