context-loader 1.3.5__tar.gz → 1.3.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {context_loader-1.3.5 → context_loader-1.3.6}/PKG-INFO +20 -12
- {context_loader-1.3.5 → context_loader-1.3.6}/README.md +19 -11
- {context_loader-1.3.5 → context_loader-1.3.6}/context_loader/__init__.py +1 -1
- {context_loader-1.3.5 → context_loader-1.3.6}/context_loader/collect.py +33 -10
- {context_loader-1.3.5 → context_loader-1.3.6}/pyproject.toml +1 -1
- {context_loader-1.3.5 → context_loader-1.3.6}/pyproject.toml.orig +1 -1
- {context_loader-1.3.5 → context_loader-1.3.6}/tool_cli_contract.json +1 -1
- {context_loader-1.3.5 → context_loader-1.3.6}/LICENSE +0 -0
- {context_loader-1.3.5 → context_loader-1.3.6}/context_loader/application.py +0 -0
- {context_loader-1.3.5 → context_loader-1.3.6}/context_loader/cli.py +0 -0
- {context_loader-1.3.5 → context_loader-1.3.6}/context_loader/filesystem.py +0 -0
- {context_loader-1.3.5 → context_loader-1.3.6}/context_loader/git.py +0 -0
- {context_loader-1.3.5 → context_loader-1.3.6}/context_loader/model.py +0 -0
- {context_loader-1.3.5 → context_loader-1.3.6}/context_loader/render.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: context-loader
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.6
|
|
4
4
|
Summary: Render deterministic local Git context for any executor
|
|
5
5
|
License: Apache License
|
|
6
6
|
Version 2.0, January 2004
|
|
@@ -219,14 +219,14 @@ Python standard library.
|
|
|
219
219
|
|
|
220
220
|
## Open-source quick start
|
|
221
221
|
|
|
222
|
-
Current stable release: **1.3.
|
|
222
|
+
Current stable release: **1.3.6**. Local CLI for coding-agent workflows; renders deterministic Markdown or JSON.
|
|
223
223
|
|
|
224
224
|
```bash
|
|
225
|
-
uv tool install 'context-loader==1.3.
|
|
225
|
+
uv tool install 'context-loader==1.3.6'
|
|
226
226
|
```
|
|
227
227
|
|
|
228
228
|
```bash
|
|
229
|
-
pip install 'context-loader==1.3.
|
|
229
|
+
pip install 'context-loader==1.3.6'
|
|
230
230
|
```
|
|
231
231
|
|
|
232
232
|
```bash
|
|
@@ -239,21 +239,21 @@ project-context --repo /path/to/repo --format json
|
|
|
239
239
|
|
|
240
240
|
## Install
|
|
241
241
|
|
|
242
|
-
Source version: `1.3.
|
|
242
|
+
Source version: `1.3.6`. Install its matching published release or an exact source commit.
|
|
243
243
|
|
|
244
244
|
Install via `uv`:
|
|
245
245
|
|
|
246
246
|
```bash
|
|
247
|
-
uv tool install 'context-loader==1.3.
|
|
247
|
+
uv tool install 'context-loader==1.3.6'
|
|
248
248
|
```
|
|
249
249
|
|
|
250
250
|
Install via `pip`:
|
|
251
251
|
|
|
252
252
|
```bash
|
|
253
|
-
pip install 'context-loader==1.3.
|
|
253
|
+
pip install 'context-loader==1.3.6'
|
|
254
254
|
```
|
|
255
255
|
|
|
256
|
-
For development or source-based installs tracking current repository (`1.3.
|
|
256
|
+
For development or source-based installs tracking current repository (`1.3.6`):
|
|
257
257
|
|
|
258
258
|
```bash
|
|
259
259
|
uv tool install git+https://github.com/xuanheng-tech/context-loader.git
|
|
@@ -350,7 +350,7 @@ set differs, as described under “Compact model consumption”. The declared co
|
|
|
350
350
|
"schema_version": 3,
|
|
351
351
|
"tool": {
|
|
352
352
|
"name": "context-loader",
|
|
353
|
-
"version": "1.3.
|
|
353
|
+
"version": "1.3.6"
|
|
354
354
|
},
|
|
355
355
|
"repository": {
|
|
356
356
|
"requested_path": "/canonical/requested/path",
|
|
@@ -470,7 +470,7 @@ although 1.1.0 added the top-level `statuses` key. From release 1.2.0 onward eac
|
|
|
470
470
|
names exactly one key set, and a new number is issued whenever a key set would otherwise be reused.
|
|
471
471
|
|
|
472
472
|
The JSON schema version and package version are independent: this build emits `schema_version` `3`
|
|
473
|
-
for `--format json` and `4` for `--format json-compact`, while `tool.version` is `1.3.
|
|
473
|
+
for `--format json` and `4` for `--format json-compact`, while `tool.version` is `1.3.6`. Version 1
|
|
474
474
|
and 2 are the exact shapes already published in release 1.2.0 and are never reused: because
|
|
475
475
|
`nested_context` changes the default document's key set, version 3 names the current full-document
|
|
476
476
|
key set and version 4 names the compact projection.
|
|
@@ -512,12 +512,20 @@ heading on the first line is still recognized as a heading.
|
|
|
512
512
|
|
|
513
513
|
The root `AGENTS.md` is split at Markdown headings outside fenced code blocks. The output always
|
|
514
514
|
starts with complete early sections fitting a 4-KiB head, then adds complete relevant sections in
|
|
515
|
-
source order using
|
|
515
|
+
source order using normalized focus/path tokens and their parent context. Remaining headings
|
|
516
516
|
appear in an explicit index whose body text is not loaded. With no selection signals, only the small
|
|
517
517
|
head and index are emitted. Unsafe heading parsing falls back to a bounded head and an explicit
|
|
518
518
|
manual-recovery notice. A head whose own headings would not fit the budget falls back to the same
|
|
519
519
|
bounded head without a section index; a single instruction file never fails the whole collection.
|
|
520
520
|
|
|
521
|
+
Matching uses NFKC normalization and case folding. Ordinary tokens require at least three characters;
|
|
522
|
+
two-character Han terms such as `安全` and `部署`, and the technical abbreviations `AI`, `CD`, `CI`,
|
|
523
|
+
`DB`, `IO`, `JS`, `ML`, `OS`, `PR`, `QA`, `TS`, `UI` and `UX`, are also eligible. Han terms can match
|
|
524
|
+
within entirely Han words, so `安全` matches `安全规则`; Latin terms still require complete tokens,
|
|
525
|
+
so `CI` does not match `special`. Existing stopwords, scoring and byte budgets still apply. Repeating
|
|
526
|
+
a Han term in a heading and body does not increase its score. This is literal matching without word
|
|
527
|
+
segmentation, synonyms or translation.
|
|
528
|
+
|
|
521
529
|
`Omitted source characters` is measured against the whole normalized source, so a bounded source
|
|
522
530
|
scan that ends before EOF still reports the characters it could not select.
|
|
523
531
|
|
|
@@ -647,7 +655,7 @@ or candidate-file content.
|
|
|
647
655
|
|
|
648
656
|
## Not Included
|
|
649
657
|
|
|
650
|
-
Version 1.3.
|
|
658
|
+
Version 1.3.6 does not provide AI summaries, project-type detection, loading or transport of
|
|
651
659
|
nested `AGENTS.md` contents (the JSON `nested_context` field reports bounded existence only),
|
|
652
660
|
Memory retrieval, semantic ranking, ignore-rule parsing, plugins, profiles, caches, databases,
|
|
653
661
|
network services, MCP, daemons, GUIs, CI/CD, telemetry, or automatic updates.
|
|
@@ -8,14 +8,14 @@ Python standard library.
|
|
|
8
8
|
|
|
9
9
|
## Open-source quick start
|
|
10
10
|
|
|
11
|
-
Current stable release: **1.3.
|
|
11
|
+
Current stable release: **1.3.6**. Local CLI for coding-agent workflows; renders deterministic Markdown or JSON.
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
uv tool install 'context-loader==1.3.
|
|
14
|
+
uv tool install 'context-loader==1.3.6'
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
pip install 'context-loader==1.3.
|
|
18
|
+
pip install 'context-loader==1.3.6'
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
```bash
|
|
@@ -28,21 +28,21 @@ project-context --repo /path/to/repo --format json
|
|
|
28
28
|
|
|
29
29
|
## Install
|
|
30
30
|
|
|
31
|
-
Source version: `1.3.
|
|
31
|
+
Source version: `1.3.6`. Install its matching published release or an exact source commit.
|
|
32
32
|
|
|
33
33
|
Install via `uv`:
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
-
uv tool install 'context-loader==1.3.
|
|
36
|
+
uv tool install 'context-loader==1.3.6'
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
Install via `pip`:
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
pip install 'context-loader==1.3.
|
|
42
|
+
pip install 'context-loader==1.3.6'
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
For development or source-based installs tracking current repository (`1.3.
|
|
45
|
+
For development or source-based installs tracking current repository (`1.3.6`):
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
48
|
uv tool install git+https://github.com/xuanheng-tech/context-loader.git
|
|
@@ -139,7 +139,7 @@ set differs, as described under “Compact model consumption”. The declared co
|
|
|
139
139
|
"schema_version": 3,
|
|
140
140
|
"tool": {
|
|
141
141
|
"name": "context-loader",
|
|
142
|
-
"version": "1.3.
|
|
142
|
+
"version": "1.3.6"
|
|
143
143
|
},
|
|
144
144
|
"repository": {
|
|
145
145
|
"requested_path": "/canonical/requested/path",
|
|
@@ -259,7 +259,7 @@ although 1.1.0 added the top-level `statuses` key. From release 1.2.0 onward eac
|
|
|
259
259
|
names exactly one key set, and a new number is issued whenever a key set would otherwise be reused.
|
|
260
260
|
|
|
261
261
|
The JSON schema version and package version are independent: this build emits `schema_version` `3`
|
|
262
|
-
for `--format json` and `4` for `--format json-compact`, while `tool.version` is `1.3.
|
|
262
|
+
for `--format json` and `4` for `--format json-compact`, while `tool.version` is `1.3.6`. Version 1
|
|
263
263
|
and 2 are the exact shapes already published in release 1.2.0 and are never reused: because
|
|
264
264
|
`nested_context` changes the default document's key set, version 3 names the current full-document
|
|
265
265
|
key set and version 4 names the compact projection.
|
|
@@ -301,12 +301,20 @@ heading on the first line is still recognized as a heading.
|
|
|
301
301
|
|
|
302
302
|
The root `AGENTS.md` is split at Markdown headings outside fenced code blocks. The output always
|
|
303
303
|
starts with complete early sections fitting a 4-KiB head, then adds complete relevant sections in
|
|
304
|
-
source order using
|
|
304
|
+
source order using normalized focus/path tokens and their parent context. Remaining headings
|
|
305
305
|
appear in an explicit index whose body text is not loaded. With no selection signals, only the small
|
|
306
306
|
head and index are emitted. Unsafe heading parsing falls back to a bounded head and an explicit
|
|
307
307
|
manual-recovery notice. A head whose own headings would not fit the budget falls back to the same
|
|
308
308
|
bounded head without a section index; a single instruction file never fails the whole collection.
|
|
309
309
|
|
|
310
|
+
Matching uses NFKC normalization and case folding. Ordinary tokens require at least three characters;
|
|
311
|
+
two-character Han terms such as `安全` and `部署`, and the technical abbreviations `AI`, `CD`, `CI`,
|
|
312
|
+
`DB`, `IO`, `JS`, `ML`, `OS`, `PR`, `QA`, `TS`, `UI` and `UX`, are also eligible. Han terms can match
|
|
313
|
+
within entirely Han words, so `安全` matches `安全规则`; Latin terms still require complete tokens,
|
|
314
|
+
so `CI` does not match `special`. Existing stopwords, scoring and byte budgets still apply. Repeating
|
|
315
|
+
a Han term in a heading and body does not increase its score. This is literal matching without word
|
|
316
|
+
segmentation, synonyms or translation.
|
|
317
|
+
|
|
310
318
|
`Omitted source characters` is measured against the whole normalized source, so a bounded source
|
|
311
319
|
scan that ends before EOF still reports the characters it could not select.
|
|
312
320
|
|
|
@@ -436,7 +444,7 @@ or candidate-file content.
|
|
|
436
444
|
|
|
437
445
|
## Not Included
|
|
438
446
|
|
|
439
|
-
Version 1.3.
|
|
447
|
+
Version 1.3.6 does not provide AI summaries, project-type detection, loading or transport of
|
|
440
448
|
nested `AGENTS.md` contents (the JSON `nested_context` field reports bounded existence only),
|
|
441
449
|
Memory retrieval, semantic ranking, ignore-rule parsing, plugins, profiles, caches, databases,
|
|
442
450
|
network services, MCP, daemons, GUIs, CI/CD, telemetry, or automatic updates.
|
|
@@ -68,6 +68,9 @@ _MAKE_TARGET_RE = re.compile(
|
|
|
68
68
|
)
|
|
69
69
|
_ATX_HEADING_RE = re.compile(r"^ {0,3}(#{1,6})(?:[ \t]+(.*)|[ \t]*)$")
|
|
70
70
|
_TOKEN_RE = re.compile(r"[^\W_]+", re.UNICODE)
|
|
71
|
+
_SHORT_TECHNICAL_TOKENS = frozenset(
|
|
72
|
+
{"ai", "cd", "ci", "db", "io", "js", "ml", "os", "pr", "qa", "ts", "ui", "ux"}
|
|
73
|
+
)
|
|
71
74
|
_MATCH_TOKEN_STOPWORDS = frozenset(
|
|
72
75
|
{
|
|
73
76
|
"and",
|
|
@@ -138,11 +141,35 @@ def _normalized_text(value: str) -> str:
|
|
|
138
141
|
return unicodedata.normalize("NFKC", value).casefold()
|
|
139
142
|
|
|
140
143
|
|
|
144
|
+
def _is_han_token(value: str) -> bool:
|
|
145
|
+
return bool(value) and all(
|
|
146
|
+
unicodedata.name(character, "").startswith("CJK UNIFIED IDEOGRAPH-") for character in value
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
|
|
141
150
|
def _matching_tokens(value: str, stopwords: frozenset[str]) -> frozenset[str]:
|
|
142
151
|
return frozenset(
|
|
143
152
|
token
|
|
144
153
|
for token in _TOKEN_RE.findall(_normalized_text(value))
|
|
145
|
-
if
|
|
154
|
+
if token not in stopwords
|
|
155
|
+
and (
|
|
156
|
+
len(token) >= 3
|
|
157
|
+
or token in _SHORT_TECHNICAL_TOKENS
|
|
158
|
+
or (len(token) == 2 and _is_han_token(token))
|
|
159
|
+
)
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def _matched_terms(terms: frozenset[str], tokens: frozenset[str]) -> frozenset[str]:
|
|
164
|
+
matches = terms & tokens
|
|
165
|
+
han_terms = tuple(term for term in terms - matches if _is_han_token(term))
|
|
166
|
+
if not han_terms:
|
|
167
|
+
return matches
|
|
168
|
+
# Han text need not delimit words with spaces. Count each query term once,
|
|
169
|
+
# without introducing substring matching for Latin words or abbreviations.
|
|
170
|
+
han_tokens = tuple(token for token in tokens if _is_han_token(token))
|
|
171
|
+
return matches | frozenset(
|
|
172
|
+
term for term in han_terms if any(term in token for token in han_tokens)
|
|
146
173
|
)
|
|
147
174
|
|
|
148
175
|
|
|
@@ -334,24 +361,20 @@ def _small_head_end(content: str, sections: tuple[MarkdownSection, ...]) -> int:
|
|
|
334
361
|
def _section_relevance(
|
|
335
362
|
section: MarkdownSection, signals: _SelectionSignals
|
|
336
363
|
) -> tuple[int, frozenset[str]]:
|
|
337
|
-
heading_tokens =
|
|
338
|
-
token
|
|
339
|
-
for token in section.normalized_heading.split()
|
|
340
|
-
if len(token) >= 3 and token not in _MATCH_TOKEN_STOPWORDS
|
|
341
|
-
)
|
|
364
|
+
heading_tokens = _matching_tokens(section.normalized_heading, _MATCH_TOKEN_STOPWORDS)
|
|
342
365
|
section_tokens = _matching_tokens(section.text, _MATCH_TOKEN_STOPWORDS)
|
|
343
366
|
body_tokens = section_tokens - heading_tokens
|
|
344
367
|
score = 0
|
|
345
368
|
reasons: set[str] = set()
|
|
346
369
|
|
|
347
|
-
focus_heading = signals.focus_tokens
|
|
348
|
-
focus_body = signals.focus_tokens
|
|
370
|
+
focus_heading = _matched_terms(signals.focus_tokens, heading_tokens)
|
|
371
|
+
focus_body = _matched_terms(signals.focus_tokens, body_tokens) - focus_heading
|
|
349
372
|
if focus_heading or focus_body:
|
|
350
373
|
reasons.add("focus_match")
|
|
351
374
|
score += 6 * len(focus_heading) + len(focus_body)
|
|
352
375
|
|
|
353
|
-
path_heading = signals.path_tokens
|
|
354
|
-
path_body = signals.path_tokens
|
|
376
|
+
path_heading = _matched_terms(signals.path_tokens, heading_tokens)
|
|
377
|
+
path_body = _matched_terms(signals.path_tokens, body_tokens) - path_heading
|
|
355
378
|
exact_path = bool(
|
|
356
379
|
signals.normalized_path
|
|
357
380
|
and _normalized_text(signals.normalized_path) in _normalized_text(section.text)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|