logseq-matryca-parser 1.4.0__tar.gz → 1.4.1__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.
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/CHANGELOG.md +11 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/CONTRIBUTING.md +6 -4
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/PKG-INFO +16 -4
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/README.md +15 -3
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/SECURITY.md +2 -2
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/ARCHITECTURE.md +7 -3
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/BUG_HUNT_REPORT.md +9 -7
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/CODEQL.md +1 -1
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/COOKBOOK.md +22 -1
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/GOOD_FIRST_ISSUES.md +49 -9
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/README.md +2 -2
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/logseq_ast_primer.md +1 -1
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/pyproject.toml +1 -1
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/__init__.py +1 -1
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/tests/test_agent_press.py +57 -0
- logseq_matryca_parser-1.4.1/tests/test_exceptions.py +62 -0
- logseq_matryca_parser-1.4.1/tests/test_extract_changelog.py +129 -0
- logseq_matryca_parser-1.4.1/tests/test_forge.py +250 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/tests/test_kinetic.py +11 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/tests/test_logos_parser.py +229 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/tests/test_logseq_paths.py +47 -0
- logseq_matryca_parser-1.4.0/tests/test_forge.py +0 -93
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.cursorignore +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.cursorrules +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.github/CODEOWNERS +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.github/FUNDING.yml +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.github/dependabot.yml +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.github/labels.yml +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.github/scripts/create_good_first_issues.sh +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.github/workflows/ci.yml +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.github/workflows/daily-metrics.yml +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.github/workflows/github_release.yml +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.github/workflows/pypi_publish.yml +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.gitignore +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.pre-commit-config.yaml +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/.repomixignore +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/CODE_OF_CONDUCT.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/LICENSE +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/Makefile +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/NOTICE +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/claude-skill-logseq-read/SKILL.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/claude-skill-logseq-read/scripts/parse_logseq.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/RELEASE_PROCESS.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/design-docs/ARCHITECTURE_BLUEPRINT.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/design-docs/CODE_SCAFFOLD.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/design-docs/LOGSEQ_ASSET_RESOLUTION_SPEC.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/design-docs/LOGSEQ_DATASCRIPT_MAPPING.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/design-docs/LOGSEQ_TEMPORAL_ONTOLOGY.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/design-docs/OFFICIAL_MLDOC_SPECS.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/design-docs/README.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/design-docs/REFERENCE_SPEC.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/error_log.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/internal/STATIC_ANALYSIS_POLICY.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/rfc/OLLAMA_RAG.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/roadmaps/ROADMAP_AGENT_NATIVE_XRAY.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/roadmaps/ROADMAP_CLI_HYDRATION_AND_ENRICHMENT.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/roadmaps/ROADMAP_CONTEXT_SYNTHESIS_AND_SCOPING.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/roadmaps/ROADMAP_EMBED_EXPANSION_AND_FLUENT_QUERIES.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/roadmaps/ROADMAP_GRAPH_RAG_SEMANTICS.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/roadmaps/ROADMAP_HEADLESS_WRITER.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/roadmaps/ROADMAP_INCREMENTAL_WATCHER.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/roadmaps/ROADMAP_INLINE_SHIELD_AND_NAMESPACES.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/roadmaps/ROADMAP_OBSIDIAN_ADAPTER.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/roadmaps/ROADMAP_ROBUSTNESS_AND_SOFT_BREAKS.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/roadmaps/ROADMAP_TOML_FIX_AND_PYPI_DISTRIBUTION.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/docs/roadmaps/ROADMAP_UUID_AND_GRAPH_SUPERPOWERS.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/examples/demo_logseq_journal.md +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/examples/run_demo.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/legacy/local_digestor.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/lib/bindings/utils.js +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/lib/tom-select/tom-select.complete.min.js +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/lib/tom-select/tom-select.css +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/lib/vis-9.1.2/vis-network.css +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/lib/vis-9.1.2/vis-network.min.js +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/metrics/history.json +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/repomix-output-parser.xml +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/scripts/__init__.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/scripts/archive_repository_metrics.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/scripts/debug_pre_release.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/scripts/extract_changelog.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/.gitignore +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/NOTICE +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/__main__.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/agent_press.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/agent_writer.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/exceptions.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/forge.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/graph.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/kinetic.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/lens.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/logos_core.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/logos_parser.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/logseq_markdown.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/logseq_paths.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/pyproject.toml +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/src/logseq_matryca_parser/synapse.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/tests/test_agent_writer.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/tests/test_archive_repository_metrics.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/tests/test_graph.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/tests/test_lens.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/tests/test_logseq_markdown.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/tests/test_package_version.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/tests/test_pre_release_roundtrip.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/tests/test_synapse.py +0 -0
- {logseq_matryca_parser-1.4.0 → logseq_matryca_parser-1.4.1}/uv.lock +0 -0
|
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.4.1] - 2026-06-24
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Test coverage (wave 1)** — Community contribution ([#42](https://github.com/MarcoPorcellato/logseq-matryca-parser/pull/42)): **107** new pytest cases (**378** total) across parser helpers (`normalize_logseq_timestamp`, `clean_node_content`), `logseq_paths` fallbacks, exception hierarchy, `extract_changelog` release script, KINETIC per-command `--help`, `agent-read --query`, and direct `ObsidianForgeVisitor` tests. New modules: `tests/test_exceptions.py`, `tests/test_extract_changelog.py`. Closes [#21](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/21)–[#24](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/24), [#27](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/27), [#30](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/30)–[#32](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/32).
|
|
15
|
+
- **Good first issues (wave 2)** — Ten new contributor tasks ([#43](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/43)–[#52](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/52)) indexed as GFI-17–GFI-26 in [`docs/GOOD_FIRST_ISSUES.md`](docs/GOOD_FIRST_ISSUES.md); wave-1 GFI items marked complete.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **Contributor docs** — [`README.md`](README.md), [`docs/README.md`](docs/README.md), [`CONTRIBUTING.md`](CONTRIBUTING.md), [`SECURITY.md`](SECURITY.md), and [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) harmonized for **v1.4.1** (test count, issue index range, supported versions).
|
|
20
|
+
|
|
10
21
|
## [1.4.0] - 2026-06-23
|
|
11
22
|
|
|
12
23
|
### Added
|
|
@@ -15,7 +15,7 @@ User-facing behavior is documented in:
|
|
|
15
15
|
- [`README.md`](README.md) — overview, quickstart, and feature matrix
|
|
16
16
|
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — LOGOS, SYNAPSE, `LogseqGraph`, agents, and data flow
|
|
17
17
|
- [`docs/logseq_ast_primer.md`](docs/logseq_ast_primer.md) — Logseq Spatial Markdown domain rules
|
|
18
|
-
- [`CHANGELOG.md`](CHANGELOG.md) — shipped releases (current: **1.4.
|
|
18
|
+
- [`CHANGELOG.md`](CHANGELOG.md) — shipped releases (current: **1.4.1**) and **Unreleased** changes (Keep a Changelog)
|
|
19
19
|
- [`docs/RELEASE_PROCESS.md`](docs/RELEASE_PROCESS.md) — version bump, tag, and PyPI publish checklist
|
|
20
20
|
- [`docs/CODEQL.md`](docs/CODEQL.md) — CodeQL default setup (no custom `codeql.yml`)
|
|
21
21
|
- [`docs/GOOD_FIRST_ISSUES.md`](docs/GOOD_FIRST_ISSUES.md) — curated starter tasks for new contributors
|
|
@@ -44,7 +44,7 @@ New to the codebase? Start here:
|
|
|
44
44
|
2. **Comment on the issue** so others know you are working on it.
|
|
45
45
|
3. **Set up** with `uv sync --all-extras` and confirm `make all` is green on `main`.
|
|
46
46
|
4. **Branch** using `feat/…`, `test/…`, or `docs/…` naming (see workflow below).
|
|
47
|
-
5. **Submit**
|
|
47
|
+
5. **Submit** one PR per issue, branched from `main` (`Fixes #123`).
|
|
48
48
|
|
|
49
49
|
Tier 1 tasks are **test-only** — no parser changes, ideal for learning `CliRunner` and pytest patterns in `tests/`. Tier 2 is documentation. Tier 3 adds small CLI or FORGE features with explicit acceptance criteria.
|
|
50
50
|
|
|
@@ -124,6 +124,8 @@ CI runs the same commands as your local environment: `uv sync --all-extras`, the
|
|
|
124
124
|
make all
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
+
As of **v1.4.1**, `make test` runs **378** pytest cases with **≥80%** line coverage on `src/logseq_matryca_parser` (currently ~**90%**). New contributors should mirror patterns in [`docs/GOOD_FIRST_ISSUES.md`](docs/GOOD_FIRST_ISSUES.md) and the module map in that file’s **Test suite** section.
|
|
128
|
+
|
|
127
129
|
Or run each step individually:
|
|
128
130
|
|
|
129
131
|
```bash
|
|
@@ -150,9 +152,9 @@ We follow [Conventional Commits](https://www.conventionalcommits.org/). Your com
|
|
|
150
152
|
|
|
151
153
|
### 6. Submit a Pull Request (PR)
|
|
152
154
|
|
|
153
|
-
- Push your branch and open a PR against the `main` branch.
|
|
155
|
+
- Push your branch and open a PR against the `main` branch (**one issue per PR**).
|
|
154
156
|
- Describe why the change is needed.
|
|
155
|
-
- Link the relevant Issue (e.g., `Fixes #123`).
|
|
157
|
+
- Link the relevant Issue (e.g., `Fixes #123`). **One issue per PR** — do not stack multiple issues on a single branch.
|
|
156
158
|
- Ensure all GitHub Actions (CI) checks pass.
|
|
157
159
|
|
|
158
160
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: logseq-matryca-parser
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.1
|
|
4
4
|
Summary: The Logos Protocol: Deterministic Logseq AST parsing for Matryca.ai.
|
|
5
5
|
Project-URL: Homepage, https://github.com/MarcoPorcellato/logseq-matryca-parser
|
|
6
6
|
Project-URL: Repository, https://github.com/MarcoPorcellato/logseq-matryca-parser
|
|
@@ -53,7 +53,7 @@ Description-Content-Type: text/markdown
|
|
|
53
53
|
[](#)
|
|
54
54
|

|
|
55
55
|
|
|
56
|
-
**v1.4.
|
|
56
|
+
**v1.4.1** — Test-hardening patch: **378 tests** (+107), community coverage for parser helpers, CLI agents, FORGE visitors, and wave-2 good-first issues ([#43](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/43)–[#52](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/52)) — no production API changes (see [CHANGELOG](CHANGELOG.md)).
|
|
57
57
|
|
|
58
58
|
> *Turning a forest of local plain-text files into a unified semantic powerhouse.*
|
|
59
59
|
|
|
@@ -147,6 +147,18 @@ Logseq Matryca Parser is a deterministic **Stack-Machine engine** that acts as t
|
|
|
147
147
|
|
|
148
148
|
---
|
|
149
149
|
|
|
150
|
+
## ⚡ Release highlights (v1.4.1)
|
|
151
|
+
|
|
152
|
+
Patch release — contributor test coverage and onboarding refresh. **No intentional changes** to parser, graph, or CLI runtime behavior.
|
|
153
|
+
|
|
154
|
+
| Area | Change |
|
|
155
|
+
| :--- | :--- |
|
|
156
|
+
| **Test suite** | **378** pytest cases (**+107** vs v1.4.0): `normalize_logseq_timestamp`, `clean_node_content`, `logseq_paths` fallbacks, exception hierarchy, `extract_changelog` script, KINETIC `--help`, `agent-read --query`, direct `ObsidianForgeVisitor` tests ([#42](https://github.com/MarcoPorcellato/logseq-matryca-parser/pull/42)). |
|
|
157
|
+
| **New test modules** | `tests/test_exceptions.py`, `tests/test_extract_changelog.py`. |
|
|
158
|
+
| **Contributor index** | [`docs/GOOD_FIRST_ISSUES.md`](docs/GOOD_FIRST_ISSUES.md) wave 2 ([#43](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/43)–[#52](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/52)); wave-1 items marked complete. |
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
150
162
|
## ⚡ Release highlights (v1.4.0)
|
|
151
163
|
|
|
152
164
|
Minor release — graph integrity, export hygiene, and parser hardening from the local static-analysis bug hunt (waves 1–8). No intentional breaking changes to default parse behavior.
|
|
@@ -361,7 +373,7 @@ Marker syntax (`[#A]`, `SCHEDULED: <...>`, `DEADLINE: <...>`) is stripped from `
|
|
|
361
373
|
## 🛠️ Quickstart
|
|
362
374
|
|
|
363
375
|
```bash
|
|
364
|
-
# Install from PyPI (latest: v1.4.
|
|
376
|
+
# Install from PyPI (latest: v1.4.1)
|
|
365
377
|
uv pip install logseq-matryca-parser
|
|
366
378
|
|
|
367
379
|
# Optional: filesystem watcher for live incremental graph updates
|
|
@@ -458,7 +470,7 @@ We welcome issues, pull requests, and constructive feedback.
|
|
|
458
470
|
|
|
459
471
|
| Resource | Link |
|
|
460
472
|
| :--- | :--- |
|
|
461
|
-
| **Good first issues** | [docs/GOOD_FIRST_ISSUES.md](docs/GOOD_FIRST_ISSUES.md) — starter tasks ([#19](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/19)–[#
|
|
473
|
+
| **Good first issues** | [docs/GOOD_FIRST_ISSUES.md](docs/GOOD_FIRST_ISSUES.md) — starter tasks ([#19](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/19)–[#52](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/52)) |
|
|
462
474
|
| **Contributing** | [CONTRIBUTING.md](CONTRIBUTING.md) — setup, tests, PR workflow |
|
|
463
475
|
| **Cookbook** | [docs/COOKBOOK.md](docs/COOKBOOK.md) — integration recipes (Synapse, graph query, watcher) |
|
|
464
476
|
| **Documentation index** | [docs/README.md](docs/README.md) — active vs historical docs |
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
[](#)
|
|
13
13
|

|
|
14
14
|
|
|
15
|
-
**v1.4.
|
|
15
|
+
**v1.4.1** — Test-hardening patch: **378 tests** (+107), community coverage for parser helpers, CLI agents, FORGE visitors, and wave-2 good-first issues ([#43](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/43)–[#52](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/52)) — no production API changes (see [CHANGELOG](CHANGELOG.md)).
|
|
16
16
|
|
|
17
17
|
> *Turning a forest of local plain-text files into a unified semantic powerhouse.*
|
|
18
18
|
|
|
@@ -106,6 +106,18 @@ Logseq Matryca Parser is a deterministic **Stack-Machine engine** that acts as t
|
|
|
106
106
|
|
|
107
107
|
---
|
|
108
108
|
|
|
109
|
+
## ⚡ Release highlights (v1.4.1)
|
|
110
|
+
|
|
111
|
+
Patch release — contributor test coverage and onboarding refresh. **No intentional changes** to parser, graph, or CLI runtime behavior.
|
|
112
|
+
|
|
113
|
+
| Area | Change |
|
|
114
|
+
| :--- | :--- |
|
|
115
|
+
| **Test suite** | **378** pytest cases (**+107** vs v1.4.0): `normalize_logseq_timestamp`, `clean_node_content`, `logseq_paths` fallbacks, exception hierarchy, `extract_changelog` script, KINETIC `--help`, `agent-read --query`, direct `ObsidianForgeVisitor` tests ([#42](https://github.com/MarcoPorcellato/logseq-matryca-parser/pull/42)). |
|
|
116
|
+
| **New test modules** | `tests/test_exceptions.py`, `tests/test_extract_changelog.py`. |
|
|
117
|
+
| **Contributor index** | [`docs/GOOD_FIRST_ISSUES.md`](docs/GOOD_FIRST_ISSUES.md) wave 2 ([#43](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/43)–[#52](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/52)); wave-1 items marked complete. |
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
109
121
|
## ⚡ Release highlights (v1.4.0)
|
|
110
122
|
|
|
111
123
|
Minor release — graph integrity, export hygiene, and parser hardening from the local static-analysis bug hunt (waves 1–8). No intentional breaking changes to default parse behavior.
|
|
@@ -320,7 +332,7 @@ Marker syntax (`[#A]`, `SCHEDULED: <...>`, `DEADLINE: <...>`) is stripped from `
|
|
|
320
332
|
## 🛠️ Quickstart
|
|
321
333
|
|
|
322
334
|
```bash
|
|
323
|
-
# Install from PyPI (latest: v1.4.
|
|
335
|
+
# Install from PyPI (latest: v1.4.1)
|
|
324
336
|
uv pip install logseq-matryca-parser
|
|
325
337
|
|
|
326
338
|
# Optional: filesystem watcher for live incremental graph updates
|
|
@@ -417,7 +429,7 @@ We welcome issues, pull requests, and constructive feedback.
|
|
|
417
429
|
|
|
418
430
|
| Resource | Link |
|
|
419
431
|
| :--- | :--- |
|
|
420
|
-
| **Good first issues** | [docs/GOOD_FIRST_ISSUES.md](docs/GOOD_FIRST_ISSUES.md) — starter tasks ([#19](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/19)–[#
|
|
432
|
+
| **Good first issues** | [docs/GOOD_FIRST_ISSUES.md](docs/GOOD_FIRST_ISSUES.md) — starter tasks ([#19](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/19)–[#52](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/52)) |
|
|
421
433
|
| **Contributing** | [CONTRIBUTING.md](CONTRIBUTING.md) — setup, tests, PR workflow |
|
|
422
434
|
| **Cookbook** | [docs/COOKBOOK.md](docs/COOKBOOK.md) — integration recipes (Synapse, graph query, watcher) |
|
|
423
435
|
| **Documentation index** | [docs/README.md](docs/README.md) — active vs historical docs |
|
|
@@ -6,8 +6,8 @@ Security fixes are provided **only for the latest released version** on [PyPI](h
|
|
|
6
6
|
|
|
7
7
|
| Version | Supported |
|
|
8
8
|
| ------- | --------- |
|
|
9
|
-
| **1.4.
|
|
10
|
-
|
|
|
9
|
+
| **1.4.1** (latest) | Yes |
|
|
10
|
+
| 1.4.0 and older | No |
|
|
11
11
|
|
|
12
12
|
We recommend always running the current release and upgrading promptly when a security advisory is published.
|
|
13
13
|
|
|
@@ -557,7 +557,11 @@ Recursive and character-budget chunkers assume **approximately flat prose**. Log
|
|
|
557
557
|
| :--- | :--- |
|
|
558
558
|
| [`logseq_ast_primer.md`](logseq_ast_primer.md) | Before touching parser or serialization behavior |
|
|
559
559
|
| [`COOKBOOK.md`](COOKBOOK.md) | Integration examples (Synapse, `LogseqGraph`, watcher) |
|
|
560
|
-
| [`GOOD_FIRST_ISSUES.md`](GOOD_FIRST_ISSUES.md) | Picking a first PR ([#19](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/19)–[#
|
|
561
|
-
| [`README.md`](README.md) |
|
|
562
|
-
| [`../CONTRIBUTING.md`](../CONTRIBUTING.md) | `uv` setup, `make all
|
|
560
|
+
| [`GOOD_FIRST_ISSUES.md`](GOOD_FIRST_ISSUES.md) | Picking a first PR ([#19](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/19)–[#52](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/52)); wave 1 tests landed in **v1.4.1** |
|
|
561
|
+
| [`README.md`](README.md) | Project overview and quickstart |
|
|
562
|
+
| [`../CONTRIBUTING.md`](../CONTRIBUTING.md) | `uv` setup, `make all` (**378** pytest, ~**90%** coverage), PR checklist |
|
|
563
563
|
| [`design-docs/README.md`](design-docs/README.md) | Warning before using historical DDD blueprints |
|
|
564
|
+
|
|
565
|
+
### Quality gate (v1.4.1)
|
|
566
|
+
|
|
567
|
+
Local and CI parity: `uv sync --all-extras` → `make lint` → `make check` → `make test`. The test gate enforces **≥80%** coverage on `src/logseq_matryca_parser` with **378** pytest cases as of **v1.4.1** (community wave 1 via [#42](https://github.com/MarcoPorcellato/logseq-matryca-parser/pull/42)). Dedicated modules: `tests/test_exceptions.py`, `tests/test_extract_changelog.py` — see [`GOOD_FIRST_ISSUES.md`](GOOD_FIRST_ISSUES.md) § Test suite.
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
**Strumenti:** analisi statica locale (graph-based), `make all`, `scripts/debug_pre_release.py`, probe Python ad hoc
|
|
6
6
|
**Riferimenti architetturali:** [Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html) (R. C. Martin), [`ARCHITECTURE.md`](ARCHITECTURE.md)
|
|
7
7
|
|
|
8
|
-
> **Stato risoluzione (2026-06-23):** tutti i **BUG-001…031** e le limitazioni **LIM-001/002** sono stati affrontati nel codice (vedi `CHANGELOG.md`
|
|
8
|
+
> **Stato risoluzione (2026-06-23):** tutti i **BUG-001…031** e le limitazioni **LIM-001/002** sono stati affrontati nel codice (vedi `CHANGELOG.md` **v1.4.0**). **DEBT-001** (`iter_canonical_pages`, `page_for_node`) è implementato; debito architetturale residuo (SRP su `kinetic.py`, OCP embed strategy) resta backlog non bloccante.
|
|
9
|
+
>
|
|
10
|
+
> **Aggiornamento test (2026-06-24, v1.4.1):** GFI-04 (`logseq_paths` fallback), GFI-14 (`normalize_logseq_timestamp`), GFI-03/05/06/09/12/13 e suite totale **378** pytest — vedi `CHANGELOG.md` **v1.4.1**.
|
|
9
11
|
|
|
10
12
|
---
|
|
11
13
|
|
|
@@ -13,8 +15,8 @@
|
|
|
13
15
|
|
|
14
16
|
| Metrica | Esito |
|
|
15
17
|
| :--- | :--- |
|
|
16
|
-
| `make all` (Ruff + Mypy +
|
|
17
|
-
| Coverage | **
|
|
18
|
+
| `make all` (Ruff + Mypy + 378 pytest) | **PASS** |
|
|
19
|
+
| Coverage | **90.18%** (soglia 80%; **378** pytest, v1.4.1) |
|
|
18
20
|
| Round-trip corpus (`debug_pre_release.py`) | **19/19 OK** |
|
|
19
21
|
| analisi statica `check` (cicli IMPORTS) | **0 cicli** |
|
|
20
22
|
| analisi statica index | `logseq-matryca-parser` — 1074 embeddings, commit `7d3f77b` |
|
|
@@ -855,7 +857,7 @@ page_title_to_relative_path('') → PosixPath('untitled.md')
|
|
|
855
857
|
write_logseq_page(page, dest) → scrive su pages/untitled.md (non crash)
|
|
856
858
|
```
|
|
857
859
|
|
|
858
|
-
Comportamento diverso dalla nota precedente (non più `Errno 21` su path vuoto grazie al fallback `untitled.md`). Resta ambiguo per vault reali. Copertura
|
|
860
|
+
Comportamento diverso dalla nota precedente (non più `Errno 21` su path vuoto grazie al fallback `untitled.md`). Resta ambiguo per vault reali. **Copertura:** GFI-04 chiuso in **v1.4.1** (`tests/test_logseq_paths.py`).
|
|
859
861
|
|
|
860
862
|
---
|
|
861
863
|
|
|
@@ -871,7 +873,7 @@ Valutazione secondo i principi di R. C. Martin, senza implicare che il codice si
|
|
|
871
873
|
| **ISP** | Adapter SYNAPSE accede a `graph._page_for_node` (privato) | `synapse.py` L222 | Esporre `graph.page_for_node()` pubblico o protocol `GraphLookup`. |
|
|
872
874
|
| **DIP** | Import lazy `logseq_paths` dentro metodo entity | `logos_core.py` L144 | Accettabile per evitare cicli; alternativa: spostare `resolve_asset_path` in use case layer. |
|
|
873
875
|
| **Boundaries** | `assert bm is not None` in produzione | `synapse.py` L171, L190 | Sostituire con guard espliciti (Clean Code: fail fast leggibile, no assert in `-O`). |
|
|
874
|
-
| **Error handling** | `except ValueError: pass` in normalizzazione timestamp | `logos_parser.py` L500 | Accettabile come fallback chain;
|
|
876
|
+
| **Error handling** | `except ValueError: pass` in normalizzazione timestamp | `logos_parser.py` L500 | Accettabile come fallback chain; **GFI-14 chiuso in v1.4.1** (`tests/test_logos_parser.py`). |
|
|
875
877
|
| **ISP / encapsulation** | Consumer iterano `graph.pages.values()` raw | `kinetic.py`, `graph.py` | `iter_canonical_pages()` — DEBT-001; radice di BUG-002/006/007. |
|
|
876
878
|
| **Use case completeness** | Nessun ramo *delete* in invalidazione incrementale | `graph.py` L641 | BUG-005; watcher senza delete/move — BUG-014 |
|
|
877
879
|
|
|
@@ -895,7 +897,7 @@ Linee non coperte con **alto rischio funzionale** (non solo numeri):
|
|
|
895
897
|
| `logseq_markdown.py` | round-trip 4-space indent | **Alto** — BUG-021 |
|
|
896
898
|
| `graph.py` | ghost nodes in search/query/agent-read | **Alto** — BUG-022 (con BUG-010) |
|
|
897
899
|
| `kinetic.py` | `_export_langchain_enriched` alias dupes | **Alto** — BUG-006 |
|
|
898
|
-
| `logseq_paths.py` | titolo vuoto, fallback graph root | **
|
|
900
|
+
| `logseq_paths.py` | titolo vuoto, fallback graph root | **Risolto (v1.4.1)** — GFI-04 |
|
|
899
901
|
|
|
900
902
|
---
|
|
901
903
|
|
|
@@ -919,7 +921,7 @@ Linee non coperte con **alto rischio funzionale** (non solo numeri):
|
|
|
919
921
|
| P3 | BUG-004 | Decisione ISO vs `%W` + doc/test | 1 h |
|
|
920
922
|
| P4 | BUG-008, BUG-009, BUG-015, BUG-018–020, BUG-024–025, BUG-028–031 | case/`#`/namespace; export dup; asset path | backlog |
|
|
921
923
|
| P5 | Debito | `graph.page_for_node` pubblico; rimuovere `assert` | 2 h |
|
|
922
|
-
| P6 | Coverage | Chiudere GFI-01, GFI-02
|
|
924
|
+
| P6 | Coverage | Chiudere GFI-01, GFI-02; wave 2 ([#43](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/43)–[#52](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/52)) | backlog |
|
|
923
925
|
|
|
924
926
|
Dopo ogni fix: `make all` + `refresh dell'indice locale` + `impact` sul simbolo modificato.
|
|
925
927
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CodeQL code scanning
|
|
2
2
|
|
|
3
|
-
**Logseq Matryca Parser** (v1.4.
|
|
3
|
+
**Logseq Matryca Parser** (v1.4.1+) uses **GitHub CodeQL default setup** for static analysis (SAST) on Python.
|
|
4
4
|
|
|
5
5
|
## Why there is no `codeql.yml` workflow
|
|
6
6
|
|
|
@@ -127,7 +127,28 @@ if broken:
|
|
|
127
127
|
print("broken ref in", node.clean_text)
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
**CLI tip:** run `matryca-parse export` after `load_directory` — KINETIC scans canonical pages internally (v1.4.0).
|
|
130
|
+
**CLI tip:** run `matryca-parse export` after `load_directory` — KINETIC scans canonical pages internally (since v1.4.0).
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Recipe 6 — Contributor test patterns
|
|
135
|
+
|
|
136
|
+
Pick a scoped task from [`GOOD_FIRST_ISSUES.md`](GOOD_FIRST_ISSUES.md) (wave 2: [#43](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/43)–[#52](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/52)), then mirror nearby tests:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
uv sync --all-extras
|
|
140
|
+
make all # 378 pytest cases, ≥80% coverage gate
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
| Pattern | Example module | Test file |
|
|
144
|
+
| :--- | :--- | :--- |
|
|
145
|
+
| Pure helper | `normalize_logseq_timestamp` | `tests/test_logos_parser.py` |
|
|
146
|
+
| CLI `--help` / errors | `kinetic.py` | `tests/test_kinetic.py` |
|
|
147
|
+
| FORGE visitor | `ObsidianForgeVisitor` | `tests/test_forge.py` |
|
|
148
|
+
| Release script | `scripts/extract_changelog.py` | `tests/test_extract_changelog.py` |
|
|
149
|
+
| Exception hierarchy | `exceptions.py` | `tests/test_exceptions.py` |
|
|
150
|
+
|
|
151
|
+
Test-only PRs should not change runtime behavior — update `CHANGELOG.md` under `[Unreleased]` only when user-visible behavior changes.
|
|
131
152
|
|
|
132
153
|
---
|
|
133
154
|
|
|
@@ -7,7 +7,7 @@ Welcome! These tasks are scoped for a **first pull request** — mostly tests an
|
|
|
7
7
|
1. Read [`CONTRIBUTING.md`](../CONTRIBUTING.md), [`ARCHITECTURE.md`](ARCHITECTURE.md) (skim the module map), and [`logseq_ast_primer.md`](logseq_ast_primer.md) if you touch parsing.
|
|
8
8
|
2. Run `uv sync --all-extras` then `make all` to confirm a green baseline.
|
|
9
9
|
3. Comment on the GitHub issue you want to claim so we avoid duplicate work.
|
|
10
|
-
4. Open
|
|
10
|
+
4. Open **one PR per issue**, branched from `main` (`Fixes #NNN`).
|
|
11
11
|
|
|
12
12
|
Integrators may prefer [`COOKBOOK.md`](COOKBOOK.md) for copy-paste recipes before picking a code task.
|
|
13
13
|
|
|
@@ -23,10 +23,18 @@ Ideal first PR: no production code changes, copy patterns from nearby tests.
|
|
|
23
23
|
| :--- | :--- | :--- | :--- |
|
|
24
24
|
| GFI-01 | `test(kinetic): add CLI error-path coverage for missing graph and optional deps` | pytest, Typer | [#19](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/19) |
|
|
25
25
|
| GFI-02 | `test(kinetic): cover agent-write validation errors` | pytest, CLI | [#20](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/20) |
|
|
26
|
-
| GFI-03 | `test: add dedicated tests for exception hierarchy` | pytest | [#21](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/21) |
|
|
27
|
-
| GFI-04 | `test(logseq_paths): cover empty title and fallback graph-root derivation` | pytest | [#22](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/22) |
|
|
28
|
-
| GFI-05 | `test: add unit tests for extract_changelog release helper` | pytest | [#23](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/23) |
|
|
29
|
-
| GFI-06 | `test(agent): add CLI test for agent-read --query filter` | pytest, CLI | [#24](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/24) |
|
|
26
|
+
| GFI-03 | `test: add dedicated tests for exception hierarchy` | pytest | [#21](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/21) ✅ |
|
|
27
|
+
| GFI-04 | `test(logseq_paths): cover empty title and fallback graph-root derivation` | pytest | [#22](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/22) ✅ |
|
|
28
|
+
| GFI-05 | `test: add unit tests for extract_changelog release helper` | pytest | [#23](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/23) ✅ |
|
|
29
|
+
| GFI-06 | `test(agent): add CLI test for agent-read --query filter` | pytest, CLI | [#24](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/24) ✅ |
|
|
30
|
+
| GFI-17 | `test(logseq_markdown): unit tests for detect_tab_size_from_markdown` | pytest | [#43](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/43) |
|
|
31
|
+
| GFI-18 | `test(synapse): table-driven tests for _strip_markdown_for_embedding` | pytest | [#44](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/44) |
|
|
32
|
+
| GFI-19 | `test(graph): unit tests for _normalize_relative_link_target helper` | pytest | [#45](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/45) |
|
|
33
|
+
| GFI-20 | `test(extract_changelog): cover main() CLI exit codes and stdout` | pytest | [#47](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/47) |
|
|
34
|
+
| GFI-21 | `test(agent_writer): cover LogseqConfigReader format_timestamp and config fallback` | pytest, CLI | [#48](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/48) |
|
|
35
|
+
| GFI-22 | `test(lens): classify journal and project nodes in GraphVisualizer` | pytest | [#49](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/49) |
|
|
36
|
+
| GFI-23 | `test(graph): unit tests for backlink alias token helpers` | pytest | [#50](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/50) |
|
|
37
|
+
| GFI-24 | `test(synapse): direct build_synapse_metadata schema coverage` | pytest | [#51](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/51) |
|
|
30
38
|
|
|
31
39
|
---
|
|
32
40
|
|
|
@@ -36,7 +44,7 @@ Ideal first PR: no production code changes, copy patterns from nearby tests.
|
|
|
36
44
|
| :--- | :--- | :--- | :--- |
|
|
37
45
|
| GFI-07 | `docs: add examples cookbook for common integration recipes` | Markdown, Python snippets | [#25](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/25) *(initial [`COOKBOOK.md`](COOKBOOK.md) landed — extend or polish)* |
|
|
38
46
|
| GFI-08 | `docs: add docs/README.md index warning about historical design-docs` | Markdown | [#26](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/26) *(index exists — verify links and `design-docs/README.md`)* |
|
|
39
|
-
| GFI-09 | `test(kinetic): assert per-command --help renders without error` | pytest, Typer | [#27](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/27) |
|
|
47
|
+
| GFI-09 | `test(kinetic): assert per-command --help renders without error` | pytest, Typer | [#27](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/27) ✅ |
|
|
40
48
|
| GFI-10 | `docs(examples): translate run_demo.py comments to English and align with package imports` | Python, docs | [#28](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/28) *(done in repo — close if satisfied)* |
|
|
41
49
|
|
|
42
50
|
---
|
|
@@ -46,9 +54,11 @@ Ideal first PR: no production code changes, copy patterns from nearby tests.
|
|
|
46
54
|
| ID | Title | Skills | Issue |
|
|
47
55
|
| :--- | :--- | :--- | :--- |
|
|
48
56
|
| GFI-11 | `feat(cli): add scan --broken-refs flag using LogseqGraph.get_broken_references()` | Typer, graph API | [#29](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/29) |
|
|
49
|
-
| GFI-12 | `test(forge): add direct ObsidianForgeVisitor visitor tests` | pytest, FORGE | [#30](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/30) |
|
|
50
|
-
| GFI-13 | `test(parser): table-driven tests for clean_node_content helper` | pytest | [#31](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/31) |
|
|
51
|
-
| GFI-14 | `test(parser): unit tests for normalize_logseq_timestamp edge inputs` | pytest | [#32](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/32) |
|
|
57
|
+
| GFI-12 | `test(forge): add direct ObsidianForgeVisitor visitor tests` | pytest, FORGE | [#30](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/30) ✅ |
|
|
58
|
+
| GFI-13 | `test(parser): table-driven tests for clean_node_content helper` | pytest | [#31](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/31) ✅ |
|
|
59
|
+
| GFI-14 | `test(parser): unit tests for normalize_logseq_timestamp edge inputs` | pytest | [#32](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/32) ✅ |
|
|
60
|
+
| GFI-25 | `test(forge): direct MarkdownForgeVisitor property and id filtering` | pytest, FORGE | [#46](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/46) |
|
|
61
|
+
| GFI-26 | `test(forge): direct JSONForgeVisitor nested stack behavior` | pytest, FORGE | [#52](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/52) |
|
|
52
62
|
|
|
53
63
|
---
|
|
54
64
|
|
|
@@ -61,6 +71,36 @@ Ideal first PR: no production code changes, copy patterns from nearby tests.
|
|
|
61
71
|
|
|
62
72
|
---
|
|
63
73
|
|
|
74
|
+
## Recommended starter pack (wave 2)
|
|
75
|
+
|
|
76
|
+
Best first picks from the new batch — pure helpers or clear fixtures:
|
|
77
|
+
|
|
78
|
+
| Priority | ID | Why |
|
|
79
|
+
| :---: | :--- | :--- |
|
|
80
|
+
| 1 | GFI-19 ([#45](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/45)) | Pure function, parametrized table |
|
|
81
|
+
| 2 | GFI-18 ([#44](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/44)) | Pure regex helper, high clarity |
|
|
82
|
+
| 3 | GFI-17 ([#43](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/43)) | Small markdown utility, no graph I/O |
|
|
83
|
+
| 4 | GFI-25 ([#46](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/46)) | Mirrors merged Obsidian visitor tests |
|
|
84
|
+
| 5 | GFI-20 ([#47](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/47)) | Extends existing `test_extract_changelog.py` |
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Test suite (v1.4.1)
|
|
89
|
+
|
|
90
|
+
| Module | Test file |
|
|
91
|
+
| :--- | :--- |
|
|
92
|
+
| Parser (LOGOS) | `tests/test_logos_parser.py` |
|
|
93
|
+
| Graph & watcher | `tests/test_graph.py` |
|
|
94
|
+
| SYNAPSE adapters | `tests/test_synapse.py` |
|
|
95
|
+
| FORGE exporters | `tests/test_forge.py` |
|
|
96
|
+
| KINETIC CLI | `tests/test_kinetic.py` |
|
|
97
|
+
| Agent read/write | `tests/test_agent_press.py`, `tests/test_agent_writer.py` |
|
|
98
|
+
| Paths & markdown | `tests/test_logseq_paths.py`, `tests/test_logseq_markdown.py` |
|
|
99
|
+
| Release helpers | `tests/test_extract_changelog.py`, `tests/test_package_version.py` |
|
|
100
|
+
| Exceptions | `tests/test_exceptions.py` |
|
|
101
|
+
|
|
102
|
+
Run the full gate: `make all` (**378** pytest cases as of **v1.4.1**).
|
|
103
|
+
|
|
64
104
|
## Out of scope for a first PR
|
|
65
105
|
|
|
66
106
|
- Changes to Pydantic models in `logos_core.py` (open a design issue first).
|
|
@@ -8,8 +8,8 @@ Use this page to find **active** documentation. Files under [`design-docs/`](des
|
|
|
8
8
|
| :--- | :--- | :--- |
|
|
9
9
|
| [`ARCHITECTURE.md`](ARCHITECTURE.md) | Contributors, integrators | LOGOS, SYNAPSE, `LogseqGraph`, agents, data flow |
|
|
10
10
|
| [`logseq_ast_primer.md`](logseq_ast_primer.md) | Parser contributors | Logseq Spatial Markdown domain rules |
|
|
11
|
-
| [`GOOD_FIRST_ISSUES.md`](GOOD_FIRST_ISSUES.md) | New contributors | Curated starter tasks ([#19](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/19)–[#
|
|
12
|
-
| [`COOKBOOK.md`](COOKBOOK.md) | Integrators | Copy-paste recipes (Synapse, graph query, watcher, agents) |
|
|
11
|
+
| [`GOOD_FIRST_ISSUES.md`](GOOD_FIRST_ISSUES.md) | New contributors | Curated starter tasks ([#19](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/19)–[#52](https://github.com/MarcoPorcellato/logseq-matryca-parser/issues/52); wave 1 landed in **v1.4.1**) |
|
|
12
|
+
| [`COOKBOOK.md`](COOKBOOK.md) | Integrators | Copy-paste recipes (Synapse, graph query, watcher, agents, contributor test patterns) |
|
|
13
13
|
| [`RELEASE_PROCESS.md`](RELEASE_PROCESS.md) | Maintainers | Semver, tag, and PyPI publish checklist |
|
|
14
14
|
| [`CODEQL.md`](CODEQL.md) | Maintainers | CodeQL default setup notes |
|
|
15
15
|
| [`BUG_HUNT_REPORT.md`](BUG_HUNT_REPORT.md) | Maintainers, contributors | Local static analysis bug audit (Clean Architecture lens, runtime evidence) |
|
|
@@ -215,7 +215,7 @@ If you feed Logseq Markdown into `RecursiveCharacterTextSplitter` (LangChain) or
|
|
|
215
215
|
|
|
216
216
|
The **Logos Protocol** solves this by walking the AST deterministically, isolating properties, shielding dead-zone literals, and using the `SYNAPSE` adapter to export native LangChain `Document` or LlamaIndex `TextNode` objects. Every generated object retains its exact hierarchical lineage in the metadata, feeding your local LLM perfectly structured data.
|
|
217
217
|
|
|
218
|
-
For vault-wide navigation (aliases, backlinks, namespace shadowing, assets), load the graph with **`LogseqGraph`** — see the [README](../README.md) and [CHANGELOG](../CHANGELOG.md) (graph parity from **v1.2.0**; **v1.3.0** adds watcher debounce, `strict_refs`, public API exports, and LlamaIndex spatial relationships; **v1.4.0** adds canonical page iteration, case-insensitive tag/search, watcher delete/move handling, and SYNAPSE embed safety).
|
|
218
|
+
For vault-wide navigation (aliases, backlinks, namespace shadowing, assets), load the graph with **`LogseqGraph`** — see the [README](../README.md) and [CHANGELOG](../CHANGELOG.md) (graph parity from **v1.2.0**; **v1.3.0** adds watcher debounce, `strict_refs`, public API exports, and LlamaIndex spatial relationships; **v1.4.0** adds canonical page iteration, case-insensitive tag/search, watcher delete/move handling, and SYNAPSE embed safety; **v1.4.1** adds community test coverage for parser helpers, CLI agents, and FORGE visitors — **378** pytest cases, no runtime API changes).
|
|
219
219
|
|
|
220
220
|
---
|
|
221
221
|
|
|
@@ -165,3 +165,60 @@ def test_agent_write_cli_splices_via_alias_state(tmp_path: Path) -> None:
|
|
|
165
165
|
|
|
166
166
|
updated = (pages / "Write.md").read_text(encoding="utf-8")
|
|
167
167
|
assert "Child from agent-write" in updated
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def test_agent_read_cli_query_filter_finds_matching_blocks(tmp_path: Path) -> None:
|
|
171
|
+
"""``agent-read --query`` prints only blocks containing the search term."""
|
|
172
|
+
graph_root = tmp_path / "graph"
|
|
173
|
+
pages = graph_root / "pages"
|
|
174
|
+
pages.mkdir(parents=True)
|
|
175
|
+
(graph_root / "journals").mkdir()
|
|
176
|
+
|
|
177
|
+
(pages / "alpha.md").write_text(
|
|
178
|
+
"- Needle in a haystack #tag-a\n"
|
|
179
|
+
" - Nested needle block\n",
|
|
180
|
+
encoding="utf-8",
|
|
181
|
+
)
|
|
182
|
+
(pages / "beta.md").write_text(
|
|
183
|
+
"- Irrelevant content #tag-b\n"
|
|
184
|
+
" - Should not appear\n",
|
|
185
|
+
encoding="utf-8",
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
result = runner.invoke(
|
|
189
|
+
app,
|
|
190
|
+
["agent-read", str(graph_root), "--query", "needle"],
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
assert result.exit_code == 0
|
|
194
|
+
# Plain text — no Rich markup
|
|
195
|
+
assert "\x1b[" not in result.output
|
|
196
|
+
# X-Ray alias format [0], [1]
|
|
197
|
+
assert "[0]" in result.output
|
|
198
|
+
assert "Needle in a haystack" in result.output
|
|
199
|
+
assert "Nested needle block" in result.output
|
|
200
|
+
# Non-matching blocks are excluded
|
|
201
|
+
assert "Irrelevant content" not in result.output
|
|
202
|
+
assert "Should not appear" not in result.output
|
|
203
|
+
|
|
204
|
+
# Alias state saved for agent-write chaining
|
|
205
|
+
state_path = graph_root / ".matryca_xray_state.json"
|
|
206
|
+
assert state_path.is_file()
|
|
207
|
+
restored = SessionAliasRegistry.load_from_disk(state_path)
|
|
208
|
+
assert restored.resolve_alias(0) is not None
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def test_agent_read_cli_query_no_matches_exits_cleanly(tmp_path: Path) -> None:
|
|
212
|
+
"""``agent-read --query`` with no matches exits 0 and prints nothing."""
|
|
213
|
+
graph_root = tmp_path / "graph"
|
|
214
|
+
pages = graph_root / "pages"
|
|
215
|
+
pages.mkdir(parents=True)
|
|
216
|
+
(graph_root / "journals").mkdir()
|
|
217
|
+
(pages / "only.md").write_text("- Just some text\n", encoding="utf-8")
|
|
218
|
+
|
|
219
|
+
result = runner.invoke(
|
|
220
|
+
app,
|
|
221
|
+
["agent-read", str(graph_root), "--query", "nonexistent"],
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
assert result.exit_code == 0
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Dedicated tests for the parser exception hierarchy (issue #21).
|
|
2
|
+
|
|
3
|
+
Verifies that all domain exceptions inherit from LogseqParserError and
|
|
4
|
+
that each class can be instantiated with a message string.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
from logseq_matryca_parser.exceptions import (
|
|
12
|
+
BlockReferenceError,
|
|
13
|
+
LogseqIndentationError,
|
|
14
|
+
LogseqParserError,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class TestExceptionHierarchy:
|
|
19
|
+
"""Structural assertions on the exception class hierarchy."""
|
|
20
|
+
|
|
21
|
+
def test_block_reference_error_is_subclass_of_logseq_parser_error(self):
|
|
22
|
+
"""BlockReferenceError must inherit from the base parser exception."""
|
|
23
|
+
assert issubclass(BlockReferenceError, LogseqParserError)
|
|
24
|
+
|
|
25
|
+
def test_logseq_indentation_error_is_subclass_of_logseq_parser_error(self):
|
|
26
|
+
"""LogseqIndentationError must inherit from LogseqParserError.
|
|
27
|
+
|
|
28
|
+
Note: LogseqIndentationError is reserved for a future strict
|
|
29
|
+
indentation mode and is not raised by the parser today.
|
|
30
|
+
"""
|
|
31
|
+
assert issubclass(LogseqIndentationError, LogseqParserError)
|
|
32
|
+
|
|
33
|
+
def test_base_exception_is_standard_exception(self):
|
|
34
|
+
"""LogseqParserError itself inherits from built-in Exception."""
|
|
35
|
+
assert issubclass(LogseqParserError, Exception)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class TestExceptionInstantiation:
|
|
39
|
+
"""Behavioural assertions — can instantiate and use as exceptions."""
|
|
40
|
+
|
|
41
|
+
def test_block_reference_error_can_be_raised_and_caught(self):
|
|
42
|
+
with pytest.raises(BlockReferenceError, match="test error"):
|
|
43
|
+
raise BlockReferenceError("test error")
|
|
44
|
+
|
|
45
|
+
def test_block_reference_error_is_caught_by_base_class(self):
|
|
46
|
+
"""Catching LogseqParserError also catches BlockReferenceError."""
|
|
47
|
+
with pytest.raises(LogseqParserError):
|
|
48
|
+
raise BlockReferenceError("caught by base")
|
|
49
|
+
|
|
50
|
+
def test_logseq_indentation_error_can_be_raised_and_caught(self):
|
|
51
|
+
"""LogseqIndentationError accepts a message like other exceptions."""
|
|
52
|
+
with pytest.raises(LogseqIndentationError, match="indent"):
|
|
53
|
+
raise LogseqIndentationError("broken indent")
|
|
54
|
+
|
|
55
|
+
def test_logseq_indentation_error_is_caught_by_base_class(self):
|
|
56
|
+
"""Catching LogseqParserError also catches LogseqIndentationError."""
|
|
57
|
+
with pytest.raises(LogseqParserError):
|
|
58
|
+
raise LogseqIndentationError("caught by base")
|
|
59
|
+
|
|
60
|
+
def test_base_exception_stores_message(self):
|
|
61
|
+
exc = LogseqParserError("base message")
|
|
62
|
+
assert str(exc) == "base message"
|