uncoded 2.1.1__tar.gz → 3.0.0__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.
- {uncoded-2.1.1/.claude → uncoded-3.0.0/.agents}/skills/uncoded-code-navigation/SKILL.md +25 -18
- uncoded-3.0.0/.agents/skills/uncoded-consistency-review/SKILL.md +145 -0
- uncoded-3.0.0/.agents/skills/uncoded-doc-navigation/SKILL.md +29 -0
- uncoded-2.1.1/src/uncoded/code_navigation.md → uncoded-3.0.0/.claude/skills/uncoded-code-navigation/SKILL.md +31 -17
- uncoded-3.0.0/.claude/skills/uncoded-consistency-review/SKILL.md +145 -0
- uncoded-3.0.0/.claude/skills/uncoded-doc-navigation/SKILL.md +29 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/.pre-commit-config.yaml +6 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/AGENTS.md +23 -17
- {uncoded-2.1.1 → uncoded-3.0.0}/PKG-INFO +61 -61
- {uncoded-2.1.1 → uncoded-3.0.0}/README.md +58 -59
- uncoded-3.0.0/dreamcatcher.toml +25 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/pyproject.toml +5 -1
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/cli.py +13 -6
- uncoded-2.1.1/.agents/skills/uncoded-code-navigation/SKILL.md → uncoded-3.0.0/src/uncoded/code_navigation.md +24 -24
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/config.py +43 -36
- uncoded-3.0.0/src/uncoded/consistency_review.md +138 -0
- uncoded-3.0.0/src/uncoded/doc_navigation.md +22 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/refs.py +5 -5
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/resolver.py +43 -26
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/skill.py +68 -43
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/stubs.py +32 -21
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/sync.py +3 -4
- {uncoded-2.1.1 → uncoded-3.0.0}/tests/test_body.py +20 -13
- {uncoded-2.1.1 → uncoded-3.0.0}/tests/test_cli.py +60 -25
- {uncoded-2.1.1 → uncoded-3.0.0}/tests/test_refs.py +9 -9
- {uncoded-2.1.1 → uncoded-3.0.0}/tests/test_skill.py +62 -63
- {uncoded-2.1.1 → uncoded-3.0.0}/uv.lock +174 -0
- uncoded-2.1.1/.agents/skills/uncoded-coherence-review/SKILL.md +0 -371
- uncoded-2.1.1/.agents/skills/uncoded-doc-navigation/SKILL.md +0 -24
- uncoded-2.1.1/.claude/skills/uncoded-coherence-review/SKILL.md +0 -371
- uncoded-2.1.1/.claude/skills/uncoded-doc-navigation/SKILL.md +0 -24
- uncoded-2.1.1/.uncoded/docs.yaml +0 -36
- uncoded-2.1.1/.uncoded/namespace.yaml +0 -594
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/__init__.pyi +0 -6
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/ast_helpers.pyi +0 -10
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/body.pyi +0 -13
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/cli.pyi +0 -41
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/config.pyi +0 -26
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/docs_map.pyi +0 -31
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/extract.pyi +0 -33
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/markers.pyi +0 -4
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/namespace_map.pyi +0 -15
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/read_helpers.pyi +0 -15
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/refs.pyi +0 -56
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/resolver.pyi +0 -36
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/skill.pyi +0 -32
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/stubs.pyi +0 -101
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/sync.pyi +0 -10
- uncoded-2.1.1/.uncoded/stubs/src/uncoded/yaml_tree.pyi +0 -11
- uncoded-2.1.1/.uncoded/stubs/tests/test_body.pyi +0 -149
- uncoded-2.1.1/.uncoded/stubs/tests/test_cli.pyi +0 -215
- uncoded-2.1.1/.uncoded/stubs/tests/test_config.pyi +0 -62
- uncoded-2.1.1/.uncoded/stubs/tests/test_docs_map.pyi +0 -154
- uncoded-2.1.1/.uncoded/stubs/tests/test_encoding_gate.pyi +0 -8
- uncoded-2.1.1/.uncoded/stubs/tests/test_extract.pyi +0 -86
- uncoded-2.1.1/.uncoded/stubs/tests/test_markers.pyi +0 -21
- uncoded-2.1.1/.uncoded/stubs/tests/test_namespace_map.pyi +0 -47
- uncoded-2.1.1/.uncoded/stubs/tests/test_refs.pyi +0 -89
- uncoded-2.1.1/.uncoded/stubs/tests/test_skill.pyi +0 -100
- uncoded-2.1.1/.uncoded/stubs/tests/test_stubs.pyi +0 -237
- uncoded-2.1.1/.uncoded/stubs/tests/test_sync.pyi +0 -54
- uncoded-2.1.1/.uncoded/stubs/tests/test_uncoded.pyi +0 -10
- uncoded-2.1.1/src/uncoded/coherence_review.md +0 -364
- uncoded-2.1.1/src/uncoded/doc_navigation.md +0 -17
- {uncoded-2.1.1 → uncoded-3.0.0}/.github/workflows/ci.yml +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/.github/workflows/publish.yml +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/.gitignore +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/.markdownlint-cli2.yaml +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/.prettierrc +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/CLAUDE.md +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/LICENSE +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/__init__.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/ast_helpers.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/body.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/docs_map.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/extract.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/markers.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/namespace_map.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/read_helpers.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/src/uncoded/yaml_tree.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/tests/__init__.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/tests/test_config.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/tests/test_docs_map.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/tests/test_encoding_gate.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/tests/test_extract.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/tests/test_markers.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/tests/test_namespace_map.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/tests/test_stubs.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/tests/test_sync.py +0 -0
- {uncoded-2.1.1 → uncoded-3.0.0}/tests/test_uncoded.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: uncoded-code-navigation
|
|
3
|
-
description:
|
|
3
|
+
description: Load once per session, before the first search, read, or edit of Python source in a codebase indexed by uncoded. Covers locating a symbol, reading a definition, or checking references before you refactor, rename, or delete.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<!-- Generated by uncoded — do not edit; regeneration overwrites. -->
|
|
@@ -17,23 +17,25 @@ for reading a symbol's body and `uncoded refs` for finding references.
|
|
|
17
17
|
symbols are classes, functions, methods, attributes, and module-level constants.
|
|
18
18
|
If it's a pattern, regex, or free-text phrase, use grep.**
|
|
19
19
|
|
|
20
|
-
This applies to every tool call where you find code, not just the
|
|
21
|
-
session. The pretrained reflex for "find X" is grep, and that
|
|
22
|
-
here. Reaching for `grep -rn 'def parse_config'` to read a
|
|
23
|
-
case for `uncoded body`. Reaching for
|
|
24
|
-
callers before a refactor is a case for
|
|
25
|
-
`Edit` to delete dead code is a case
|
|
26
|
-
dead, then `Edit`. The grep version of
|
|
27
|
-
reliable. Grep matches comments, strings, and
|
|
28
|
-
re-exports, so caller and delete checks come
|
|
29
|
-
arithmetic to slice a body. The indexed
|
|
20
|
+
This dispatch rule applies to every tool call where you find code, not just the
|
|
21
|
+
first in the session. The pretrained reflex for "find X" is grep, and that
|
|
22
|
+
reflex is wrong here. Reaching for `grep -rn 'def parse_config'` to read a
|
|
23
|
+
function's body is a case for `uncoded body`. Reaching for
|
|
24
|
+
`grep -rn 'validate_input'` to check callers before a refactor is a case for
|
|
25
|
+
`uncoded refs`. Reaching for `grep` then `Edit` to delete dead code is a case
|
|
26
|
+
for `uncoded refs` to confirm the code is dead, then `Edit`. The grep version of
|
|
27
|
+
any of these is noisier and less reliable. Grep matches comments, strings, and
|
|
28
|
+
unrelated attributes. Grep misses re-exports, so caller and delete checks come
|
|
29
|
+
back incomplete. Grep forces offset arithmetic to slice a body. The indexed
|
|
30
|
+
tools don't.
|
|
30
31
|
|
|
31
32
|
## How to execute the rule
|
|
32
33
|
|
|
33
|
-
The index has two parts
|
|
34
|
-
|
|
34
|
+
The index has two parts: a namespace map and per-file stubs. Follow this
|
|
35
|
+
sequence.
|
|
35
36
|
|
|
36
|
-
**Step 1: Orient. Read the namespace map first.**
|
|
37
|
+
**Step 1: Orient. Read the namespace map first.** If the map is missing, run the
|
|
38
|
+
repository's configured `uncoded sync` command. Then, before answering the user,
|
|
37
39
|
before any other tool call:
|
|
38
40
|
|
|
39
41
|
```text
|
|
@@ -74,10 +76,11 @@ for a method and `function_name` for a top-level function. Per task:
|
|
|
74
76
|
|
|
75
77
|
- **Find every reference to a symbol.**
|
|
76
78
|
`uvx uncoded refs <name_path> --in <relative_path>`. Prints one reference per
|
|
77
|
-
line as
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
line as `<path>:<line>:<col>`, sorted by path, then line, then column. Each
|
|
80
|
+
path is relative to the current working directory when possible and otherwise
|
|
81
|
+
absolute. Grep on the name misses re-exports and adds false positives from
|
|
82
|
+
comments, strings, and attribute lookups on other types. If the next move
|
|
83
|
+
depends on the answer being complete, grep cannot give you that.
|
|
81
84
|
|
|
82
85
|
- **Edit a symbol.** `uvx uncoded body <name_path> --in <relative_path>` gives
|
|
83
86
|
the exact `old_string`; then `Edit` to apply the change.
|
|
@@ -88,6 +91,10 @@ for a method and `function_name` for a top-level function. Per task:
|
|
|
88
91
|
- **Safely delete.** `uvx uncoded refs <name_path> --in <relative_path>` must
|
|
89
92
|
return empty; then `Edit` to remove.
|
|
90
93
|
|
|
94
|
+
**Step 4: Refresh.** After every modification to indexed Python source, run the
|
|
95
|
+
repository's configured `uncoded sync` command before the next code-navigation
|
|
96
|
+
operation. The modification can change the namespace map and stubs.
|
|
97
|
+
|
|
91
98
|
## Where Read, Edit, and grep are still the right tools
|
|
92
99
|
|
|
93
100
|
The rule is about source navigation by symbol name. Outside that, Read, Edit,
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: uncoded-consistency-review
|
|
3
|
+
description: Review a Python codebase for semantic and naming consistency. It reports only concrete disagreements between two claims about the same concept, with verbatim evidence for each claim. It assumes uncoded is installed (.uncoded/namespace.yaml and .uncoded/stubs/ present).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- Generated by uncoded — do not edit; regeneration overwrites. -->
|
|
7
|
+
|
|
8
|
+
# Semantic Consistency Review
|
|
9
|
+
|
|
10
|
+
Review a Python codebase for concrete disagreements in its vocabulary and symbol
|
|
11
|
+
contracts. A finding must identify two claims about the same concept that ought
|
|
12
|
+
to agree, but do not.
|
|
13
|
+
|
|
14
|
+
## Guardrails
|
|
15
|
+
|
|
16
|
+
Admit a finding only when the codebase supports both claims, their observable
|
|
17
|
+
difference, and the reason that they should agree. Quote both claims verbatim.
|
|
18
|
+
Omit a candidate when either claim or the reason for comparing them is
|
|
19
|
+
unsupported.
|
|
20
|
+
|
|
21
|
+
Review semantic and naming consistency, not formatting or style consistency. Do
|
|
22
|
+
not report general bugs, complexity, performance, security, or design
|
|
23
|
+
preferences unless they appear as a disagreement between two supported claims.
|
|
24
|
+
Do not report overgrown public surfaces, private imports, cross-domain imports,
|
|
25
|
+
zero-reference symbols, or redundant public surfaces merely because they exist.
|
|
26
|
+
|
|
27
|
+
## Prerequisites
|
|
28
|
+
|
|
29
|
+
Run the repository's configured `uncoded sync` command. Read the repository's
|
|
30
|
+
agent instructions and follow its navigation rules.
|
|
31
|
+
|
|
32
|
+
## Orientation
|
|
33
|
+
|
|
34
|
+
Read `.uncoded/namespace.yaml` in full. Use its package structure and symbol
|
|
35
|
+
names to map the codebase's main concepts and vocabulary.
|
|
36
|
+
|
|
37
|
+
## Vocabulary sweep
|
|
38
|
+
|
|
39
|
+
Use the namespace and stubs to find candidates, then confirm semantic overlap
|
|
40
|
+
from signatures, docstrings, or bodies. Look for:
|
|
41
|
+
|
|
42
|
+
- **Competing terms:** different names for substantively the same concept.
|
|
43
|
+
- **Conflicting use:** the same term used incompatibly within a shared context.
|
|
44
|
+
- **Stale qualifiers:** names such as `legacy`, `v2`, or `final` whose
|
|
45
|
+
distinction conflicts with another symbol or a symbol's docstring.
|
|
46
|
+
|
|
47
|
+
Similar spelling, low vocabulary overlap, or the presence of a qualifier is not
|
|
48
|
+
evidence on its own. A finding needs two concrete claims that establish the
|
|
49
|
+
shared concept and the disagreement.
|
|
50
|
+
|
|
51
|
+
## Symbol-contract sweep
|
|
52
|
+
|
|
53
|
+
Compare a symbol's name, signature, docstring, and, when needed, behaviour.
|
|
54
|
+
Findings may cover:
|
|
55
|
+
|
|
56
|
+
- name-signature disagreement
|
|
57
|
+
- name-docstring disagreement
|
|
58
|
+
- docstring-signature disagreement
|
|
59
|
+
- name-behaviour disagreement
|
|
60
|
+
|
|
61
|
+
Read each relevant source file's stub for names and signatures. Run the
|
|
62
|
+
repository's configured `uncoded body` command only when a docstring or
|
|
63
|
+
implementation is needed to confirm a candidate. Do not retrieve every symbol
|
|
64
|
+
body.
|
|
65
|
+
|
|
66
|
+
## Report
|
|
67
|
+
|
|
68
|
+
Return the report directly as the final turn output.
|
|
69
|
+
|
|
70
|
+
Use this structure:
|
|
71
|
+
|
|
72
|
+
```markdown
|
|
73
|
+
## Semantic Consistency Review
|
|
74
|
+
|
|
75
|
+
### Scope
|
|
76
|
+
|
|
77
|
+
<What was reviewed and intentionally omitted.>
|
|
78
|
+
|
|
79
|
+
### Summary
|
|
80
|
+
|
|
81
|
+
<Two or three sentences that summarise the supported findings.>
|
|
82
|
+
|
|
83
|
+
### Vocabulary findings
|
|
84
|
+
|
|
85
|
+
#### 1. <Summary>
|
|
86
|
+
|
|
87
|
+
**Claim A** — `<path>` · `<symbol>` · name | signature | docstring | body
|
|
88
|
+
|
|
89
|
+
> Verbatim evidence
|
|
90
|
+
|
|
91
|
+
**Claim B** — `<path>` · `<symbol>` · name | signature | docstring | body
|
|
92
|
+
|
|
93
|
+
> Verbatim evidence
|
|
94
|
+
|
|
95
|
+
**How they differ:** <The observable disagreement.>
|
|
96
|
+
|
|
97
|
+
**Why these should agree:** <Evidence that both claims describe the same
|
|
98
|
+
concept.>
|
|
99
|
+
|
|
100
|
+
### Symbol-contract findings
|
|
101
|
+
|
|
102
|
+
#### 1. <Summary>
|
|
103
|
+
|
|
104
|
+
<Use the same finding structure.>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Keep both finding headings. If a group has no supported findings, state that
|
|
108
|
+
under its heading. Number findings independently within each group.
|
|
109
|
+
|
|
110
|
+
## Examples
|
|
111
|
+
|
|
112
|
+
### Vocabulary finding
|
|
113
|
+
|
|
114
|
+
#### 1. Customer lookup uses competing verbs
|
|
115
|
+
|
|
116
|
+
**Claim A** — `storage.py` · `fetch_customer` · signature
|
|
117
|
+
|
|
118
|
+
> `fetch_customer(customer_id: str) -> Customer`
|
|
119
|
+
|
|
120
|
+
**Claim B** — `adapter.py` · `load_customer` · signature
|
|
121
|
+
|
|
122
|
+
> `load_customer(customer_id: str) -> Customer`
|
|
123
|
+
|
|
124
|
+
**How they differ:** The same lookup uses `fetch` in one module and `load` in
|
|
125
|
+
another.
|
|
126
|
+
|
|
127
|
+
**Why these should agree:** Both signatures accept a customer ID and return a
|
|
128
|
+
customer through sibling adapters.
|
|
129
|
+
|
|
130
|
+
### Symbol-contract finding
|
|
131
|
+
|
|
132
|
+
#### 1. Predicate name promises a boolean but returns a value
|
|
133
|
+
|
|
134
|
+
**Claim A** — `cache.py` · `is_cached` · name
|
|
135
|
+
|
|
136
|
+
> `is_cached`
|
|
137
|
+
|
|
138
|
+
**Claim B** — `cache.py` · `is_cached` · signature
|
|
139
|
+
|
|
140
|
+
> `is_cached(key: str) -> str | None`
|
|
141
|
+
|
|
142
|
+
**How they differ:** The name promises a predicate, while the return type holds
|
|
143
|
+
a cached value or absence.
|
|
144
|
+
|
|
145
|
+
**Why these should agree:** Both claims describe the contract of `is_cached`.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: uncoded-doc-navigation
|
|
3
|
+
description: Load once per session, before the first search or read of a codebase's Markdown documentation indexed by uncoded. Covers locating which file and section cover a topic, or orienting to what documentation exists.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- Generated by uncoded — do not edit; regeneration overwrites. -->
|
|
7
|
+
|
|
8
|
+
# Documentation Navigation
|
|
9
|
+
|
|
10
|
+
This codebase uses [uncoded](https://github.com/alimanfoo/uncoded) to maintain a
|
|
11
|
+
documentation index.
|
|
12
|
+
|
|
13
|
+
**Step 1: Orient. Read the docs map first.** If the map is missing, run the
|
|
14
|
+
repository's configured `uncoded sync` command. Then, before answering the user,
|
|
15
|
+
before any other tool call:
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
Read .uncoded/docs.yaml
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`.uncoded/docs.yaml` is an orientation outline: it lists every Markdown file and
|
|
22
|
+
its heading hierarchy. Read it once, in full, at session start.
|
|
23
|
+
|
|
24
|
+
**Step 2: Navigate.** Headings in the map are literal text. Use `Read` or `grep`
|
|
25
|
+
to navigate to a specific section identified in the map.
|
|
26
|
+
|
|
27
|
+
**Step 3: Refresh.** After every modification to indexed Markdown, run the
|
|
28
|
+
repository's configured `uncoded sync` command before the next
|
|
29
|
+
documentation-navigation operation. The modification can change the heading map.
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: uncoded-code-navigation
|
|
3
|
+
description: Load once per session, before the first search, read, or edit of Python source in a codebase indexed by uncoded. Covers locating a symbol, reading a definition, or checking references before you refactor, rename, or delete.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- Generated by uncoded — do not edit; regeneration overwrites. -->
|
|
7
|
+
|
|
1
8
|
# Code Navigation
|
|
2
9
|
|
|
3
10
|
This codebase uses [uncoded](https://github.com/alimanfoo/uncoded) to maintain a
|
|
@@ -10,23 +17,25 @@ for reading a symbol's body and `uncoded refs` for finding references.
|
|
|
10
17
|
symbols are classes, functions, methods, attributes, and module-level constants.
|
|
11
18
|
If it's a pattern, regex, or free-text phrase, use grep.**
|
|
12
19
|
|
|
13
|
-
This applies to every tool call where you find code, not just the
|
|
14
|
-
session. The pretrained reflex for "find X" is grep, and that
|
|
15
|
-
here. Reaching for `grep -rn 'def parse_config'` to read a
|
|
16
|
-
case for `uncoded body`. Reaching for
|
|
17
|
-
callers before a refactor is a case for
|
|
18
|
-
`Edit` to delete dead code is a case
|
|
19
|
-
dead, then `Edit`. The grep version of
|
|
20
|
-
reliable. Grep matches comments, strings, and
|
|
21
|
-
re-exports, so caller and delete checks come
|
|
22
|
-
arithmetic to slice a body. The indexed
|
|
20
|
+
This dispatch rule applies to every tool call where you find code, not just the
|
|
21
|
+
first in the session. The pretrained reflex for "find X" is grep, and that
|
|
22
|
+
reflex is wrong here. Reaching for `grep -rn 'def parse_config'` to read a
|
|
23
|
+
function's body is a case for `uncoded body`. Reaching for
|
|
24
|
+
`grep -rn 'validate_input'` to check callers before a refactor is a case for
|
|
25
|
+
`uncoded refs`. Reaching for `grep` then `Edit` to delete dead code is a case
|
|
26
|
+
for `uncoded refs` to confirm the code is dead, then `Edit`. The grep version of
|
|
27
|
+
any of these is noisier and less reliable. Grep matches comments, strings, and
|
|
28
|
+
unrelated attributes. Grep misses re-exports, so caller and delete checks come
|
|
29
|
+
back incomplete. Grep forces offset arithmetic to slice a body. The indexed
|
|
30
|
+
tools don't.
|
|
23
31
|
|
|
24
32
|
## How to execute the rule
|
|
25
33
|
|
|
26
|
-
The index has two parts
|
|
27
|
-
|
|
34
|
+
The index has two parts: a namespace map and per-file stubs. Follow this
|
|
35
|
+
sequence.
|
|
28
36
|
|
|
29
|
-
**Step 1: Orient. Read the namespace map first.**
|
|
37
|
+
**Step 1: Orient. Read the namespace map first.** If the map is missing, run the
|
|
38
|
+
repository's configured `uncoded sync` command. Then, before answering the user,
|
|
30
39
|
before any other tool call:
|
|
31
40
|
|
|
32
41
|
```text
|
|
@@ -67,10 +76,11 @@ for a method and `function_name` for a top-level function. Per task:
|
|
|
67
76
|
|
|
68
77
|
- **Find every reference to a symbol.**
|
|
69
78
|
`uvx uncoded refs <name_path> --in <relative_path>`. Prints one reference per
|
|
70
|
-
line as
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
79
|
+
line as `<path>:<line>:<col>`, sorted by path, then line, then column. Each
|
|
80
|
+
path is relative to the current working directory when possible and otherwise
|
|
81
|
+
absolute. Grep on the name misses re-exports and adds false positives from
|
|
82
|
+
comments, strings, and attribute lookups on other types. If the next move
|
|
83
|
+
depends on the answer being complete, grep cannot give you that.
|
|
74
84
|
|
|
75
85
|
- **Edit a symbol.** `uvx uncoded body <name_path> --in <relative_path>` gives
|
|
76
86
|
the exact `old_string`; then `Edit` to apply the change.
|
|
@@ -81,6 +91,10 @@ for a method and `function_name` for a top-level function. Per task:
|
|
|
81
91
|
- **Safely delete.** `uvx uncoded refs <name_path> --in <relative_path>` must
|
|
82
92
|
return empty; then `Edit` to remove.
|
|
83
93
|
|
|
94
|
+
**Step 4: Refresh.** After every modification to indexed Python source, run the
|
|
95
|
+
repository's configured `uncoded sync` command before the next code-navigation
|
|
96
|
+
operation. The modification can change the namespace map and stubs.
|
|
97
|
+
|
|
84
98
|
## Where Read, Edit, and grep are still the right tools
|
|
85
99
|
|
|
86
100
|
The rule is about source navigation by symbol name. Outside that, Read, Edit,
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: uncoded-consistency-review
|
|
3
|
+
description: Review a Python codebase for semantic and naming consistency. It reports only concrete disagreements between two claims about the same concept, with verbatim evidence for each claim. It assumes uncoded is installed (.uncoded/namespace.yaml and .uncoded/stubs/ present).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- Generated by uncoded — do not edit; regeneration overwrites. -->
|
|
7
|
+
|
|
8
|
+
# Semantic Consistency Review
|
|
9
|
+
|
|
10
|
+
Review a Python codebase for concrete disagreements in its vocabulary and symbol
|
|
11
|
+
contracts. A finding must identify two claims about the same concept that ought
|
|
12
|
+
to agree, but do not.
|
|
13
|
+
|
|
14
|
+
## Guardrails
|
|
15
|
+
|
|
16
|
+
Admit a finding only when the codebase supports both claims, their observable
|
|
17
|
+
difference, and the reason that they should agree. Quote both claims verbatim.
|
|
18
|
+
Omit a candidate when either claim or the reason for comparing them is
|
|
19
|
+
unsupported.
|
|
20
|
+
|
|
21
|
+
Review semantic and naming consistency, not formatting or style consistency. Do
|
|
22
|
+
not report general bugs, complexity, performance, security, or design
|
|
23
|
+
preferences unless they appear as a disagreement between two supported claims.
|
|
24
|
+
Do not report overgrown public surfaces, private imports, cross-domain imports,
|
|
25
|
+
zero-reference symbols, or redundant public surfaces merely because they exist.
|
|
26
|
+
|
|
27
|
+
## Prerequisites
|
|
28
|
+
|
|
29
|
+
Run the repository's configured `uncoded sync` command. Read the repository's
|
|
30
|
+
agent instructions and follow its navigation rules.
|
|
31
|
+
|
|
32
|
+
## Orientation
|
|
33
|
+
|
|
34
|
+
Read `.uncoded/namespace.yaml` in full. Use its package structure and symbol
|
|
35
|
+
names to map the codebase's main concepts and vocabulary.
|
|
36
|
+
|
|
37
|
+
## Vocabulary sweep
|
|
38
|
+
|
|
39
|
+
Use the namespace and stubs to find candidates, then confirm semantic overlap
|
|
40
|
+
from signatures, docstrings, or bodies. Look for:
|
|
41
|
+
|
|
42
|
+
- **Competing terms:** different names for substantively the same concept.
|
|
43
|
+
- **Conflicting use:** the same term used incompatibly within a shared context.
|
|
44
|
+
- **Stale qualifiers:** names such as `legacy`, `v2`, or `final` whose
|
|
45
|
+
distinction conflicts with another symbol or a symbol's docstring.
|
|
46
|
+
|
|
47
|
+
Similar spelling, low vocabulary overlap, or the presence of a qualifier is not
|
|
48
|
+
evidence on its own. A finding needs two concrete claims that establish the
|
|
49
|
+
shared concept and the disagreement.
|
|
50
|
+
|
|
51
|
+
## Symbol-contract sweep
|
|
52
|
+
|
|
53
|
+
Compare a symbol's name, signature, docstring, and, when needed, behaviour.
|
|
54
|
+
Findings may cover:
|
|
55
|
+
|
|
56
|
+
- name-signature disagreement
|
|
57
|
+
- name-docstring disagreement
|
|
58
|
+
- docstring-signature disagreement
|
|
59
|
+
- name-behaviour disagreement
|
|
60
|
+
|
|
61
|
+
Read each relevant source file's stub for names and signatures. Run the
|
|
62
|
+
repository's configured `uncoded body` command only when a docstring or
|
|
63
|
+
implementation is needed to confirm a candidate. Do not retrieve every symbol
|
|
64
|
+
body.
|
|
65
|
+
|
|
66
|
+
## Report
|
|
67
|
+
|
|
68
|
+
Return the report directly as the final turn output.
|
|
69
|
+
|
|
70
|
+
Use this structure:
|
|
71
|
+
|
|
72
|
+
```markdown
|
|
73
|
+
## Semantic Consistency Review
|
|
74
|
+
|
|
75
|
+
### Scope
|
|
76
|
+
|
|
77
|
+
<What was reviewed and intentionally omitted.>
|
|
78
|
+
|
|
79
|
+
### Summary
|
|
80
|
+
|
|
81
|
+
<Two or three sentences that summarise the supported findings.>
|
|
82
|
+
|
|
83
|
+
### Vocabulary findings
|
|
84
|
+
|
|
85
|
+
#### 1. <Summary>
|
|
86
|
+
|
|
87
|
+
**Claim A** — `<path>` · `<symbol>` · name | signature | docstring | body
|
|
88
|
+
|
|
89
|
+
> Verbatim evidence
|
|
90
|
+
|
|
91
|
+
**Claim B** — `<path>` · `<symbol>` · name | signature | docstring | body
|
|
92
|
+
|
|
93
|
+
> Verbatim evidence
|
|
94
|
+
|
|
95
|
+
**How they differ:** <The observable disagreement.>
|
|
96
|
+
|
|
97
|
+
**Why these should agree:** <Evidence that both claims describe the same
|
|
98
|
+
concept.>
|
|
99
|
+
|
|
100
|
+
### Symbol-contract findings
|
|
101
|
+
|
|
102
|
+
#### 1. <Summary>
|
|
103
|
+
|
|
104
|
+
<Use the same finding structure.>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Keep both finding headings. If a group has no supported findings, state that
|
|
108
|
+
under its heading. Number findings independently within each group.
|
|
109
|
+
|
|
110
|
+
## Examples
|
|
111
|
+
|
|
112
|
+
### Vocabulary finding
|
|
113
|
+
|
|
114
|
+
#### 1. Customer lookup uses competing verbs
|
|
115
|
+
|
|
116
|
+
**Claim A** — `storage.py` · `fetch_customer` · signature
|
|
117
|
+
|
|
118
|
+
> `fetch_customer(customer_id: str) -> Customer`
|
|
119
|
+
|
|
120
|
+
**Claim B** — `adapter.py` · `load_customer` · signature
|
|
121
|
+
|
|
122
|
+
> `load_customer(customer_id: str) -> Customer`
|
|
123
|
+
|
|
124
|
+
**How they differ:** The same lookup uses `fetch` in one module and `load` in
|
|
125
|
+
another.
|
|
126
|
+
|
|
127
|
+
**Why these should agree:** Both signatures accept a customer ID and return a
|
|
128
|
+
customer through sibling adapters.
|
|
129
|
+
|
|
130
|
+
### Symbol-contract finding
|
|
131
|
+
|
|
132
|
+
#### 1. Predicate name promises a boolean but returns a value
|
|
133
|
+
|
|
134
|
+
**Claim A** — `cache.py` · `is_cached` · name
|
|
135
|
+
|
|
136
|
+
> `is_cached`
|
|
137
|
+
|
|
138
|
+
**Claim B** — `cache.py` · `is_cached` · signature
|
|
139
|
+
|
|
140
|
+
> `is_cached(key: str) -> str | None`
|
|
141
|
+
|
|
142
|
+
**How they differ:** The name promises a predicate, while the return type holds
|
|
143
|
+
a cached value or absence.
|
|
144
|
+
|
|
145
|
+
**Why these should agree:** Both claims describe the contract of `is_cached`.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: uncoded-doc-navigation
|
|
3
|
+
description: Load once per session, before the first search or read of a codebase's Markdown documentation indexed by uncoded. Covers locating which file and section cover a topic, or orienting to what documentation exists.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<!-- Generated by uncoded — do not edit; regeneration overwrites. -->
|
|
7
|
+
|
|
8
|
+
# Documentation Navigation
|
|
9
|
+
|
|
10
|
+
This codebase uses [uncoded](https://github.com/alimanfoo/uncoded) to maintain a
|
|
11
|
+
documentation index.
|
|
12
|
+
|
|
13
|
+
**Step 1: Orient. Read the docs map first.** If the map is missing, run the
|
|
14
|
+
repository's configured `uncoded sync` command. Then, before answering the user,
|
|
15
|
+
before any other tool call:
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
Read .uncoded/docs.yaml
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`.uncoded/docs.yaml` is an orientation outline: it lists every Markdown file and
|
|
22
|
+
its heading hierarchy. Read it once, in full, at session start.
|
|
23
|
+
|
|
24
|
+
**Step 2: Navigate.** Headings in the map are literal text. Use `Read` or `grep`
|
|
25
|
+
to navigate to a specific section identified in the map.
|
|
26
|
+
|
|
27
|
+
**Step 3: Refresh.** After every modification to indexed Markdown, run the
|
|
28
|
+
repository's configured `uncoded sync` command before the next
|
|
29
|
+
documentation-navigation operation. The modification can change the heading map.
|
|
@@ -32,6 +32,11 @@ repos:
|
|
|
32
32
|
entry: uv run ty check src tests
|
|
33
33
|
language: system
|
|
34
34
|
pass_filenames: false
|
|
35
|
+
- id: complexipy
|
|
36
|
+
name: complexipy
|
|
37
|
+
entry: uv run complexipy src tests
|
|
38
|
+
language: system
|
|
39
|
+
pass_filenames: false
|
|
35
40
|
# Runs before uncoded so the generated skill files are built from
|
|
36
41
|
# already-formatted sources. The generated skill dirs are excluded
|
|
37
42
|
# because uncoded sync owns those files.
|
|
@@ -47,4 +52,5 @@ repos:
|
|
|
47
52
|
name: uncoded
|
|
48
53
|
entry: uv run uncoded sync
|
|
49
54
|
language: system
|
|
55
|
+
always_run: true
|
|
50
56
|
pass_filenames: false
|
|
@@ -43,7 +43,7 @@ This project uses [uv](https://docs.astral.sh/uv/). Run all commands via
|
|
|
43
43
|
install, which may have different behaviour.
|
|
44
44
|
|
|
45
45
|
```sh
|
|
46
|
-
# Generate
|
|
46
|
+
# Generate or update the navigation artefacts
|
|
47
47
|
uv run uncoded sync
|
|
48
48
|
|
|
49
49
|
# Verify the index without writing. It exits non-zero if any file would change
|
|
@@ -74,6 +74,7 @@ Clone and install dev dependencies:
|
|
|
74
74
|
git clone https://github.com/alimanfoo/uncoded
|
|
75
75
|
cd uncoded
|
|
76
76
|
uv sync --extra dev
|
|
77
|
+
uv run uncoded sync
|
|
77
78
|
uv run pre-commit install
|
|
78
79
|
```
|
|
79
80
|
|
|
@@ -83,8 +84,9 @@ packages such as pytest and hypothesis. Without the dev extras in the venv, ty
|
|
|
83
84
|
cannot resolve those imports and reports spurious errors.
|
|
84
85
|
|
|
85
86
|
This repo uses uncoded on itself. The pre-commit hook runs `uv run uncoded sync`
|
|
86
|
-
on each commit.
|
|
87
|
-
|
|
87
|
+
on each commit. The local `.uncoded/` index is ignored. If the hook modifies a
|
|
88
|
+
tracked generated skill file, the commit fails. Re-stage the skill file and
|
|
89
|
+
commit again.
|
|
88
90
|
|
|
89
91
|
### Windows
|
|
90
92
|
|
|
@@ -98,7 +100,8 @@ following the symlink.
|
|
|
98
100
|
Run `uv run ruff check --fix` and `uv run ruff format` before committing. Both
|
|
99
101
|
are pinned via the `dev` optional dependency. The pre-commit hooks run the same
|
|
100
102
|
commands automatically. If a hook rewrites files, the commit fails. Re-stage the
|
|
101
|
-
modified files and commit again. The uncoded sync hook follows the same pattern
|
|
103
|
+
modified files and commit again. The uncoded sync hook follows the same pattern
|
|
104
|
+
for tracked generated skill files.
|
|
102
105
|
|
|
103
106
|
Never commit with `--no-verify`. CI runs `pre-commit run --all-files` on every
|
|
104
107
|
pull request and will fail a build where a hook was skipped.
|
|
@@ -106,8 +109,10 @@ pull request and will fail a build where a hook was skipped.
|
|
|
106
109
|
Do not pass `--unsafe-fixes` unless a specific violation needs it and you have
|
|
107
110
|
reviewed the change.
|
|
108
111
|
|
|
109
|
-
A
|
|
110
|
-
flatten it
|
|
112
|
+
A complexity-check violation means a function is too complex to pass. Refactor
|
|
113
|
+
or flatten it. Never suppress a complexity violation with an ignore comment and
|
|
114
|
+
never raise the threshold. The enabled checks and their thresholds are in
|
|
115
|
+
`pyproject.toml`.
|
|
111
116
|
|
|
112
117
|
The ty pre-commit hook runs the type checker. It is pinned via the `dev`
|
|
113
118
|
optional dependency, the same way ruff is.
|
|
@@ -132,8 +137,7 @@ This section names where each cross-cutting convention lives and what keeps it
|
|
|
132
137
|
in place.
|
|
133
138
|
|
|
134
139
|
**Provenance marker.** Every generated file carries `GENERATED_MARKER`, defined
|
|
135
|
-
in `src/uncoded/markers.py`.
|
|
136
|
-
output kinds carry it.
|
|
140
|
+
in `src/uncoded/markers.py`. The tests verify that every output kind carries it.
|
|
137
141
|
|
|
138
142
|
**Explicit encoding.** Every text read/write in the repository must pass
|
|
139
143
|
`encoding=`. Configuration lives in `pyproject.toml` and
|
|
@@ -158,12 +162,14 @@ Run tests locally as `PYTHONWARNDEFAULTENCODING=1 uv run pytest`. The sentinel
|
|
|
158
162
|
in `tests/test_encoding_gate.py` fails loudly if either the env var is unset or
|
|
159
163
|
the filterwarnings escalation is removed.
|
|
160
164
|
|
|
161
|
-
**Complexity ceiling.** The
|
|
162
|
-
`pyproject.toml`. See [Linting and formatting](#linting-and-formatting) for
|
|
163
|
-
response to a
|
|
165
|
+
**Complexity ceiling.** The enabled complexity checks and their thresholds are
|
|
166
|
+
in `pyproject.toml`. See [Linting and formatting](#linting-and-formatting) for
|
|
167
|
+
the response to a violation.
|
|
164
168
|
|
|
165
|
-
**Index
|
|
166
|
-
|
|
169
|
+
**Index local.** `uncoded sync` writes `.uncoded/.gitignore`, which keeps the
|
|
170
|
+
whole index out of Git. Run `uv run uncoded sync` after every indexed source or
|
|
171
|
+
documentation change and before using the index again. The pre-commit hook is a
|
|
172
|
+
final refresh. See [Commands](#commands) and [Dev setup](#dev-setup).
|
|
167
173
|
|
|
168
174
|
## Releasing
|
|
169
175
|
|
|
@@ -185,7 +191,7 @@ PyPI.
|
|
|
185
191
|
|
|
186
192
|
## Before you start
|
|
187
193
|
|
|
188
|
-
- Load the `uncoded-code-navigation` skill before searching,
|
|
189
|
-
any code.
|
|
190
|
-
- Load the `uncoded-doc-navigation` skill before searching,
|
|
191
|
-
any docs.
|
|
194
|
+
- Load the `uncoded-code-navigation` skill once per session, before searching,
|
|
195
|
+
reading or editing any code.
|
|
196
|
+
- Load the `uncoded-doc-navigation` skill once per session, before searching,
|
|
197
|
+
reading or editing any docs.
|