Skip to content

Releases: xuanheng-tech/context-loader

v1.3.9

Choose a tag to compare

@github-actions github-actions released this 19 Oct 03:17
  • Collect bare-repository and worktree-root facts in one bounded Git query, preserving literal
    path bytes, canonical-root validation and the shared deadline. Cover unborn, linked and bare
    repositories, nested paths, whitespace, newlines and undecodable filesystem names.
  • Fetch the public release tag into FETCH_HEAD for Gitea synchronization, preserving checkout's
    local tag ref and requiring the exact public tag object remotely. Report fixed, credential-safe
    failure categories and cover repeat synchronization and conflicting annotated objects.
  • Extend the opt-in benchmark with warm-ups, all three formats, individual samples and a read-only
    real-repository case whose timing files remain in scratch. Record a measured 1.3.8 baseline.

Package: https://pypi.org/project/context-loader/1.3.9/

Source commit: 28b87405f300ff43bf2ff27e4cbec1d28b8c29c0

v1.3.8

Choose a tag to compare

@github-actions github-actions released this 18 Oct 22:48
  • Check nested AGENTS depth and directory budgets before opening children. Count failed opens
    against the 2,000-directory budget and stop opening siblings once it is exhausted.
  • Report directory entries whose type cannot be determined as unreadable, rather than ordinary
    files. Preserve explicit unknown/incomplete observations in both machine formats.
  • Skip the unused nested-instruction presence scan for Markdown CLI calls. Machine formats and
    default application calls retain the scan; an explicitly skipped scan remains marked incomplete.
  • Parse bounded Git status output incrementally and retain only the first 100 changes sorted by
    raw path bytes. Validate records beyond that prefix and preserve output limits, shared deadlines,
    dirty-state semantics and truncation statuses.
  • Move pure AGENTS selection and its byte-budgeted audit into context_loader/agents.py, sharing
    it with collection and rendering while preserving existing collection imports and output contracts.
  • Document compact JSON as the preferred model input when separate source bodies are unnecessary.

Package: https://pypi.org/project/context-loader/1.3.8/

Source commit: 640e5b94fde78b5e8f96dcaafb225c82dc566070

v1.3.7

Choose a tag to compare

@github-actions github-actions released this 10 Oct 19:12
  • Select a section when two distinct focus terms match its body even without a heading match.
    Preserve heading priority, single-term false-positive controls, parent context and byte budgets.
  • Ignore the generic research path component when ranking sections, while retaining explicit
    research focus and specific path signals, to avoid unrelated notebook rules in research packages.
  • Add regressions for body-only English, Han and abbreviation queries, duplicate and split terms,
    ranking and budget fallback. Extend offline installed-wheel acceptance across ordinary and linked
    worktrees and all three output formats; document literal matching and omitted-rule recovery.

Package: https://pypi.org/project/context-loader/1.3.7/

Source commit: a3ea77e15c20e7fae0cb197174c8c4110b6c1282

v1.3.6

Choose a tag to compare

@github-actions github-actions released this 10 Oct 18:22
  • Select late AGENTS sections using two-character Han focus/path terms and common two-letter
    technical abbreviations. Han terms match inside entirely Han words; Latin abbreviations retain
    complete-token matching. Repeated heading/body matches count each query term once.
  • Add regression coverage for Chinese titles, fullwidth/case-normalized abbreviations, path
    components, section bodies, false positives, deterministic ranking and budget-fallback indexing.
  • Extend offline installed-wheel acceptance with Chinese and abbreviation selection in ordinary
    and linked worktrees across Markdown and both existing JSON schemas; retain byte budgets and
    zero runtime dependencies.

Package: https://pypi.org/project/context-loader/1.3.6/

Source commit: ff4707ea438b56fe07e74c642c8c753c189b7c9f

v1.3.5

Choose a tag to compare

@github-actions github-actions released this 10 Oct 17:38
  • Apply one shared 30-second Git collection deadline across discovery, refs, configuration and
    submodule preflight, status and history. Process creation consumes the budget; expiry stops later
    commands and preserves safe errors, empty stdout and child termination/reaping.
  • Extend installed-wheel acceptance with long multi-module instructions in ordinary and linked
    worktrees, checking focus/path selection, budget-fallback indexing, explicit truncation and
    nested-instruction presence without loading nested bodies.
  • Preserve CLI/schema contracts; verify unchanged context and source selection on real repository
    inputs.

Package: https://pypi.org/project/context-loader/1.3.5/

Source commit: 5b06d216b475b0cde98fb2025e5950f2992afd02

v1.3.4

Choose a tag to compare

