logseq-matryca-parser 1.3.0__tar.gz → 1.4.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.
Files changed (108) hide show
  1. logseq_matryca_parser-1.4.0/.cursorrules +4 -0
  2. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/.github/ISSUE_TEMPLATE/config.yml +3 -0
  3. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/.github/PULL_REQUEST_TEMPLATE.md +5 -4
  4. logseq_matryca_parser-1.4.0/.github/labels.yml +38 -0
  5. logseq_matryca_parser-1.4.0/.github/scripts/create_good_first_issues.sh +570 -0
  6. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/.github/workflows/ci.yml +2 -2
  7. logseq_matryca_parser-1.4.0/.github/workflows/daily-metrics.yml +64 -0
  8. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/.github/workflows/github_release.yml +2 -2
  9. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/.github/workflows/pypi_publish.yml +3 -3
  10. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/CHANGELOG.md +46 -0
  11. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/CONTRIBUTING.md +31 -2
  12. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/PKG-INFO +41 -9
  13. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/README.md +40 -8
  14. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/SECURITY.md +3 -1
  15. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/claude-skill-logseq-read/SKILL.md +1 -1
  16. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/ARCHITECTURE.md +33 -9
  17. logseq_matryca_parser-1.4.0/docs/BUG_HUNT_REPORT.md +1245 -0
  18. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/CODEQL.md +3 -1
  19. logseq_matryca_parser-1.4.0/docs/COOKBOOK.md +141 -0
  20. logseq_matryca_parser-1.4.0/docs/GOOD_FIRST_ISSUES.md +77 -0
  21. logseq_matryca_parser-1.4.0/docs/README.md +37 -0
  22. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/RELEASE_PROCESS.md +2 -1
  23. logseq_matryca_parser-1.4.0/docs/design-docs/README.md +11 -0
  24. logseq_matryca_parser-1.4.0/docs/internal/STATIC_ANALYSIS_POLICY.md +55 -0
  25. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/logseq_ast_primer.md +16 -3
  26. logseq_matryca_parser-1.4.0/docs/rfc/OLLAMA_RAG.md +33 -0
  27. logseq_matryca_parser-1.4.0/examples/run_demo.py +62 -0
  28. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/metrics/history.json +995 -225
  29. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/pyproject.toml +2 -1
  30. logseq_matryca_parser-1.4.0/scripts/archive_repository_metrics.py +375 -0
  31. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/__init__.py +1 -1
  32. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/agent_press.py +11 -1
  33. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/agent_writer.py +6 -2
  34. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/graph.py +203 -38
  35. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/kinetic.py +20 -9
  36. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/lens.py +45 -8
  37. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/logos_core.py +18 -0
  38. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/logos_parser.py +20 -3
  39. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/logseq_markdown.py +27 -3
  40. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/logseq_paths.py +9 -2
  41. logseq_matryca_parser-1.4.0/src/logseq_matryca_parser/pyproject.toml +0 -0
  42. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/synapse.py +54 -31
  43. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/tests/test_agent_press.py +15 -0
  44. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/tests/test_agent_writer.py +37 -1
  45. logseq_matryca_parser-1.4.0/tests/test_archive_repository_metrics.py +104 -0
  46. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/tests/test_graph.py +203 -0
  47. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/tests/test_kinetic.py +23 -0
  48. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/tests/test_logos_parser.py +13 -0
  49. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/tests/test_logseq_markdown.py +17 -0
  50. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/tests/test_logseq_paths.py +12 -0
  51. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/tests/test_synapse.py +83 -0
  52. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/uv.lock +50 -4
  53. logseq_matryca_parser-1.3.0/.github/workflows/daily-metrics.yml +0 -145
  54. logseq_matryca_parser-1.3.0/examples/run_demo.py +0 -54
  55. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/.cursorignore +0 -0
  56. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/.github/CODEOWNERS +0 -0
  57. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/.github/FUNDING.yml +0 -0
  58. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  59. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  60. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/.github/dependabot.yml +0 -0
  61. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/.gitignore +0 -0
  62. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/.pre-commit-config.yaml +0 -0
  63. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/.repomixignore +0 -0
  64. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/CODE_OF_CONDUCT.md +0 -0
  65. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/LICENSE +0 -0
  66. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/Makefile +0 -0
  67. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/NOTICE +0 -0
  68. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/claude-skill-logseq-read/scripts/parse_logseq.py +0 -0
  69. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/design-docs/ARCHITECTURE_BLUEPRINT.md +0 -0
  70. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/design-docs/CODE_SCAFFOLD.md +0 -0
  71. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/design-docs/LOGSEQ_ASSET_RESOLUTION_SPEC.md +0 -0
  72. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/design-docs/LOGSEQ_DATASCRIPT_MAPPING.md +0 -0
  73. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/design-docs/LOGSEQ_TEMPORAL_ONTOLOGY.md +0 -0
  74. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/design-docs/OFFICIAL_MLDOC_SPECS.md +0 -0
  75. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/design-docs/REFERENCE_SPEC.md +0 -0
  76. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/error_log.md +0 -0
  77. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/roadmaps/ROADMAP_AGENT_NATIVE_XRAY.md +0 -0
  78. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/roadmaps/ROADMAP_CLI_HYDRATION_AND_ENRICHMENT.md +0 -0
  79. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/roadmaps/ROADMAP_CONTEXT_SYNTHESIS_AND_SCOPING.md +0 -0
  80. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/roadmaps/ROADMAP_EMBED_EXPANSION_AND_FLUENT_QUERIES.md +0 -0
  81. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/roadmaps/ROADMAP_GRAPH_RAG_SEMANTICS.md +0 -0
  82. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/roadmaps/ROADMAP_HEADLESS_WRITER.md +0 -0
  83. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/roadmaps/ROADMAP_INCREMENTAL_WATCHER.md +0 -0
  84. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/roadmaps/ROADMAP_INLINE_SHIELD_AND_NAMESPACES.md +0 -0
  85. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/roadmaps/ROADMAP_OBSIDIAN_ADAPTER.md +0 -0
  86. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/roadmaps/ROADMAP_ROBUSTNESS_AND_SOFT_BREAKS.md +0 -0
  87. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/roadmaps/ROADMAP_TOML_FIX_AND_PYPI_DISTRIBUTION.md +0 -0
  88. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/docs/roadmaps/ROADMAP_UUID_AND_GRAPH_SUPERPOWERS.md +0 -0
  89. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/examples/demo_logseq_journal.md +0 -0
  90. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/legacy/local_digestor.py +0 -0
  91. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/lib/bindings/utils.js +0 -0
  92. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/lib/tom-select/tom-select.complete.min.js +0 -0
  93. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/lib/tom-select/tom-select.css +0 -0
  94. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/lib/vis-9.1.2/vis-network.css +0 -0
  95. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/lib/vis-9.1.2/vis-network.min.js +0 -0
  96. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/repomix-output-parser.xml +0 -0
  97. /logseq_matryca_parser-1.3.0/src/logseq_matryca_parser/.gitignore → /logseq_matryca_parser-1.4.0/scripts/__init__.py +0 -0
  98. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/scripts/debug_pre_release.py +0 -0
  99. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/scripts/extract_changelog.py +0 -0
  100. /logseq_matryca_parser-1.3.0/src/logseq_matryca_parser/pyproject.toml → /logseq_matryca_parser-1.4.0/src/logseq_matryca_parser/.gitignore +0 -0
  101. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/NOTICE +0 -0
  102. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/__main__.py +0 -0
  103. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/exceptions.py +0 -0
  104. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/src/logseq_matryca_parser/forge.py +0 -0
  105. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/tests/test_forge.py +0 -0
  106. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/tests/test_lens.py +0 -0
  107. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/tests/test_package_version.py +0 -0
  108. {logseq_matryca_parser-1.3.0 → logseq_matryca_parser-1.4.0}/tests/test_pre_release_roundtrip.py +0 -0
