3.9 KiB
lore scripts
Cross-platform Python 3.6+ helpers that reduce repetitive mechanical work. No third-party dependencies. Called by init / sync / audit / compress / lore mirror; can also be run standalone for ad-hoc inspection.
The script list and quick-reference command examples live in the project root README.md "Scripts" section. This file covers the things that don't fit there: design intent, integration points, and limits.
Design notes
Cross-platform first. Python standard library only. No bash, no jq, no platform-specific tools. The same invocation works on Windows, Linux, macOS.
JSON-friendly output. Every script supports --json for machine consumption. Agent callers parse the output; humans pipe to less or jq (if available).
Composition. find_duplicates.py and find_stale.py shell out to list_entries.py --json rather than re-implementing the parser. One source of truth for entry format — if the format ever changes, only list_entries.py needs updating.
Read-only by default. None of these scripts write to .lore/. They observe; the agent decides what to do with findings.
Run from project root. list_entries.py walks up the directory tree looking for .lore/. The other scripts depend on it via subprocess, so the same constraint applies transitively.
When each script is called
| Script | Call site | Purpose |
|---|---|---|
history.py |
lore history | List git commits related to a memory entry / file / scope |
id_hash.py |
Any time a new entry is written (init / sync) | Compute the 4-char content hash for the entry ID |
list_entries.py |
Pre-step of query / audit / compress | Enumerate all entries as JSON for downstream processing |
find_duplicates.py |
sync step 5 (de-duplication) | Identify candidate duplicate entries before writing |
find_stale.py |
audit step 2; compress step 2; lore mirror (optional) | Identify entries past the verified-date threshold or already marked #stale |
Output channels
stdout is the data channel; stderr is the warning channel. All scripts follow this split so --json consumers never have to filter noise out of their parsers. Currently list_entries.py is the only script that emits a warning:
[WARN] .lore/.config.json has no schema_version field.— fires once per invocation when the config file exists but lacks the version field. Add"schema_version": 1to silence it.[WARN] .lore/.config.json#schema_version=N is newer than this lore skill expects (max: 1).— fires when the config version exceeds what this skill understands. Pull the latest lore from upstream.
Both warnings are informational; list_entries.py always produces the same stdout regardless of config state. See references/compatibility.md for the full schema versioning policy.
Testing
Without a real .lore/, you can sanity-check that imports and argument parsing work:
python scripts/id_hash.py "test entry"
python scripts/list_entries.py # should print "(no entries)" or exit with a clear error
list_entries.py, find_duplicates.py, and find_stale.py require a populated .lore/ to produce meaningful output. Set one up via lore init first.
Limitations
- Token-overlap dedup, not semantic. Jaccard similarity catches rewrites with similar words but misses semantic equivalence (e.g. "use TypeScript" vs "TypeScript-only codebase"). Deeper checks still need an LLM pass.
- Naive date math.
find_stale.pyuses wall-clock dates from#verified/#addedtags. If the system's clock is wrong, results will be off. - No automatic archive promotion. The script reports pending-archive entries but does not move them. Use
lore syncto actually relocate to.lore/archive/. - Hash collisions on identical text are theoretically possible (4 hex chars = 16 bits = 1 in 65536). In practice a lore project will not hit this. If it does, slightly edit the entry text to bump the hash.