@github-actions github-actions released this 10 Oct 17:01
  • Support Python 3.12–3.14 after installed-wheel and full-suite validation on 3.12.13, 3.13.13 and
    3.14.5; maintain the range with a GitHub CI matrix and preserve the existing CLI/schema contracts.
  • Add an opt-in synthetic performance baseline for long instructions, large directory listings
    and large working-tree status, reporting elapsed time, peak RSS and output bytes.
  • Add offline installed-wheel acceptance to the shared quality gate, covering all output formats,
    deterministic projections, linked worktrees and filter/argument failures outside the checkout.
  • Verify Git deadlines with real bounded child processes, including streaming and closed stdout,
    and assert process termination/reaping plus the CLI's empty-output failure contract.
  • Fix root-runner CI after dropping privileges: prepare Python 3.12.13 and the uv cache in
    runner-owned storage, transfer their ownership with the checkout, and remove duplicate
    Gitea Python installation steps. The test user never needs access to /root.
  • Preserve both existing proxy bypass lists when enabling direct public release reads.
    HTTP transport failures name the method and service without exposing URLs or diagnostics.
  • Preserve wildcard proxy bypasses and bound transport retries for public HTTPS GET reads.
    Transport failures in API writes still stop for outcome verification.

Package: https://pypi.org/project/context-loader/1.3.4/

Source commit: 183ff13d1fc38fdc50a8ea2fa12e459750ef4970

v1.3.3

Choose a tag to compare

@github-actions github-actions released this 10 Oct 14:16
  • Refuse status inspection when effective root/submodule config enables executable Git
    clean/process filters, and disable Git protocols to prevent lazy network reads.

  • Preserve distinct escaped filesystem names (including literal escape sequences and
    undecodable bytes) and deduplicate unreadable directory observations by their raw paths.

  • Charge truncation markers to the aggregate entry-file budget and share rendered source
    bodies between Markdown and JSON instead of calculating them twice.

  • Admit AGENTS sections using incremental byte/character/audit costs; build the complete
    selection/index only once. Document directory caps as retention/classification bounds,
    since deterministic alphabetical selection still scans names. Stop on the first name
    beyond 65,536 entries and discard that directory's partial prefix with an explicit status.

  • Isolate test Git routing/configuration from the caller. Use public PyPI lockfile URLs,
    self-contained Renovate settings and a shared CI check that supports non-root runners
    and a configurable account for root containers.

  • Release control: identify the failing Git operation without echoing arguments or diagnostics.
    Retry only transient reads of the public GitHub repository, at most three attempts with a
    60-second timeout each; permissions, identity conflicts and pushes stop immediately.

Package: https://pypi.org/project/context-loader/1.3.3/

Source commit: cd9c0a6a0571797a1cd2aa8370a14fb2bc729401

v1.3.2

Choose a tag to compare