@@ -0,0 +1,4 @@
1
+ ## Tooling & Static Analysis Policy
2
+ - Do not track, commit, or mention specific third-party local development tools, AST indexers, or custom MCP servers in public documentation, CI/CD, or commit messages.
3
+ - Keep the public repository vendor-agnostic and strictly focused on core project requirements.
4
+ - When referring to local code audits in docs or issues, use generic terms like "Local Static Analysis", "AST tooling", or "Graph-based code analysis".
@@ -3,6 +3,9 @@ contact_links:
3
3
  - name: Security vulnerability
4
4
  url: https://github.com/MarcoPorcellato/logseq-matryca-parser/security/policy
5
5
  about: Report a security issue privately — do not open a public issue
6
+ - name: Good first issues
7
+ url: https://github.com/MarcoPorcellato/logseq-matryca-parser/blob/main/docs/GOOD_FIRST_ISSUES.md
8
+ about: Curated starter tasks for your first pull request
6
9
  - name: Contributing guidelines
7
10
  url: https://github.com/MarcoPorcellato/logseq-matryca-parser/blob/main/CONTRIBUTING.md
8
11
  about: Read how to set up your environment, run tests, and open a pull request
@@ -8,10 +8,11 @@ Fixes # (issue_number)
8
8
  - [ ] 📚 Documentation update
