wikifier 4.5.2__tar.gz → 4.5.3__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.
- {wikifier-4.5.2/wikifier.egg-info → wikifier-4.5.3}/PKG-INFO +30 -27
- {wikifier-4.5.2 → wikifier-4.5.3}/README.md +29 -26
- {wikifier-4.5.2 → wikifier-4.5.3}/skills/run.md +48 -20
- wikifier-4.5.3/tests/test_gap_closure.py +128 -0
- wikifier-4.5.3/tests/test_selftest_wrappers.py +39 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/__init__.py +15 -5
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/cli.py +138 -19
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/contracts.py +0 -227
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/daemon.py +37 -9
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/health.py +48 -15
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/import_cache.py +87 -54
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/mcp/server.py +23 -87
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/parsers/bree.py +9 -29
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/parsers/cdia.py +0 -112
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/parsers/javascript.py +8 -330
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/parsers/python.py +0 -44
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/resolution.py +0 -142
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/scripts/wikifier.sh +8 -2
- {wikifier-4.5.2 → wikifier-4.5.3/wikifier.egg-info}/PKG-INFO +30 -27
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier.egg-info/SOURCES.txt +2 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/CONTRIBUTING.md +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/LICENSE +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/MANIFEST.in +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/diagnostics.html +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/docs/spec.md +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/index.html +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/pyproject.toml +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/setup.cfg +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/tests/test_barrel_invalidation.py +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/tests/test_health.py +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/tests/test_import_cache.py +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/tests/test_parsers.py +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/__main__.py +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/diagnostics.py +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/index.html +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/library.py +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/locking.py +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/mcp/__init__.py +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/parsers/__init__.py +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/scripts/wikifier.bat +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/scripts/wikifier.ps1 +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier/serve.py +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier.egg-info/dependency_links.txt +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier.egg-info/entry_points.txt +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier.egg-info/requires.txt +0 -0
- {wikifier-4.5.2 → wikifier-4.5.3}/wikifier.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wikifier
|
|
3
|
-
Version: 4.5.
|
|
3
|
+
Version: 4.5.3
|
|
4
4
|
Summary: Zero-dependency agent-to-agent codebase wiki for LLMs and AI agents. Autonomously maintained via record-change and mark-green for token-efficient lookup of files, dependencies, health, and summaries — across tiny scripts to 50k+ monorepos. Optional MCP server with rich tools for agents.
|
|
5
5
|
Author-email: Aron Amos <aron@example.com>
|
|
6
6
|
Maintainer: Aron Amos
|
|
@@ -40,65 +40,63 @@ Dynamic: license-file
|
|
|
40
40
|
|
|
41
41
|
Wikifier is an **agent-to-agent** tool: it builds a living map of a project (health matrix, dependency graph, short file summaries) and agents keep that map current as they work. Humans can peek via a small dashboard; the product is the agent loop, not a general docs site or IDE.
|
|
42
42
|
|
|
43
|
-
Works from small scripts to large monorepos
|
|
43
|
+
Works from small scripts to large monorepos. **Deep import maps** cover **Python + JavaScript/TypeScript** (barrels, cycles, incremental updates). Other languages can still use health/journal/watch; they won’t get full import graphs until a parser exists.
|
|
44
44
|
|
|
45
45
|
## Why
|
|
46
46
|
|
|
47
47
|
Context windows are finite. Re-reading a large file to answer “what is this and who depends on it?” wastes tokens.
|
|
48
48
|
|
|
49
|
-
Wikifier keeps a small set of artifacts agents can query:
|
|
50
|
-
|
|
51
49
|
| Artifact | Role |
|
|
52
50
|
|----------|------|
|
|
53
51
|
| `file_health.md` | 🟢 / 🟡 / 🔴 matrix — what to trust, what to fix first |
|
|
54
52
|
| `library.md` | File tree, Mermaid dependency map, import tables, cycles + confidence |
|
|
55
|
-
| `*.wiki.md` | Short per-file “what this is for” notes (agent-maintained) |
|
|
56
|
-
| `journal/` | Semantic *why* trail
|
|
53
|
+
| `*.wiki.md` | Short per-file “what this is for” notes (**agent-maintained** prose) |
|
|
54
|
+
| `journal/` + `pending_updates.md` | Semantic *why* trail + work queue (audit, **not** a full issue tracker) |
|
|
57
55
|
|
|
58
|
-
|
|
56
|
+
**Map first, wiki depth second:** `update-maps` builds the structural map automatically. Rich per-file wiki text is filled by agents as they work — not a free full-repo “understand everything” pass on init.
|
|
59
57
|
|
|
60
|
-
##
|
|
58
|
+
## First run (bootstrap the map)
|
|
61
59
|
|
|
62
60
|
```bash
|
|
63
61
|
pip install wikifier # pure Python stdlib core — no runtime deps
|
|
64
62
|
pip install wikifier[mcp] # optional Model Context Protocol (MCP) server
|
|
65
63
|
|
|
66
64
|
cd /path/to/your/project
|
|
67
|
-
wikifier init
|
|
68
|
-
wikifier update-maps #
|
|
69
|
-
wikifier
|
|
70
|
-
wikifier
|
|
65
|
+
wikifier init # seeds + human index.html
|
|
66
|
+
wikifier update-maps # full structural map → library.md + import cache
|
|
67
|
+
wikifier health --summary # matrix counts
|
|
68
|
+
wikifier suggest-next # or MCP suggest_next_actions — 🔴/🟡 only
|
|
71
69
|
```
|
|
72
70
|
|
|
73
|
-
Always set an explicit root for external trees:
|
|
71
|
+
Always set an explicit root for external trees: `WIKIFIER_PROJECT_ROOT=/abs/path wikifier …`
|
|
74
72
|
|
|
75
|
-
|
|
76
|
-
WIKIFIER_PROJECT_ROOT=/abs/path/to/project wikifier check-changes
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## Agent loop
|
|
73
|
+
## Steady state (only touch what needs it)
|
|
80
74
|
|
|
81
75
|
Full protocol: [`skills/run.md`](skills/run.md).
|
|
82
76
|
|
|
83
77
|
```bash
|
|
84
|
-
wikifier check-changes
|
|
85
|
-
# prioritize 🔴 then 🟡
|
|
86
|
-
# ... edit
|
|
78
|
+
wikifier check-changes # yellow dirty files; red ghosts (missing paths)
|
|
79
|
+
# prioritize 🔴 then 🟡 — do NOT re-wiki 🟢 Green files
|
|
80
|
+
# ... edit only those sources ...
|
|
87
81
|
wikifier record-change "path/file.py" "why this changed" # required
|
|
88
|
-
# ... refresh that file’s wiki summary ...
|
|
82
|
+
# ... refresh that file’s wiki summary only ...
|
|
89
83
|
wikifier mark-green "path/file.py"
|
|
90
|
-
wikifier update-maps # if imports/structure changed
|
|
84
|
+
wikifier update-maps # only if imports/structure changed
|
|
85
|
+
# removals:
|
|
86
|
+
wikifier record-deletion "path/gone.py" "why removed"
|
|
91
87
|
```
|
|
92
88
|
|
|
93
|
-
`
|
|
89
|
+
MCP **Core 6** (start every session): `get_project_status`, `check_changes`, `get_files_needing_attention`, `get_file_wiki`, `suggest_next_actions`, `record_change` / `mark_green`. Intel as needed: `get_dependencies`, `get_dependents`, `get_cycles`. Always pass `project_root=` for external trees.
|
|
94
90
|
|
|
95
91
|
## What you get
|
|
96
92
|
|
|
97
93
|
- **Import analysis** — Python + JS/TS (ESM, CommonJS, dynamic imports, path aliases, package exports); per-edge confidence; name-routed barrel expansion (precise leaves, not edge explosion)
|
|
98
94
|
- **Incremental pipeline** — pure-Python `update-maps`: dirty parse → import cache → reverse deps → cycles → `library.md`
|
|
95
|
+
- **Selective agent work** — health + suggest bias to 🔴/🟡 only; ACS *actionable* low-conf excludes stdlib/external noise
|
|
99
96
|
- **Scale** — reverse index + barrel invalidation so one edit doesn’t re-scan the monorepo
|
|
100
|
-
- **MCP tools** — optional server for Claude, Cursor, Cline, and other MCP clients
|
|
97
|
+
- **MCP tools** — optional server for Claude, Cursor, Cline, and other MCP clients
|
|
101
98
|
- **Zero core dependencies** — stdlib only; forks can add their own stack on top
|
|
99
|
+
- **Agent navigability** — short **AGENT MAP** docstrings on core modules; self-tests under `tests/` (not buried in parsers)
|
|
102
100
|
|
|
103
101
|
## Performance (measured)
|
|
104
102
|
|
|
@@ -118,13 +116,16 @@ Tests: `python -m unittest discover tests` (stdlib only).
|
|
|
118
116
|
| `wikifier check-changes` | Incremental scan → health / pending |
|
|
119
117
|
| `wikifier record-change <file> "reason"` | Log *why* (required after edits) |
|
|
120
118
|
| `wikifier mark-green <file>` | Mark wiki current |
|
|
119
|
+
| `wikifier record-deletion <file> "reason"` | Mark removed paths 🔴 + prune barrel refs |
|
|
120
|
+
| `wikifier suggest-next` | Next actions (🔴/🟡 only) |
|
|
121
121
|
| `wikifier update-maps [--directory=src/] [--max-files=N]` | Rebuild graph + `library.md` |
|
|
122
122
|
| `wikifier health [--summary\|--json]` | Health matrix (machine-friendly flags) |
|
|
123
|
+
| `wikifier validate` | Missing wiki rows + ghost paths |
|
|
123
124
|
| `wikifier cycles` | Circular deps + break hints |
|
|
124
|
-
| `wikifier monitor` / `daemon` | Background maintenance |
|
|
125
|
+
| `wikifier monitor` / `daemon` | Background maintenance (`WIKIFIER_DAEMON_MAPS=0` for check-only) |
|
|
125
126
|
| `wikifier serve` | Localhost dashboard with Run/Stop |
|
|
126
127
|
|
|
127
|
-
Library: `from wikifier import check_changes, record_change, mark_green,
|
|
128
|
+
Library: `from wikifier import check_changes, record_change, mark_green, suggest_next_actions, update_maps, health`.
|
|
128
129
|
|
|
129
130
|
## MCP
|
|
130
131
|
|
|
@@ -146,6 +147,8 @@ Setup and tool list: [`wikifier/mcp/README.md`](wikifier/mcp/README.md).
|
|
|
146
147
|
**In:** agent-maintained codebase wiki, dependency intelligence, token-saving lookup for LLMs and coding agents.
|
|
147
148
|
**Out:** general human documentation systems, IDE plugins, “docs for everyone” product growth.
|
|
148
149
|
|
|
150
|
+
**Agent navigability:** Prefer protocol ([`skills/run.md`](skills/run.md)) + MCP Core 6 over reading 20k LOC of parsers/cache. Production modules carry a short **AGENT MAP** docstring; self-tests live under `tests/` and `tests/selftest/`, not inline at the bottom of parsers.
|
|
151
|
+
|
|
149
152
|
## Links
|
|
150
153
|
|
|
151
154
|
- [PyPI](https://pypi.org/project/wikifier/) · [GitHub](https://github.com/IronAdamant/wikifier)
|
|
@@ -8,65 +8,63 @@
|
|
|
8
8
|
|
|
9
9
|
Wikifier is an **agent-to-agent** tool: it builds a living map of a project (health matrix, dependency graph, short file summaries) and agents keep that map current as they work. Humans can peek via a small dashboard; the product is the agent loop, not a general docs site or IDE.
|
|
10
10
|
|
|
11
|
-
Works from small scripts to large monorepos
|
|
11
|
+
Works from small scripts to large monorepos. **Deep import maps** cover **Python + JavaScript/TypeScript** (barrels, cycles, incremental updates). Other languages can still use health/journal/watch; they won’t get full import graphs until a parser exists.
|
|
12
12
|
|
|
13
13
|
## Why
|
|
14
14
|
|
|
15
15
|
Context windows are finite. Re-reading a large file to answer “what is this and who depends on it?” wastes tokens.
|
|
16
16
|
|
|
17
|
-
Wikifier keeps a small set of artifacts agents can query:
|
|
18
|
-
|
|
19
17
|
| Artifact | Role |
|
|
20
18
|
|----------|------|
|
|
21
19
|
| `file_health.md` | 🟢 / 🟡 / 🔴 matrix — what to trust, what to fix first |
|
|
22
20
|
| `library.md` | File tree, Mermaid dependency map, import tables, cycles + confidence |
|
|
23
|
-
| `*.wiki.md` | Short per-file “what this is for” notes (agent-maintained) |
|
|
24
|
-
| `journal/` | Semantic *why* trail
|
|
21
|
+
| `*.wiki.md` | Short per-file “what this is for” notes (**agent-maintained** prose) |
|
|
22
|
+
| `journal/` + `pending_updates.md` | Semantic *why* trail + work queue (audit, **not** a full issue tracker) |
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
**Map first, wiki depth second:** `update-maps` builds the structural map automatically. Rich per-file wiki text is filled by agents as they work — not a free full-repo “understand everything” pass on init.
|
|
27
25
|
|
|
28
|
-
##
|
|
26
|
+
## First run (bootstrap the map)
|
|
29
27
|
|
|
30
28
|
```bash
|
|
31
29
|
pip install wikifier # pure Python stdlib core — no runtime deps
|
|
32
30
|
pip install wikifier[mcp] # optional Model Context Protocol (MCP) server
|
|
33
31
|
|
|
34
32
|
cd /path/to/your/project
|
|
35
|
-
wikifier init
|
|
36
|
-
wikifier update-maps #
|
|
37
|
-
wikifier
|
|
38
|
-
wikifier
|
|
33
|
+
wikifier init # seeds + human index.html
|
|
34
|
+
wikifier update-maps # full structural map → library.md + import cache
|
|
35
|
+
wikifier health --summary # matrix counts
|
|
36
|
+
wikifier suggest-next # or MCP suggest_next_actions — 🔴/🟡 only
|
|
39
37
|
```
|
|
40
38
|
|
|
41
|
-
Always set an explicit root for external trees:
|
|
39
|
+
Always set an explicit root for external trees: `WIKIFIER_PROJECT_ROOT=/abs/path wikifier …`
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
WIKIFIER_PROJECT_ROOT=/abs/path/to/project wikifier check-changes
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Agent loop
|
|
41
|
+
## Steady state (only touch what needs it)
|
|
48
42
|
|
|
49
43
|
Full protocol: [`skills/run.md`](skills/run.md).
|
|
50
44
|
|
|
51
45
|
```bash
|
|
52
|
-
wikifier check-changes
|
|
53
|
-
# prioritize 🔴 then 🟡
|
|
54
|
-
# ... edit
|
|
46
|
+
wikifier check-changes # yellow dirty files; red ghosts (missing paths)
|
|
47
|
+
# prioritize 🔴 then 🟡 — do NOT re-wiki 🟢 Green files
|
|
48
|
+
# ... edit only those sources ...
|
|
55
49
|
wikifier record-change "path/file.py" "why this changed" # required
|
|
56
|
-
# ... refresh that file’s wiki summary ...
|
|
50
|
+
# ... refresh that file’s wiki summary only ...
|
|
57
51
|
wikifier mark-green "path/file.py"
|
|
58
|
-
wikifier update-maps # if imports/structure changed
|
|
52
|
+
wikifier update-maps # only if imports/structure changed
|
|
53
|
+
# removals:
|
|
54
|
+
wikifier record-deletion "path/gone.py" "why removed"
|
|
59
55
|
```
|
|
60
56
|
|
|
61
|
-
`
|
|
57
|
+
MCP **Core 6** (start every session): `get_project_status`, `check_changes`, `get_files_needing_attention`, `get_file_wiki`, `suggest_next_actions`, `record_change` / `mark_green`. Intel as needed: `get_dependencies`, `get_dependents`, `get_cycles`. Always pass `project_root=` for external trees.
|
|
62
58
|
|
|
63
59
|
## What you get
|
|
64
60
|
|
|
65
61
|
- **Import analysis** — Python + JS/TS (ESM, CommonJS, dynamic imports, path aliases, package exports); per-edge confidence; name-routed barrel expansion (precise leaves, not edge explosion)
|
|
66
62
|
- **Incremental pipeline** — pure-Python `update-maps`: dirty parse → import cache → reverse deps → cycles → `library.md`
|
|
63
|
+
- **Selective agent work** — health + suggest bias to 🔴/🟡 only; ACS *actionable* low-conf excludes stdlib/external noise
|
|
67
64
|
- **Scale** — reverse index + barrel invalidation so one edit doesn’t re-scan the monorepo
|
|
68
|
-
- **MCP tools** — optional server for Claude, Cursor, Cline, and other MCP clients
|
|
65
|
+
- **MCP tools** — optional server for Claude, Cursor, Cline, and other MCP clients
|
|
69
66
|
- **Zero core dependencies** — stdlib only; forks can add their own stack on top
|
|
67
|
+
- **Agent navigability** — short **AGENT MAP** docstrings on core modules; self-tests under `tests/` (not buried in parsers)
|
|
70
68
|
|
|
71
69
|
## Performance (measured)
|
|
72
70
|
|
|
@@ -86,13 +84,16 @@ Tests: `python -m unittest discover tests` (stdlib only).
|
|
|
86
84
|
| `wikifier check-changes` | Incremental scan → health / pending |
|
|
87
85
|
| `wikifier record-change <file> "reason"` | Log *why* (required after edits) |
|
|
88
86
|
| `wikifier mark-green <file>` | Mark wiki current |
|
|
87
|
+
| `wikifier record-deletion <file> "reason"` | Mark removed paths 🔴 + prune barrel refs |
|
|
88
|
+
| `wikifier suggest-next` | Next actions (🔴/🟡 only) |
|
|
89
89
|
| `wikifier update-maps [--directory=src/] [--max-files=N]` | Rebuild graph + `library.md` |
|
|
90
90
|
| `wikifier health [--summary\|--json]` | Health matrix (machine-friendly flags) |
|
|
91
|
+
| `wikifier validate` | Missing wiki rows + ghost paths |
|
|
91
92
|
| `wikifier cycles` | Circular deps + break hints |
|
|
92
|
-
| `wikifier monitor` / `daemon` | Background maintenance |
|
|
93
|
+
| `wikifier monitor` / `daemon` | Background maintenance (`WIKIFIER_DAEMON_MAPS=0` for check-only) |
|
|
93
94
|
| `wikifier serve` | Localhost dashboard with Run/Stop |
|
|
94
95
|
|
|
95
|
-
Library: `from wikifier import check_changes, record_change, mark_green,
|
|
96
|
+
Library: `from wikifier import check_changes, record_change, mark_green, suggest_next_actions, update_maps, health`.
|
|
96
97
|
|
|
97
98
|
## MCP
|
|
98
99
|
|
|
@@ -114,6 +115,8 @@ Setup and tool list: [`wikifier/mcp/README.md`](wikifier/mcp/README.md).
|
|
|
114
115
|
**In:** agent-maintained codebase wiki, dependency intelligence, token-saving lookup for LLMs and coding agents.
|
|
115
116
|
**Out:** general human documentation systems, IDE plugins, “docs for everyone” product growth.
|
|
116
117
|
|
|
118
|
+
**Agent navigability:** Prefer protocol ([`skills/run.md`](skills/run.md)) + MCP Core 6 over reading 20k LOC of parsers/cache. Production modules carry a short **AGENT MAP** docstring; self-tests live under `tests/` and `tests/selftest/`, not inline at the bottom of parsers.
|
|
119
|
+
|
|
117
120
|
## Links
|
|
118
121
|
|
|
119
122
|
- [PyPI](https://pypi.org/project/wikifier/) · [GitHub](https://github.com/IronAdamant/wikifier)
|
|
@@ -3,11 +3,18 @@
|
|
|
3
3
|
**Formerly "Wikifier Skills & Commands". This is the authoritative, versioned specification for agent behavior when using Wikifier.**
|
|
4
4
|
|
|
5
5
|
**Version**: v0.6 (v4.2.0 real-pipeline + reliability update; package current **4.5.x**)
|
|
6
|
-
**Date**: 2026-06-10 (package notes refreshed 2026-07-09)
|
|
6
|
+
**Date**: 2026-06-10 (package notes refreshed 2026-07-09; gap-closure contract 2026-07-09)
|
|
7
7
|
**Status**: Active. Supersedes v0.5.
|
|
8
|
-
**See also**: `README.md`
|
|
8
|
+
**See also**: `README.md`, `Findings/gap-closure-report.md`, and the library in wikifier/.
|
|
9
9
|
|
|
10
|
-
**Package 4.5.x notes (additive; protocol still v0.6):**
|
|
10
|
+
**Package 4.5.x + gap-closure notes (additive; protocol still v0.6):**
|
|
11
|
+
- File Tree + `wikifier serve`; MCP status/attention use library + emoji (not `[GREEN]` tags).
|
|
12
|
+
- **First-run:** `init` → `update-maps` → `health --summary` → `suggest_next_actions`. Map is automatic; wiki *prose* is agent-filled over time.
|
|
13
|
+
- **Steady-state selective work:** only 🔴/🟡 (never re-wiki 🟢 unless required). ACS suggestions use `actionable_low_conf_edges` (stdlib/external bare demoted).
|
|
14
|
+
- **Deletions:** `record-deletion` + check-changes ghost detection (missing paths → Red DELETED).
|
|
15
|
+
- **Languages:** deep import maps = Python + JS/TS. journal/pending = audit queue, not Jira.
|
|
16
|
+
- **Monitor:** optional background `monitor`/`daemon` for mtime heartbeat; agents still own wiki/mark-green.
|
|
17
|
+
- Health module: use `importlib.import_module("wikifier.health")` or `wikifier.health_module` — `from wikifier import health` is the *function*.
|
|
11
18
|
|
|
12
19
|
**v0.6 migration notes (packages v4.2.0–v4.3.0)** — changes are additive or strictly-better defaults; v0.5 agent behavior keeps working:
|
|
13
20
|
- `update-maps` (CLI) now runs the **pure-Python full pipeline**: every dirty file is parsed in-process, the canonical per-file cache is persisted, reverse deps + cycles + ACS are computed, and `library.md` is regenerated atomically. `--python-primary` is accepted but redundant; the in-shell first-pass was retired entirely (wikifier.sh's update-maps delegates to this pipeline; `--sh`/`--legacy-sh` are deprecated no-ops). Scoping is explicit via `--directory=`/`--max-files=` and reported in the result (`files_skipped`) — there are no silent caps.
|
|
@@ -24,33 +31,54 @@ This protocol + the Python package + MCP server form the bridge for consistent,
|
|
|
24
31
|
|
|
25
32
|
**This file is the primary contract for any LLM or agent operating Wikifier.**
|
|
26
33
|
|
|
34
|
+
## Agent architecture (navigability — G12)
|
|
35
|
+
|
|
36
|
+
Do **not** open megamodules (`javascript.py`, `import_cache.py`, `bree.py`) to decide workflow. Use this map:
|
|
37
|
+
|
|
38
|
+
| Need | Use |
|
|
39
|
+
|------|-----|
|
|
40
|
+
| First-run map | `init` → `update-maps` → `health --summary` → `suggest-next` |
|
|
41
|
+
| Steady-state | `check-changes` → edit 🔴/🟡 only → `record-change` → wiki → `mark-green` |
|
|
42
|
+
| Lookup | MCP Core 6: status, check_changes, needing_attention, get_file_wiki, suggest, record/mark |
|
|
43
|
+
| Deps / cycles | `get_dependencies`, `get_dependents`, `get_cycles` (json) |
|
|
44
|
+
| Deletion | `record-deletion` |
|
|
45
|
+
| Code entry | `wikifier/cli.py` (dispatch) + `wikifier/health.py` + parsers — self-tests live in `tests/` + `tests/selftest/` |
|
|
46
|
+
|
|
47
|
+
**CLI pure-Python vs shell:** mutators and maps prefer `python -m wikifier …`. Shell still owns `init`, `monitor`, `daemon`, `serve`, `journal`.
|
|
48
|
+
**Scope:** `monitored_paths` = change detection; `exclude_patterns` + optional `--directory` = map walk.
|
|
49
|
+
**Human HTML** is secondary observation only.
|
|
50
|
+
|
|
27
51
|
## Mandatory New-Session Rule
|
|
28
52
|
|
|
29
53
|
**Copy this exact block into the system prompt or the very first instruction of every new LLM session that uses Wikifier:**
|
|
30
54
|
|
|
31
55
|
```
|
|
32
|
-
You are now operating inside a Wikifier-managed codebase (Agent Protocol v0.6 —
|
|
56
|
+
You are now operating inside a Wikifier-managed codebase (Agent Protocol v0.6 — package 4.5.x).
|
|
57
|
+
|
|
58
|
+
This is strictly an agent-to-agent wiki for token saving: map lookup (health + file wikis + deps) instead of full sources; selective wiki updates; not a human docs product or Jira.
|
|
33
59
|
|
|
34
|
-
|
|
60
|
+
SELECTIVE WORK (mandatory): Only update/remove/re-wiki 🔴 Red and 🟡 Yellow files. Do not re-summarize 🟢 Green files or the whole tree. First-run builds the structural map; wiki depth is filled as you touch files.
|
|
35
61
|
|
|
36
|
-
FIRST ACTIONS
|
|
37
|
-
1.
|
|
38
|
-
2.
|
|
62
|
+
FIRST ACTIONS:
|
|
63
|
+
1. Prefer MCP tools when connected (get_project_status, get_file_wiki, check_changes, suggest_next_actions, get_dependencies, …). Always pass project_root= for external projects.
|
|
64
|
+
2. CLI/library fallback:
|
|
39
65
|
WIKIFIER_PROJECT_ROOT=/path/to/target python -m wikifier check-changes
|
|
40
|
-
python -m wikifier health --summary # or format=json/summary for machine use (token-efficient lookup)
|
|
41
|
-
... perform edit on source ...
|
|
42
|
-
python -m wikifier record-change "path/to/file" "concise semantic reason (why, not what). Include subid if agent work."
|
|
43
|
-
... write/update the wiki summary for the file ...
|
|
44
|
-
python -m wikifier mark-green "path/to/file" "Reason for Green (e.g. after autonomous agent update)."
|
|
45
|
-
if imports changed: python -m wikifier update-maps [--directory=src/] # pure-Python full pipeline by default (v4.2.0)
|
|
46
66
|
python -m wikifier health --summary
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
67
|
+
python -m wikifier suggest-next # or suggest_next_actions(format="json")
|
|
68
|
+
... edit only red/yellow sources ...
|
|
69
|
+
python -m wikifier record-change "path/to/file" "why (semantic). Include subid if agent work."
|
|
70
|
+
... update that file's wiki only ...
|
|
71
|
+
python -m wikifier mark-green "path/to/file" "reason"
|
|
72
|
+
if imports changed: python -m wikifier update-maps [--directory=src/]
|
|
73
|
+
if file removed: python -m wikifier record-deletion "path" "why"
|
|
74
|
+
python -m wikifier health --summary
|
|
75
|
+
3. Optional background: `python -m wikifier monitor` or daemon for mtime heartbeat — you still own wiki + mark-green.
|
|
76
|
+
4. Prioritize 🔴 then 🟡 from health/pending. Lookup greens via get_file_wiki; do not rewrite them.
|
|
77
|
+
5. Agent docs edits: record-change + mark-green.
|
|
78
|
+
6. Always explicit project_root / WIKIFIER_PROJECT_ROOT for external/multi-project work.
|
|
79
|
+
7. End turn: health + suggest_next_actions.
|
|
52
80
|
|
|
53
|
-
Never skip record-change —
|
|
81
|
+
Never skip record-change — semantic audit trail (journal + health + pending).
|
|
54
82
|
|
|
55
83
|
**M5+ notes (2026-06)**:
|
|
56
84
|
- External projects: always explicit root. CLI is battle-tested fallback (M5.1 MCP reliability: 60s timeout + better errors; M5 dogfood on alt BRC exact named services, 79k llvm, etc.).
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""Gap-closure regressions (G4 ACS actionable, G5 health module, G7 ghosts/deletion)."""
|
|
2
|
+
|
|
3
|
+
import importlib
|
|
4
|
+
import unittest
|
|
5
|
+
|
|
6
|
+
from tests._base import TempProjectTestCase
|
|
7
|
+
|
|
8
|
+
from wikifier import import_cache as ic
|
|
9
|
+
from wikifier import cli
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TestHealthModuleImportG5(unittest.TestCase):
|
|
13
|
+
def test_importlib_health_is_module_with_get_summary(self):
|
|
14
|
+
mod = importlib.import_module("wikifier.health")
|
|
15
|
+
self.assertTrue(hasattr(mod, "get_summary"))
|
|
16
|
+
self.assertTrue(hasattr(mod, "find_ghost_entries"))
|
|
17
|
+
self.assertTrue(callable(mod.get_summary))
|
|
18
|
+
|
|
19
|
+
def test_health_module_alias_on_package(self):
|
|
20
|
+
import wikifier
|
|
21
|
+
self.assertTrue(hasattr(wikifier, "health_module"))
|
|
22
|
+
self.assertTrue(hasattr(wikifier.health_module, "get_summary"))
|
|
23
|
+
# Convenience function still exported as wikifier.health
|
|
24
|
+
self.assertTrue(callable(wikifier.health))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class TestAcsActionableG4(TempProjectTestCase):
|
|
28
|
+
def test_external_noise_excluded_from_actionable_low_conf(self):
|
|
29
|
+
cache = {}
|
|
30
|
+
# Project-internal low-conf edge
|
|
31
|
+
ic.update_file_data(
|
|
32
|
+
cache,
|
|
33
|
+
"app.py",
|
|
34
|
+
mtime=1,
|
|
35
|
+
imports=["./util"],
|
|
36
|
+
resolved_pairs=[{
|
|
37
|
+
"raw": "./util",
|
|
38
|
+
"resolved": "util.py",
|
|
39
|
+
"resolved_path": "util.py",
|
|
40
|
+
"confidence_score": 0.4,
|
|
41
|
+
"confidence_reasons": ["base:low", "via_barrel"],
|
|
42
|
+
"confidence_explanation": "Base low. Recommendation: Review project edge.",
|
|
43
|
+
"diagnostic": {"category": "project"},
|
|
44
|
+
"resolution_metadata": {"strategy": "relative-fs"},
|
|
45
|
+
}],
|
|
46
|
+
)
|
|
47
|
+
# External/stdlib-style edge (noise)
|
|
48
|
+
ic.update_file_data(
|
|
49
|
+
cache,
|
|
50
|
+
"app.py",
|
|
51
|
+
mtime=1,
|
|
52
|
+
imports=["json", "./util"],
|
|
53
|
+
resolved_pairs=[
|
|
54
|
+
{
|
|
55
|
+
"raw": "./util",
|
|
56
|
+
"resolved": "util.py",
|
|
57
|
+
"resolved_path": "util.py",
|
|
58
|
+
"confidence_score": 0.4,
|
|
59
|
+
"confidence_reasons": ["base:low"],
|
|
60
|
+
"confidence_explanation": "Project low. Recommendation: Review.",
|
|
61
|
+
"resolution_metadata": {"strategy": "relative-fs"},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"raw": "json",
|
|
65
|
+
"resolved": "json",
|
|
66
|
+
"resolved_path": "",
|
|
67
|
+
"confidence_score": 0.48,
|
|
68
|
+
"confidence_reasons": ["base:medium", "no_resolved_path"],
|
|
69
|
+
"confidence_explanation": "stdlib. Recommendation: harden import.",
|
|
70
|
+
"diagnostic": {"category": "external_or_bare"},
|
|
71
|
+
"resolution_metadata": {"strategy": "python-bare-or-external"},
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
)
|
|
75
|
+
# Note: update_file_data may replace pairs — set explicitly
|
|
76
|
+
cache["app.py"]["resolved_pairs"] = [
|
|
77
|
+
{
|
|
78
|
+
"raw": "./util",
|
|
79
|
+
"resolved": "util.py",
|
|
80
|
+
"resolved_path": "util.py",
|
|
81
|
+
"confidence_score": 0.4,
|
|
82
|
+
"confidence_reasons": ["base:low"],
|
|
83
|
+
"confidence_explanation": "Project low. Recommendation: Review.",
|
|
84
|
+
"resolution_metadata": {"strategy": "relative-fs"},
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"raw": "json",
|
|
88
|
+
"resolved": "json",
|
|
89
|
+
"confidence_score": 0.48,
|
|
90
|
+
"confidence_reasons": ["base:medium"],
|
|
91
|
+
"confidence_explanation": "stdlib noise. Recommendation: ignore.",
|
|
92
|
+
"diagnostic": {"category": "external_or_bare"},
|
|
93
|
+
"resolution_metadata": {"strategy": "python-bare-or-external"},
|
|
94
|
+
},
|
|
95
|
+
]
|
|
96
|
+
summary = ic.compute_acs_summary(cache)
|
|
97
|
+
self.assertGreaterEqual(summary["low_conf_edges"], 1)
|
|
98
|
+
self.assertEqual(summary["actionable_low_conf_edges"], 1)
|
|
99
|
+
self.assertGreaterEqual(summary["external_noise_edges"], 1)
|
|
100
|
+
action = ic.get_low_confidence_edges(cache, actionable_only=True)
|
|
101
|
+
self.assertTrue(all(
|
|
102
|
+
(p.get("diagnostic") or {}).get("category") != "external_or_bare"
|
|
103
|
+
for p in action
|
|
104
|
+
))
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class TestGhostAndDeletionG7(TempProjectTestCase):
|
|
108
|
+
def test_find_ghost_and_record_deletion(self):
|
|
109
|
+
health_mod = importlib.import_module("wikifier.health")
|
|
110
|
+
self.write("keep.py", "x=1\n")
|
|
111
|
+
self.write("gone.py", "y=1\n")
|
|
112
|
+
health_mod.upsert_entry(self.root, "keep.py", "🟢 Green", "ok")
|
|
113
|
+
health_mod.upsert_entry(self.root, "gone.py", "🟢 Green", "ok")
|
|
114
|
+
(self.root / "gone.py").unlink()
|
|
115
|
+
|
|
116
|
+
ghosts = health_mod.find_ghost_entries(self.root)
|
|
117
|
+
self.assertIn("gone.py", ghosts)
|
|
118
|
+
self.assertNotIn("keep.py", ghosts)
|
|
119
|
+
|
|
120
|
+
res = cli.record_deletion("gone.py", "removed in cleanup", project_root=self.root)
|
|
121
|
+
self.assertTrue(res.get("success"))
|
|
122
|
+
entries = health_mod.load_health(self.root)["entries"]
|
|
123
|
+
self.assertIn("🔴", entries["gone.py"]["status"])
|
|
124
|
+
self.assertIn("DELETED", entries["gone.py"]["reason"])
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
if __name__ == "__main__":
|
|
128
|
+
unittest.main()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""G12: run extracted selftest harnesses via unittest (no harness in prod modules)."""
|
|
2
|
+
|
|
3
|
+
import runpy
|
|
4
|
+
import unittest
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
SELFTEST = Path(__file__).resolve().parent / "selftest"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TestExtractedSelftests(unittest.TestCase):
|
|
11
|
+
def _run(self, name: str):
|
|
12
|
+
path = SELFTEST / name
|
|
13
|
+
self.assertTrue(path.is_file(), f"missing {path}")
|
|
14
|
+
# Execute as __main__ so assert-based scripts raise on failure
|
|
15
|
+
try:
|
|
16
|
+
runpy.run_path(str(path), run_name="__main__")
|
|
17
|
+
except SystemExit as e:
|
|
18
|
+
if e.code not in (0, None):
|
|
19
|
+
self.fail(f"{name} exited with {e.code}")
|
|
20
|
+
|
|
21
|
+
def test_contracts_selftest(self):
|
|
22
|
+
self._run("run_contracts_selftest.py")
|
|
23
|
+
|
|
24
|
+
def test_python_parser_selftest(self):
|
|
25
|
+
self._run("run_python_parser_selftest.py")
|
|
26
|
+
|
|
27
|
+
def test_cdia_selftest(self):
|
|
28
|
+
self._run("run_cdia_selftest.py")
|
|
29
|
+
|
|
30
|
+
def test_resolution_selftest(self):
|
|
31
|
+
self._run("run_resolution_selftest.py")
|
|
32
|
+
|
|
33
|
+
def test_javascript_selftest(self):
|
|
34
|
+
# Heavier; still must pass for agent-navigable JS parser
|
|
35
|
+
self._run("run_javascript_selftest.py")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
if __name__ == "__main__":
|
|
39
|
+
unittest.main()
|
|
@@ -13,14 +13,18 @@ Zero-dependency, agent-to-agent codebase wiki. Provides:
|
|
|
13
13
|
|
|
14
14
|
The flat library API below (check_changes, record_change, mark_green,
|
|
15
15
|
health, update_maps, ...) is the preferred surface for agents calling
|
|
16
|
-
Wikifier directly from Python.
|
|
17
|
-
|
|
18
|
-
`from wikifier
|
|
16
|
+
Wikifier directly from Python.
|
|
17
|
+
|
|
18
|
+
**Health import hygiene (G5):** `from wikifier import health` is the *convenience
|
|
19
|
+
function* (cli). The real module is always `importlib.import_module("wikifier.health")`
|
|
20
|
+
or `from wikifier.health import upsert_entry, get_summary, ...`. Prefer
|
|
21
|
+
`wikifier.health_module` (alias below) over `import wikifier.health as …`, which
|
|
22
|
+
binds the function under CPython because the package attribute is shadowed.
|
|
19
23
|
"""
|
|
20
24
|
|
|
21
25
|
from . import parsers
|
|
22
26
|
from . import mcp # exposes wikifier.mcp.mcp (None when the optional extra is absent)
|
|
23
|
-
from . import health
|
|
27
|
+
from . import health as health_module # submodule — keep this name for agents/tools
|
|
24
28
|
from . import locking
|
|
25
29
|
from . import import_cache
|
|
26
30
|
from . import resolution
|
|
@@ -40,6 +44,12 @@ from .cli import (
|
|
|
40
44
|
health, # flat convenience func (delegates to the health module + adds scoping)
|
|
41
45
|
)
|
|
42
46
|
|
|
47
|
+
# Re-export module under a non-shadowed name (G5). sys.modules['wikifier.health']
|
|
48
|
+
# remains the real module; package attribute `health` is intentionally the function.
|
|
49
|
+
import sys as _sys
|
|
50
|
+
if "wikifier.health" not in _sys.modules:
|
|
51
|
+
_sys.modules["wikifier.health"] = health_module
|
|
52
|
+
|
|
43
53
|
# Shared frozen data contracts (single source of truth for shapes used by
|
|
44
54
|
# parsers, cache, MCP, and diagnostics).
|
|
45
55
|
from . import contracts
|
|
@@ -61,4 +71,4 @@ from .contracts import (
|
|
|
61
71
|
compute_acs_confidence,
|
|
62
72
|
)
|
|
63
73
|
|
|
64
|
-
__version__ = "4.5.
|
|
74
|
+
__version__ = "4.5.3"
|