@github-actions github-actions released this 29 Sep 07:29
  • Preserve private Just recipes across stacked attributes, recognize literal Make targets
    with double-colon rules and inline recipes, and reject duplicate value options before collection.

  • Refuse conflicting or duplicate annotated-tag headers before release identity checks.

  • Ignore local Qoder sessions and release build output at repository level for isolated Git audits.

  • Docs: tighten the release-notes claims that a post-release audit could not reproduce from the
    published artifacts. The 1.3.1 "Preserve" note is exact only for Markdown: --format json and
    --format json-compact embed tool.version, so their bytes differ from 1.3.0 by that one string,
    while every remaining field — including each real repository's nested_context path list —
    matched 1.3.0 byte for byte (measured on seven repositories). Two README sentences that described
    the document key set and the version renumbering relative to 1.2.0 are restated version-neutrally,
    since a reader of 1.3.1 cannot resolve "now" or "below" from the shipped text.

  • Fixed: a skipped or absent root source reports the machine code of the condition the collector
    observed, taken from that condition itself, instead of a code looked up from the sentence shown in
    context. The lookup matched only the exact wording in use, so any reworded or newly added
    sentence fell through to skipped_unreadable and --format json / --format json-compact could
    report an unrelated condition as an unreadable file with nothing anywhere indicating the mistake.
    The five codes (not_present, skipped_symlink, skipped_not_regular, skipped_encoding,
    skipped_unreadable) and the Markdown sentences are unchanged for every repository that collects
    today.

  • Fixed: a truncated source status is no longer derived by searching the rendered body for the
    truncation marker. A source whose own text quotes that marker was reported as truncated; only a
    budget that actually shortened the body now claims it.

  • Changed: the directory tree lists each directory's own entries before descending into any of its
    subdirectories, so a repository's top-level files are no longer displaced by deep content. In any
    worktree whose listing includes a subdirectory entry and that subdirectory's own contents, the
    lines after that entry appear in a different order than in 1.3.1, which changes the
    ## Directory Tree body inside context and therefore context_sha256. The tree's budgets
    (12 KiB of listing body, 300 entries, depth 2), the meaning of truncated, the entry kinds and
    every JSON key are unchanged.

  • Added: directory enumeration is capped per directory — 512 entries for the tree, 1,024 for the
    nested AGENTS.md presence scan — and the retained entries are the alphabetically first names, so
    a single huge directory is no longer materialised whole and a capped listing does not depend on
    operating-system enumeration order. Each scan keeps its own budget and its own truncation signal.
    Capped tree directories are reported by exactly one Listing incomplete: line carrying the total
    count, the limit that was applied and up to three example names, and by at most eight
    directory_listing_incomplete statuses entries naming individual directories plus one aggregate
    entry giving the totals when more were capped than are named individually; a capped directory
    beyond the retained examples is counted rather than silently dropped, counting the capped
    directories the listing reached: a directory is reached only when its parent offered it inside that
    parent's own alphabetical prefix and kept it, so capped siblings displaced by the entry budget are
    disclosed through their parent's truncation rather than as separate numbers. Previously each capped directory
    produced its own unbounded note outside any budget. Measured on a freshly built repository of
    exactly 120 directories cap000 to cap119, each holding the 513 empty files item000 to
    item512, committed with GIT_AUTHOR_DATE and GIT_COMMITTER_DATE both
    2020-01-01T00:00:00+0000 and no other entries -- the section is 4,551 bytes on 1.3.1 with no
    incompleteness note or status at all, 17,998 bytes on 7562d86 with 120 notes, which is 5,710
    bytes past the 12 KiB it documents, and 4,132 bytes here with one note. The listing body is the
    same 3,687 bytes on 7562d86 and here, so bounding the note cost no entries, while the section
    dropped by 13,866 bytes. tests/test_directory_tree.py machine-checks the invariants on a
    reduced form of this shape -- one note, a bounded status count, a section inside its budget and a
    reconciled total -- not these absolute byte counts, which depend on the name widths above.
    The note is charged against the 12 KiB listing budget before the body is
    cut, so the claim cannot inflate the section; where the note is long it is paid for in listing
    bytes, and the marker plus truncated say so. The heading and fence lines remain unmetered, as
    they were in 1.3.1. Internal counting and deduplication use the raw directory
    path and the aggregate carries an explicit identity, because display escaping is not injective: a
    directory named ` and one named \x60 render identically and must stay two facts. A
    directory above the nested-scan cap sets the existing scan_truncated flag and
    nested_agents_scan_truncated status. No JSON key set changes, so schema_version stays 3/4.

  • Added: when a directory's own entries no longer fit the tree item budget, its subdirectories and
    its non-directories each keep a share of it, so alphabetically-earlier directories cannot crowd
    out a root README.md entirely. The precondition is now stated exactly, and it is three limits
    rather than two: the enumeration must have offered the name, the 300-entry budget must still have
    a slot, and the 12 KiB listing budget must still have room to render the line. Being offered is
    not the same as an uncapped root -- the 512-entry cut drops only the names sorting after its
    retained prefix, so a README.md that sorts early is still listed from a capped root. Any one of
    them can drop a name on its own, so the tool promises no specific file; where a
    limit bites the listing reports the count, the cap and its retained examples instead of
    implying completeness.

  • Fixed: a directory tree shortened by its own 12 KiB render budget is now reported in the machine
    formats. The renderer kept that fact to itself, so context carried the truncation marker while
    statuses stayed silent: measured on a repository of 297 root files with 41-character names, 298
    entries were collected and passed the 300-entry item budget, the 12 KiB body budget published 292
    of them, and 1.3.1 emitted no tree status at all for that cut. truncated/tree/Directory Tree is
    now reported for a render-budget cut as well as for a collection cut. context and
    context_sha256 are byte-identical to 1.3.1 on that fixture and no JSON key changed; the gap
    predates 1.3.1 and is on a path this change touches, so it is fixed here rather than left to
    documentation.

  • Changed: the shared limits and frozen value types move to context_loader/model.py and the safe,
    bounded filesystem primitives to context_loader/filesystem.py; collect.py keeps collection
    policy, render.py derives display text from the typed reason, and no output changes from the move
    itself.

Package: https://pypi.org/project/context-loader/1.3.2/

Source commit: c705cc45c432b1359d9b740f3f34238766a79960

v1.3.1

Choose a tag to compare

@github-actions github-actions released this 24 Sep 10:47
  • Fixed: the nested AGENTS.md path report budget is metered on each path's final serializable
    representation — escaped with the same display escaping the document emits, then measured as the
    JSON string bytes actually written, including quoting, the array separator and, for the first
    entry, the array's own brackets — instead of on pre-escape path bytes. Escape-dense names
    (backticks, undecodable byte sequences) could previously make the emitted nested_context.files
    carry several times the documented 4 KiB; because quoting is now counted, an array whose total is
    already near 4 KiB can also admit one entry fewer even with ordinary names. Both are value changes
    in that one field and in the two signals derived from it — list_truncated can become true and the
    nested_agents_list_truncated status can appear where 1.3.0 reported neither — while no key set
    changes, so schema_version stays 3/4 and list_truncated keeps its meaning.
  • Added: --format json and --format json-compact enforce a bound on the final serialized
    document (8,388,608 bytes including the trailing newline). The bound is fail-closed: an
    over-budget repository exits 1 with an empty stdout and a one-line diagnostic rather than emitting
    a document the declared contract cannot describe. It is a backstop, not an expected truncation
    point: the component budgets cap the rendered context at 98,304 Markdown bytes and the repeated
    source bodies at 56 KiB before escaping, the nested path list at 4 KiB after escaping, and
    statuses at the 300-entry directory tree and 100 working-tree changes — the worst audited
    escape-dense repository measured 248 KiB of escaped subjects and 263 KiB for the whole document,
    so no run that succeeds today starts failing from this bound.
  • Docs: "Limits" now states a per-format final bound (Markdown 98,304 bytes; JSON and
    JSON-compact 8 MiB serialized document) instead of one figure that only described Markdown, since
    the machine formats legitimately carry the rendered context plus a second copy of every source
    body and cannot share the Markdown cap. The same section now states the remaining asymmetry this
    audit exposed and a new test pins it: nested_context paths and statuses subjects are escaped,
    while repository and sources[*].path are emitted verbatim, so a repository root containing
    bytes the filesystem could not decode renders as Markdown but makes --format json and
    --format json-compact exit 1. Escaping those two fields is a separate published-value change
    with its own consumer impact, so it is deliberately not folded into this budget correction.
  • Preserve: Markdown bytes, the default format, every flag and exit code other than the new
    over-budget JSON case, schema_version 3 and 4, contract_version 3, the collection scope and the
    Authority Boundary are unchanged; on ordinary repositories all three formats produce the same
    bytes as 1.3.0.

Package: https://pypi.org/project/context-loader/1.3.1/

Source commit: aab62912762864c9761d04551cd1b97bbb721bf8

v1.3.0

Choose a tag to compare

@github-actions github-actions released this 23 Sep 17:31
  • Changed: because the new top-level nested_context key changes the exact document shape, the JSON
    document schema version advances — --format json now emits schema_version 3 (was 1) and
    --format json-compact emits 4 (was 2). Versions 1 and 2 stay bound to the shapes already
    published in release 1.2.0 and are never reused, so each schema_version names exactly
    one key set; the compact document remains the full document minus sources[*].content.
  • Added: JSON documents (--format json and --format json-compact) include an always-present
    existence-only nested_context object listing non-directory nested AGENTS.md relative paths
    found by a contents-blind bounded scan (depth 4 and 2,000-directory scan bounds, 32-path and
    4-KiB report caps; symlinked entries listed without ever resolving or reading their targets;
    .git, .venv, venv, node_modules and site-packages trees skipped), with
    list_truncated/scan_truncated flags mirrored as nested_agents_list_truncated and
    nested_agents_scan_truncated statuses. Listed paths are sanitized with the same escaping the
    Markdown uses for repository-derived text, which also fixes a pre-existing crash class: an
    unreadable non-UTF-8 directory name no longer breaks --format json through a raw status
    subject. Root-file selection, Authority Boundary semantics and
    Markdown bytes are otherwise unchanged; presence is not instruction and nested contents are
    never read or transported.
  • Docs: the json-compact section states that sources is provenance/index metadata whose bodies
    already occur verbatim in context, so consumers must not reopen source files to recover a body
    the document already carried.
  • Changed: tool_cli_contract.json advances tool_version to 1.3.0 while contract_version stays
    3: this release changes the JSON document shape — governed by the output schema_version values 3
    and 4 — and no command, flag, format choice or precondition, mirroring the 1.1.0 precedent where a
    document-shape addition left the public CLI contract version alone.

Package: https://pypi.org/project/context-loader/1.3.0/

Source commit: 14ce181c5a0a290d4eafe230f15a1c9e798c84aa