Repository navigation
Releases: xuanheng-tech/context-loader
Release list
v1.3.9
- 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_HEADfor 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
- 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
- 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
researchpath 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
- 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
- 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
- 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
-
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
-
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 jsonand
--format json-compactembedtool.version, so their bytes differ from 1.3.0 by that one string,
while every remaining field — including each real repository'snested_contextpath 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 toskipped_unreadableand--format json/--format json-compactcould
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
truncatedsource 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 Treebody insidecontextand thereforecontext_sha256. The tree's budgets
(12 KiB of listing body, 300 entries, depth 2), the meaning oftruncated, 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
nestedAGENTS.mdpresence 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 oneListing incomplete:line carrying the total
count, the limit that was applied and up to three example names, and by at most eight
directory_listing_incompletestatusesentries 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 directoriescap000tocap119, each holding the 513 empty filesitem000to
item512, committed withGIT_AUTHOR_DATEandGIT_COMMITTER_DATEboth
2020-01-01T00:00:00+0000and 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.pymachine-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 plustruncatedsay 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\x60render identically and must stay two facts. A
directory above the nested-scan cap sets the existingscan_truncatedflag and
nested_agents_scan_truncatedstatus. No JSON key set changes, soschema_versionstays 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 rootREADME.mdentirely. 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 aREADME.mdthat 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, socontextcarried the truncation marker while
statusesstayed 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 Treeis
now reported for a render-budget cut as well as for a collection cut.contextand
context_sha256are 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.pyand the safe,
bounded filesystem primitives tocontext_loader/filesystem.py;collect.pykeeps collection
policy,render.pyderives 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
- Fixed: the nested
AGENTS.mdpath 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 emittednested_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_truncatedcan become true and the
nested_agents_list_truncatedstatus can appear where 1.3.0 reported neither — while no key set
changes, soschema_versionstays 3/4 andlist_truncatedkeeps its meaning. - Added:
--format jsonand--format json-compactenforce 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 renderedcontextat 98,304 Markdown bytes and the repeated
source bodies at 56 KiB before escaping, the nested path list at 4 KiB after escaping, and
statusesat 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_contextpaths andstatusessubjects are escaped,
whilerepositoryandsources[*].pathare emitted verbatim, so a repository root containing
bytes the filesystem could not decode renders as Markdown but makes--format jsonand
--format json-compactexit 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_version3 and 4,contract_version3, 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
- Changed: because the new top-level
nested_contextkey changes the exact document shape, the JSON
document schema version advances —--format jsonnow emitsschema_version3(was1) and
--format json-compactemits4(was2). Versions1and2stay bound to the shapes already
published in release 1.2.0 and are never reused, so eachschema_versionnames exactly
one key set; the compact document remains the full document minussources[*].content. - Added: JSON documents (
--format jsonand--format json-compact) include an always-present
existence-onlynested_contextobject listing non-directory nestedAGENTS.mdrelative 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_modulesandsite-packagestrees skipped), with
list_truncated/scan_truncatedflags mirrored asnested_agents_list_truncatedand
nested_agents_scan_truncatedstatuses. 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 jsonthrough 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-compactsection states thatsourcesis provenance/index metadata whose bodies
already occur verbatim incontext, so consumers must not reopen source files to recover a body
the document already carried. - Changed:
tool_cli_contract.jsonadvancestool_versionto 1.3.0 whilecontract_versionstays
3: this release changes the JSON document shape — governed by the outputschema_versionvalues 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