9
9
 
10
10
  ## 🛡️ Sovereign Developer Checklist
11
- - [ ] I have read the `CONTRIBUTING.md` guidelines.
11
+ - [ ] I have read [`CONTRIBUTING.md`](../CONTRIBUTING.md) (or picked a task from [`docs/GOOD_FIRST_ISSUES.md`](../docs/GOOD_FIRST_ISSUES.md)).
12
12
  - [ ] I have executed `make all` locally, and all linters (Ruff), type-checkers (Mypy), and tests (Pytest) pass successfully.
13
13
  - [ ] I have added/updated tests for my changes (if applicable).
14
- - [ ] I have updated the documentation accordingly.
15
- - [ ] My code follows the strict typing rules (`strict=True`) of this project.
14
+ - [ ] I have updated the relevant documentation (`README.md`, `docs/`, `CONTRIBUTING.md` as needed).
15
+ - [ ] I updated [`CHANGELOG.md`](../CHANGELOG.md) under `[Unreleased]` for user-visible behavior changes.
16
+ - [ ] My code follows the project's typing conventions (explicit hints on new functions; Pydantic `strict=True` on domain models).
16
17
 
17
- ## Screenshots / CLI Output (if applicable)
18
+ ## Screenshots / CLI Output (if applicable)
@@ -0,0 +1,38 @@
1
+ # Sync with GitHub: gh label sync -f .github/labels.yml
2
+ # https://cli.github.com/manual/gh_label_sync
3
+
4
+ - name: bug
5
+ color: d73a4a
6
+ description: Something isn't working
7
+
8
+ - name: triage
9
+ color: fbca04
10
+ description: Needs maintainer review or reproduction
11
+
12
+ - name: enhancement
13
+ color: a2eeef
14
+ description: New feature or request
15
+
16
+ - name: good first issue
17
+ color: 7057ff
18
+ description: Good for newcomers — scoped, documented, low risk
19
+
20
+ - name: help wanted
21
+ color: 008672
22
+ description: Extra attention or skill is welcome
23
+
24
+ - name: tests
25
+ color: 1d76db
26
+ description: Test coverage or quality gates
27
+
28
+ - name: documentation
29
+ color: 0075ca
30
+ description: Documentation improvements
31
+
32
+ - name: cli
33
+ color: e99695
34
+ description: KINETIC CLI (matryca-parse)
35
+
36
+ - name: forge
37
+ color: bfd4f2
38
+ description: FORGE exporters and visitors
@@ -0,0 +1,570 @@
1
+ #!/usr/bin/env bash
2
+ # Creates Good First Issues on GitHub. Run from repo root:
3
+ # bash .github/scripts/create_good_first_issues.sh
4
+ set -euo pipefail
5
+ ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
6
+ cd "$ROOT"
7
+ OUT="$ROOT/.github/gfi_issue_numbers.txt"
8
+ : > "$OUT"
9
+
10
+ create_issue() {
11
+ local id="$1"
12
+ local title="$2"
13
+ local labels="$3"
14
+ local body_file="$4"
15
+ local url
16
+ url=$(gh issue create --title "$title" --label "$labels" --body-file "$body_file")
17
+ local num="${url##*/}"
18
+ echo "$id=$num" >> "$OUT"
19
+ echo "Created $id -> #$num"
20
+ }
21
+
22
+ BODY_DIR=$(mktemp -d)
23
+ trap 'rm -rf "$BODY_DIR"' EXIT
24
+
25
+ # GFI-01
26
+ cat > "$BODY_DIR/gfi01.md" <<'EOF'
27
+ ## Context
28
+
29
+ `tests/test_kinetic.py` covers happy paths for the KINETIC CLI (`matryca-parse`). Error messages for missing graph paths and optional dependencies (`[viz]`, `[ai]`) are implemented in `kinetic.py` but not asserted in tests.
30
+
31
+ ## Objectives
32
+
33
+ - [ ] `scan` / `export` on an empty vault → output contains `"No Markdown files found"`
34
+ - [ ] Command without positional graph path and without `--graph` → `"Graph path required"`
35
+ - [ ] `visualize` / `demo` without `[viz]` extra → dependency hint message
36
+ - [ ] `export --format langchain` without `[ai]` extra → dependency hint message
37
+ - [ ] Reuse existing `CliRunner` and `_create_graph()` patterns from `tests/test_kinetic.py`
38
+
39
+ ## Files
40
+
41
+ - `tests/test_kinetic.py`
42
+ - Reference: `src/logseq_matryca_parser/kinetic.py`
43
+
44
+ ## Getting started
45
+
46
+ 1. `uv sync --all-extras`
47
+ 2. `make all`
48
+ 3. Copy an existing CLI test (e.g. `test_scan_command_prints_graph_statistics`) and assert `result.exit_code != 0` plus substring in `result.stdout` / `result.stderr`
49
+
50
+ ## Out of scope
51
+
52
+ - Changes to `logos_core.py`
53
+ - Production CLI behavior changes (tests only)
54
+
55
+ ## Definition of Done
56
+
57
+ - `make all` passes
58
+ - No `CHANGELOG.md` entry needed (test-only)
59
+ EOF
60
+ create_issue "GFI-01" "test(kinetic): add CLI error-path coverage for missing graph and optional deps" "good first issue,tests,cli" "$BODY_DIR/gfi01.md"
61
+
62
+ # GFI-02
63
+ cat > "$BODY_DIR/gfi02.md" <<'EOF'
64
+ ## Context
65
+
66
+ `matryca-parse agent-write` validates `--alias` vs `--target-uuid` and X-Ray state files, but validation error paths lack dedicated CLI tests.
67
+
68
+ ## Objectives
69
+
70
+ - [ ] Neither `--alias` nor `--target-uuid` → non-zero exit
71
+ - [ ] Both flags together → mutual exclusion error
72
+ - [ ] Unknown alias without `.matryca_xray_state.json` → clear error message
73
+ - [ ] Missing `--state-file` when required by code path (if applicable)
74
+
75
+ ## Files
76
+
77
+ - `tests/test_kinetic.py` and/or `tests/test_agent_press.py`
78
+
79
+ ## Getting started
80
+
81
+ 1. `uv sync --all-extras`
82
+ 2. `make all`
83
+ 3. Inspect `agent_write` command in `src/logseq_matryca_parser/kinetic.py`
84
+
85
+ ## Out of scope
86
+
87
+ - `logos_core.py` model changes
88
+ - Agent write engine logic changes (tests only unless a bug is found)
89
+
90
+ ## Definition of Done
91
+
92
+ - `make all` passes
93
+ - No `CHANGELOG.md` entry needed (test-only)
94
+ EOF
95
+ create_issue "GFI-02" "test(kinetic): cover agent-write validation errors" "good first issue,tests,cli" "$BODY_DIR/gfi02.md"
96
+
97
+ # GFI-03
98
+ cat > "$BODY_DIR/gfi03.md" <<'EOF'
99
+ ## Context
100
+
101
+ `src/logseq_matryca_parser/exceptions.py` defines the public exception hierarchy exported in `__all__`, but there is no dedicated test module. `LogseqIndentationError` is reserved for future strict indentation mode and is not raised today.
102
+
103
+ ## Objectives
104
+
105
+ - [ ] Add `tests/test_exceptions.py`
106
+ - [ ] Assert `BlockReferenceError` is a subclass of `LogseqParserError`
107
+ - [ ] Assert `LogseqIndentationError` is a subclass of `LogseqParserError`
108
+ - [ ] Document via test docstring that `LogseqIndentationError` is currently unused (no behavior change)
109
+
110
+ ## Files
111
+
112
+ - New: `tests/test_exceptions.py`
113
+ - Reference: `src/logseq_matryca_parser/exceptions.py`
114
+
115
+ ## Getting started
116
+
117
+ 1. `uv sync --all-extras`
118
+ 2. `make all`
119
+
120
+ ## Out of scope
121
+
122
+ - Raising `LogseqIndentationError` from the parser
123
+ - `logos_core.py` changes
124
+
125
+ ## Definition of Done
126
+
127
+ - `make all` passes
128
+ - No `CHANGELOG.md` entry needed
129
+ EOF
130
+ create_issue "GFI-03" "test: add dedicated tests for exception hierarchy" "good first issue,tests" "$BODY_DIR/gfi03.md"
131
+
132
+ # GFI-04
133
+ cat > "$BODY_DIR/gfi04.md" <<'EOF'
134
+ ## Context
135
+
136
+ `logseq_paths.py` has edge-case helpers that are partially covered. Empty page titles and fallback graph-root derivation need explicit tests.
137
+
138
+ ## Objectives
139
+
140
+ - [ ] `page_title_to_relative_path("")` → `untitled.md`
141
+ - [ ] `derive_graph_root_from_source_path` without `pages/` or `journals/` marker → falls back to `path.parent`
142
+ - [ ] `derive_page_title_from_source_path` outside `pages/`/`journals/` → uses `filename_to_page_title(stem)`
143
+
144
+ ## Files
145
+
146
+ - `tests/test_logseq_paths.py`
147
+ - Reference: `src/logseq_matryca_parser/logseq_paths.py`
148
+
149
+ ## Getting started
150
+
151
+ 1. `uv sync --all-extras`
152
+ 2. `make all`
153
+ 3. Follow patterns in existing `test_logseq_paths.py` tests
154
+
155
+ ## Out of scope
156
+
157
+ - Changing path encoding rules
158
+
159
+ ## Definition of Done
160
+
161
+ - `make all` passes
162
+ - No `CHANGELOG.md` entry needed
163
+ EOF
164
+ create_issue "GFI-04" "test(logseq_paths): cover empty title and fallback graph-root derivation" "good first issue,tests" "$BODY_DIR/gfi04.md"
165
+
166
+ # GFI-05
167
+ cat > "$BODY_DIR/gfi05.md" <<'EOF'
168
+ ## Context
169
+
170
+ `scripts/extract_changelog.py` provides pure functions for release notes extraction but has no unit tests. This is an ideal first PR with zero parser knowledge required.
171
+
172
+ ## Objectives
173
+
174
+ - [ ] Add `tests/test_extract_changelog.py`
175
+ - [ ] `normalize_version("v1.0.0")` → `"1.0.0"`
176
+ - [ ] Extract existing section from a minimal CHANGELOG fixture
177
+ - [ ] Missing version raises `LookupError` or documented exit code
178
+ - [ ] `[Unreleased]` rejected when `allow_unreleased=False`
179
+
180
+ ## Files
181
+
182
+ - New: `tests/test_extract_changelog.py`
183
+ - Reference: `scripts/extract_changelog.py`
184
+
185
+ ## Getting started
186
+
187
+ 1. `uv sync --all-extras`
188
+ 2. `make all`
189
+ 3. Import functions from `scripts/extract_changelog.py` (add `tests/` import path or use `importlib` pattern used elsewhere)
190
+
191
+ ## Out of scope
192
+
193
+ - Changing release script CLI behavior
194
+
195
+ ## Definition of Done
196
+
197
+ - `make all` passes
198
+ - No `CHANGELOG.md` entry needed
199
+ EOF
200
+ create_issue "GFI-05" "test: add unit tests for extract_changelog release helper" "good first issue,tests" "$BODY_DIR/gfi05.md"
201
+
202
+ # GFI-06
203
+ cat > "$BODY_DIR/gfi06.md" <<'EOF'
204
+ ## Context
205
+
206
+ README documents `matryca-parse agent-read --query "needle"` but only `--tag` filtering is tested in `tests/test_agent_press.py`.
207
+
208
+ ## Objectives
209
+
210
+ - [ ] CLI test: fixture graph with known text; `--query "needle"` prints only matching blocks
211
+ - [ ] Assert stdout uses X-Ray alias format (e.g. `[0]` prefix style)
212
+ - [ ] Output is plain text (no Rich markup)
213
+
214
+ ## Files
215
+
216
+ - `tests/test_agent_press.py` and/or `tests/test_kinetic.py`
217
+
218
+ ## Getting started
219
+
220
+ 1. `uv sync --all-extras`
221
+ 2. `make all`
222
+ 3. Mirror existing `agent-read --tag` test setup
223
+
224
+ ## Out of scope
225
+
226
+ - X-Ray formatting changes
227
+
228
+ ## Definition of Done
229
+
230
+ - `make all` passes
231
+ - No `CHANGELOG.md` entry needed
232
+ EOF
233
+ create_issue "GFI-06" "test(agent): add CLI test for agent-read --query filter" "good first issue,tests,cli" "$BODY_DIR/gfi06.md"
234
+
235
+ # GFI-07
236
+ cat > "$BODY_DIR/gfi07.md" <<'EOF'
237
+ ## Context
238
+
239
+ The repo has `examples/run_demo.py` and a journal fixture, but no copy-paste integration cookbook for Synapse, graph queries, or the filesystem watcher.
240
+
241
+ ## Objectives
242
+
243
+ - [ ] Add `docs/COOKBOOK.md` with three minimal recipes:
244
+ 1. Parse a single page + `SynapseAdapter.to_langchain_documents`
245
+ 2. `LogseqGraph.load_directory` + fluent `graph.query()`
246
+ 3. `start_watching()` with note on `uv sync --extra watch`
247
+ - [ ] Link from `CONTRIBUTING.md` and README Contributing table
248
+ - [ ] Snippets import from package root (`logseq_matryca_parser` `__all__`)
249
+
250
+ ## Files
251
+
252
+ - New: `docs/COOKBOOK.md`
253
+ - `CONTRIBUTING.md`, `README.md`, `docs/README.md`
254
+
255
+ ## Getting started
256
+
257
+ 1. `uv sync --all-extras`
258
+ 2. Run snippets locally to verify they work
259
+
260
+ ## Out of scope
261
+
262
+ - New Python modules or API changes
263
+
264
+ ## Definition of Done
265
+
266
+ - Links verified
267
+ - Optional: brief `CHANGELOG.md` `### Added` entry for cookbook
268
+ EOF
269
+ create_issue "GFI-07" "docs: add examples cookbook for common integration recipes" "good first issue,documentation" "$BODY_DIR/gfi07.md"
270
+
271
+ # GFI-08
272
+ cat > "$BODY_DIR/gfi08.md" <<'EOF'
273
+ ## Context
274
+
275
+ `docs/design-docs/` contains rich historical blueprints that can mislead newcomers. A documentation index (`docs/README.md`) was added to distinguish active vs historical docs — verify completeness and cross-links.
276
+
277
+ ## Objectives
278
+
279
+ - [ ] Review `docs/README.md`: active vs historical table is accurate
280
+ - [ ] Link to `ARCHITECTURE.md`, `logseq_ast_primer.md`, `GOOD_FIRST_ISSUES.md`
281
+ - [ ] Add one-line pointer in `CONTRIBUTING.md` Documentation section (if missing)
282
+ - [ ] Optionally add a one-line banner at the top of `docs/design-docs/README.md` (new stub) pointing to `docs/README.md`
283
+
284
+ ## Files
285
+
286
+ - `docs/README.md`
287
+ - `CONTRIBUTING.md`
288
+ - Optional: `docs/design-docs/README.md`
289
+
290
+ ## Getting started
291
+
292
+ 1. Read `docs/design-docs/CODE_SCAFFOLD.md` banner text for tone
293
+ 2. Walk the `docs/` tree and confirm the index matches reality
294
+
295
+ ## Out of scope
296
+
297
+ - Rewriting historical design docs
298
+
299
+ ## Definition of Done
300
+
301
+ - All links resolve
302
+ - Optional `CHANGELOG.md` `### Added` for docs index
303
+ EOF
304
+ create_issue "GFI-08" "docs: add docs/README.md index warning about historical design-docs" "good first issue,documentation" "$BODY_DIR/gfi08.md"
305
+
306
+ # GFI-09
307
+ cat > "$BODY_DIR/gfi09.md" <<'EOF'
308
+ ## Context
309
+
310
+ Only root `--help` is tested for Rich markup mode. Per-subcommand `--help` should render without errors to lock in CLI UX.
311
+
312
+ ## Objectives
313
+
314
+ - [ ] `runner.invoke(app, ["<cmd>", "--help"])` returns exit code 0 for: `scan`, `export`, `visualize`, `agent-read`, `agent-write`, `append`, `demo`
315
+ - [ ] Optional: assert key flags appear (`--format`, `--tag`, `--graph`)
316
+
317
+ ## Files
318
+
319
+ - `tests/test_kinetic.py`
320
+
321
+ ## Getting started
322
+
323
+ 1. `uv sync --all-extras`
324
+ 2. See `test_cli_help_uses_rich_markup_mode` for pattern
325
+
326
+ ## Out of scope
327
+
328
+ - Changing help text content
329
+
330
+ ## Definition of Done
331
+
332
+ - `make all` passes
333
+ EOF
334
+ create_issue "GFI-09" "test(kinetic): assert per-command --help renders without error" "good first issue,tests,cli" "$BODY_DIR/gfi09.md"
335
+
336
+ # GFI-10
337
+ cat > "$BODY_DIR/gfi10.md" <<'EOF'
338
+ ## Context
339
+
340
+ `examples/run_demo.py` has Italian comments and uses `sys.path` manipulation instead of package imports after `uv sync`.
341
+
342
+ ## Objectives
343
+
344
+ - [ ] Translate comments and error messages to English
345
+ - [ ] Use `from logseq_matryca_parser...` imports without `sys.path` hack when possible
346
+ - [ ] `make check` passes on `examples/run_demo.py`
347
+
348
+ ## Files
349
+
350
+ - `examples/run_demo.py`
351
+
352
+ ## Getting started
353
+
354
+ 1. `uv sync --all-extras`
355
+ 2. `uv run python examples/run_demo.py`
356
+
357
+ ## Out of scope
358
+
359
+ - New example features
360
+
361
+ ## Definition of Done
362
+
363
+ - `make all` passes
364
+ - Optional `CHANGELOG.md` docs bullet
365
+ EOF
366
+ create_issue "GFI-10" "docs(examples): translate run_demo.py comments to English and align with package imports" "good first issue,documentation" "$BODY_DIR/gfi10.md"
367
+
368
+ # GFI-11
369
+ cat > "$BODY_DIR/gfi11.md" <<'EOF'
370
+ ## Context
371
+
372
+ `LogseqGraph.get_broken_references()` (v1.3.0) scans the vault for unresolved `((uuid))` block refs but is not exposed in the CLI. A `--broken-refs` flag on `scan` would help CI vault hygiene.
373
+
374
+ ## Objectives
375
+
376
+ - [ ] `matryca-parse scan GRAPH --broken-refs` prints missing refs (Rich table or one line per ref)
377
+ - [ ] Optional: exit code 1 when broken refs > 0 (document behavior in help text)
378
+ - [ ] Tests in `tests/test_kinetic.py` with fixture referencing `((fake-uuid))`
379
+ - [ ] `CHANGELOG.md` `### Added` entry
380
+
381
+ ## Files
382
+
383
+ - `src/logseq_matryca_parser/kinetic.py`
384
+ - `tests/test_kinetic.py`
385
+
386
+ ## Getting started
387
+
388
+ 1. Read `get_broken_references()` in `graph.py`
389
+ 2. See existing `test_get_broken_references_flags_missing_uuid` in `tests/test_graph.py`
390
+
391
+ ## Out of scope
392
+
393
+ - `logos_core.py` changes
394
+
395
+ ## Definition of Done
396
+
397
+ - `make all` passes
398
+ - CHANGELOG updated
399
+ EOF
400
+ create_issue "GFI-11" "feat(cli): add scan --broken-refs flag using LogseqGraph.get_broken_references()" "good first issue,cli,help wanted" "$BODY_DIR/gfi11.md"
401
+
402
+ # GFI-12
403
+ cat > "$BODY_DIR/gfi12.md" <<'EOF'
404
+ ## Context
405
+
406
+ `ObsidianForgeVisitor` is public API (`__all__`) but `tests/test_forge.py` only exercises `ForgeExporter.to_obsidian_markdown`.
407
+
408
+ ## Objectives
409
+
410
+ - [ ] Direct visitor tests: `((uuid))` → `[[Page#^anchor]]` with mock resolver
411
+ - [ ] Referenced block receives `^block-id` suffix
412
+ - [ ] YAML frontmatter from `page_properties`
413
+
414
+ ## Files
415
+
416
+ - `tests/test_forge.py`
417
+ - Reference: `src/logseq_matryca_parser/forge.py`
418
+
419
+ ## Getting started
420
+
421
+ 1. `uv sync --all-extras`
422
+ 2. See `test_forge_visitors_are_ast_compatible` for visitor patterns
423
+
424
+ ## Out of scope
425
+
426
+ - Obsidian namespace path alignment (separate design issue)
427
+
428
+ ## Definition of Done
429
+
430
+ - `make all` passes
431
+ EOF
432
+ create_issue "GFI-12" "test(forge): add direct ObsidianForgeVisitor visitor tests" "good first issue,tests,forge" "$BODY_DIR/gfi12.md"
433
+
434
+ # GFI-13
435
+ cat > "$BODY_DIR/gfi13.md" <<'EOF'
436
+ ## Context
437
+
438
+ `clean_node_content` is exported in `__all__` and used throughout the parser pipeline but only tested indirectly.
439
+
440
+ ## Objectives
441
+
442
+ - [ ] Table-driven tests in `tests/test_logos_parser.py`
443
+ - [ ] Cases: strip `id::`, `SCHEDULED`/`DEADLINE` markers, case-insensitive property keys
444
+ - [ ] No changes to `StackMachineParser`
445
+
446
+ ## Files
447
+
448
+ - `tests/test_logos_parser.py`
449
+ - Reference: `clean_node_content` in `logos_parser.py`
450
+
451
+ ## Getting started
452
+
453
+ 1. `uv sync --all-extras`
454
+ 2. Import `clean_node_content` from `logseq_matryca_parser`
455
+
456
+ ## Out of scope
457
+
458
+ - Parser stack-machine changes
459
+
460
+ ## Definition of Done
461
+
462
+ - `make all` passes
463
+ EOF
464
+ create_issue "GFI-13" "test(parser): table-driven tests for clean_node_content helper" "good first issue,tests" "$BODY_DIR/gfi13.md"
465
+
466
+ # GFI-14
467
+ cat > "$BODY_DIR/gfi14.md" <<'EOF'
468
+ ## Context
469
+
470
+ `normalize_logseq_timestamp` complements `resolve_journal_day` (already tested) but has no direct unit tests for edge inputs.
471
+
472
+ ## Objectives
473
+
474
+ - [ ] Valid Org/Logseq timestamp strings → UTC epoch `int`
475
+ - [ ] `None`, empty string, invalid format → `None`
476
+ - [ ] Tests in `tests/test_logos_parser.py`
477
+
478
+ ## Files
479
+
480
+ - `tests/test_logos_parser.py`
481
+ - Reference: `normalize_logseq_timestamp` in `logos_parser.py`
482
+
483
+ ## Getting started
484
+
485
+ 1. `uv sync --all-extras`
486
+ 2. Read function implementation before writing cases
487
+
488
+ ## Out of scope
489
+
490
+ - Changing timestamp parsing rules
491
+
492
+ ## Definition of Done
493
+
494
+ - `make all` passes
495
+ EOF
496
+ create_issue "GFI-14" "test(parser): unit tests for normalize_logseq_timestamp edge inputs" "good first issue,tests" "$BODY_DIR/gfi14.md"
497
+
498
+ # GFI-15
499
+ cat > "$BODY_DIR/gfi15.md" <<'EOF'
500
+ ## Context
501
+
502
+ CONTRIBUTING cites "a new exporter in `forge.py`" as an example feature. A minimal CSV exporter is a bounded way to learn the FORGE visitor pattern.
503
+
504
+ ## Objectives
505
+
506
+ - [ ] Add CSV export visitor (or static method on `ForgeExporter`)
507
+ - [ ] Columns: at minimum `uuid`, `clean_text`, `indent_level`, `parent_id`
508
+ - [ ] Tests in `tests/test_forge.py`
509
+ - [ ] Optional CLI `--format csv` (discuss in PR if scope grows)
510
+ - [ ] `CHANGELOG.md` if user-visible
511
+
512
+ ## Files
513
+
514
+ - `src/logseq_matryca_parser/forge.py`
515
+ - `tests/test_forge.py`
516
+
517
+ ## Getting started
518
+
519
+ 1. Copy pattern from JSON exporter in `forge.py`
520
+ 2. `uv sync --all-extras` && `make all`
521
+
522
+ ## Out of scope
523
+
524
+ - `logos_core.py` model changes
525
+
526
+ ## Definition of Done
527
+
528
+ - `make all` passes
529
+ EOF
530
+ create_issue "GFI-15" "feat(forge): add minimal CSV exporter" "help wanted,forge,enhancement" "$BODY_DIR/gfi15.md"
531
+
532
+ # GFI-16
533
+ cat > "$BODY_DIR/gfi16.md" <<'EOF'
534
+ ## Context
535
+
536
+ README roadmap lists "Ollama Integration: One-click local RAG setup" with no linked design issue. This RFC captures scope before implementation.
537
+
538
+ ## Objectives
539
+
540
+ - [ ] Add `docs/rfc/OLLAMA_RAG.md` (or section in COOKBOOK) describing:
541
+ - Target user story (local vault → embeddings → Ollama chat)
542
+ - Dependencies (`[ai]` extra, optional Ollama binary)
543
+ - Proposed CLI or script entry point (e.g. `matryca-parse export` + sample pipeline)
544
+ - Non-goals (no cloud, no telemetry)
545
+ - [ ] Link RFC from README roadmap item
546
+ - [ ] Break implementation into follow-up issues
547
+
548
+ ## Files
549
+
550
+ - New: `docs/rfc/OLLAMA_RAG.md`
551
+ - `README.md`
552
+
553
+ ## Getting started
554
+
555
+ 1. Review `SynapseAdapter` and existing `export --format langchain` flow
556
+ 2. Research Ollama embedding/chat APIs (document links)
557
+
558
+ ## Out of scope
559
+
560
+ - Production Ollama integration code in this issue
561
+
562
+ ## Definition of Done
563
+
564
+ - RFC merged; follow-up issues filed for implementation slices
565
+ EOF
566
+ create_issue "GFI-16" "docs: RFC Ollama one-click local RAG" "documentation,enhancement,help wanted" "$BODY_DIR/gfi16.md"
567
+
568
+ echo "---"
569
+ echo "Issue numbers written to $OUT"
570
+ cat "$OUT"
@@ -23,10 +23,10 @@ jobs:
23
23
 
24
24
  steps:
25
25
  - name: Checkout Code
26
- uses: actions/checkout@v6
26
+ uses: actions/checkout@v7
27
27
 
28
28
  - name: Install uv
29
- uses: astral-sh/setup-uv@v6
29
+ uses: astral-sh/setup-uv@v7
30
30
  with:
31
31
  python-version: ${{ matrix.python-version }}
32
32
  enable-cache: true