diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 1ebaba0f..ab2c16dd 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,611 +1,612 @@ -{"id":"k-02o9","title":"HTML writer source location tracking for editor integration","description":"Add optional source location tracking to HTML output to enable 'click in HTML → highlight in source' for interactive previews. See plan: claude-notes/plans/2025-12-21-html-source-location-tracking.md","status":"open","priority":1,"issue_type":"feature","created_at":"2025-12-21T15:40:02.85188-06:00","updated_at":"2025-12-21T15:40:02.85188-06:00"} -{"id":"k-02rp","title":"Add project rendering from VFS to wasm-qmd-parser","description":"Add a function to render a project (multi-file) using files from the virtual filesystem. This will read _quarto.yml and referenced files from VFS and produce HTML output.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-22T19:02:56.445592-06:00","updated_at":"2025-12-22T19:10:58.943494-06:00","closed_at":"2025-12-22T19:10:58.943494-06:00"} -{"id":"k-0dqu","title":"Refactor citeproc output rendering to unify String and Inlines paths","description":"The quarto-citeproc crate has dual code paths for Output AST conversion: render() -\u003e String and to_inlines() -\u003e Pandoc AST. Both implement similar logic for delimiter handling, punctuation collision avoidance, formatting, etc. This creates maintenance burden and potential for bugs (like the delimiter inheritance bug). Refactor to use Output -\u003e Inlines as the canonical conversion, then Inlines -\u003e String for the String path. Plan: claude-notes/plans/2025-12-05-citeproc-delimiter-inheritance-report.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-12-05T17:36:21.963061-06:00","updated_at":"2025-12-05T18:23:28.822793-06:00","closed_at":"2025-12-05T18:23:28.822793-06:00"} -{"id":"k-0dqw","title":"Fix trailing LineBreak at end of block to match CommonMark","description":"In CommonMark, a backslash at the end of a block (paragraph, header) produces a literal backslash, not a LineBreak. pampa currently produces LineBreak in this case. The fix should convert trailing LineBreak to Str('\\\\') in the postprocess.rs handlers.\n\nPlan document: claude-notes/plans/2025-12-17-trailing-linebreak-fix.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-17T08:00:28.743309-06:00","updated_at":"2025-12-17T08:39:08.442844-06:00","closed_at":"2025-12-17T08:39:08.442844-06:00"} -{"id":"k-0sdx","title":"Create web frontend for quarto-hub with WASM rendering","description":"Create a web frontend SPA for quarto-hub that allows users to edit project files in a browser and see live preview. Uses automerge for collaboration and WASM modules from quarto/pampa crates for rendering.\n\nPlan: claude-notes/plans/2025-12-22-quarto-hub-web-frontend-and-wasm.md","status":"open","priority":1,"issue_type":"epic","created_at":"2025-12-22T15:08:41.454563-06:00","updated_at":"2025-12-22T16:24:39.178837-06:00"} -{"id":"k-1","title":"Migrate quarto-markdown error handling to quarto-error-reporting","description":"Replace custom ErrorCollector with quarto-error-reporting infrastructure using phased bridge pattern. See claude-notes/plans/2025-10-18-error-reporting-migration.md for detailed plan.\n\nPhase A: Implement rendering (to_text, to_json, generic_error helper)\nPhase B: Create DiagnosticCollector bridge\nPhase C: Switch implementations\nPhase D: Source location integration (future)\nPhase E: Retire old collectors (future)\n\nFocus is infrastructure change, not message enhancement. Use Q-0-99 with file!() line!() for now.","status":"closed","priority":2,"issue_type":"epic","created_at":"2025-10-18T14:41:31.345695-05:00","updated_at":"2025-10-28T12:43:01.067279-05:00","closed_at":"2025-10-28T12:43:01.067279-05:00","dependencies":[{"issue_id":"k-1","depends_on_id":"k-5","type":"blocks","created_at":"2025-10-18T13:52:20.671231-05:00","created_by":"import"}]} -{"id":"k-10","title":"Run full test suite and verify migration","description":"Run cargo test for quarto-markdown-pandoc and ensure all tests pass after ErrorCollector to DiagnosticCollector migration","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:29:07.029816-05:00","updated_at":"2025-10-18T15:33:05.814566-05:00","closed_at":"2025-10-18T15:33:05.814566-05:00","dependencies":[{"issue_id":"k-10","depends_on_id":"k-9","type":"blocks","created_at":"2025-10-18T13:52:20.672035-05:00","created_by":"import"}]} -{"id":"k-100","title":"Collect all warnings in ParseResult.diagnostics","description":"Combine warnings from AST conversion (error_collector) and metadata parsing into ParseResult.diagnostics instead of outputting to stderr","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T09:25:31.72535-05:00","updated_at":"2025-10-21T10:29:21.892234-05:00","closed_at":"2025-10-21T10:29:21.892234-05:00","dependencies":[{"issue_id":"k-100","depends_on_id":"k-96","type":"discovered-from","created_at":"2025-10-21T09:25:31.727071-05:00","created_by":"cscheid"}]} -{"id":"k-101","title":"Update main.rs to handle new ParseResult API","description":"Remove error_formatter logic. Handle diagnostics output (text/JSON) based on --json-errors flag in main.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T09:25:38.909199-05:00","updated_at":"2025-10-21T10:29:21.905483-05:00","closed_at":"2025-10-21T10:29:21.905483-05:00","dependencies":[{"issue_id":"k-101","depends_on_id":"k-96","type":"discovered-from","created_at":"2025-10-21T09:25:38.91089-05:00","created_by":"cscheid"}]} -{"id":"k-102","title":"Update all test callers for new qmd::read API","description":"Update all tests to use ParseResult instead of (Pandoc, ASTContext) tuple. Remove error_formatter None parameters","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T09:25:46.955046-05:00","updated_at":"2025-10-21T10:38:21.880567-05:00","closed_at":"2025-10-21T10:38:21.880567-05:00","dependencies":[{"issue_id":"k-102","depends_on_id":"k-96","type":"discovered-from","created_at":"2025-10-21T09:25:46.956867-05:00","created_by":"cscheid"}]} -{"id":"k-103","title":"Support in-memory content for anonymous/unknown files in ariadne rendering","description":"When rendering ariadne diagnostics, we currently read file content from disk using the path. This fails for \u003canonymous\u003e or \u003cunknown\u003e files that don't exist on disk. We need to store content in memory for these cases while still reading from disk for real files.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T11:01:32.416755-05:00","updated_at":"2025-10-21T12:50:22.100652-05:00","closed_at":"2025-10-21T12:50:22.100652-05:00"} -{"id":"k-104","title":"crates/quarto-markdown-pandoc/tests/claude-examples/meta-error.qmd has broken messages","description":"The meta-error.qmd test file is producing broken error messages that need investigation. This was noticed during the DiagnosticMessage consolidation work but needs separate attention to ensure error messages are properly formatted.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-21T11:07:16.610573-05:00","updated_at":"2025-10-21T13:51:17.142583-05:00","closed_at":"2025-10-21T13:51:17.142583-05:00"} -{"id":"k-105","title":"Refactor read() to return DiagnosticMessage instead of formatted strings","description":"Replace error_formatter parameter with DiagnosticMessage return values. See claude-notes/plans/2025-10-21-diagnostic-message-refactor.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:01:30.792974-05:00","updated_at":"2025-10-21T14:25:31.639143-05:00","closed_at":"2025-10-21T14:25:31.639143-05:00"} -{"id":"k-106","title":"Update read() signature to return DiagnosticMessage","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:01:39.635533-05:00","updated_at":"2025-10-21T14:03:11.811461-05:00","closed_at":"2025-10-21T14:03:11.811461-05:00","dependencies":[{"issue_id":"k-106","depends_on_id":"k-105","type":"parent-child","created_at":"2025-10-21T14:01:39.63723-05:00","created_by":"cscheid"}]} -{"id":"k-107","title":"Thread DiagnosticCollector through metadata parsing functions","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:01:39.650127-05:00","updated_at":"2025-10-21T14:06:33.632747-05:00","closed_at":"2025-10-21T14:06:33.632747-05:00","dependencies":[{"issue_id":"k-107","depends_on_id":"k-105","type":"parent-child","created_at":"2025-10-21T14:01:39.651253-05:00","created_by":"cscheid"}]} -{"id":"k-108","title":"Update main.rs to format diagnostics based on json_errors flag","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:01:39.663424-05:00","updated_at":"2025-10-21T14:08:31.949797-05:00","closed_at":"2025-10-21T14:08:31.949797-05:00","dependencies":[{"issue_id":"k-108","depends_on_id":"k-105","type":"parent-child","created_at":"2025-10-21T14:01:39.664532-05:00","created_by":"cscheid"}]} -{"id":"k-109","title":"Update all call sites (wasm, tests) to handle new return type","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:01:39.676749-05:00","updated_at":"2025-10-21T15:10:55.413016-05:00","closed_at":"2025-10-21T15:10:55.413016-05:00","dependencies":[{"issue_id":"k-109","depends_on_id":"k-105","type":"parent-child","created_at":"2025-10-21T14:01:39.67783-05:00","created_by":"cscheid"}]} -{"id":"k-11","title":"Change treesitter_to_pandoc return type to Vec\u003cDiagnosticMessage\u003e","description":"Update function signature from Result\u003cPandoc, Vec\u003cString\u003e\u003e to Result\u003cPandoc, Vec\u003cDiagnosticMessage\u003e\u003e so caller decides output format","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:38:24.598967-05:00","updated_at":"2025-10-18T15:40:03.746055-05:00","closed_at":"2025-10-18T15:40:03.746055-05:00","dependencies":[{"issue_id":"k-11","depends_on_id":"k-10","type":"blocks","created_at":"2025-10-18T13:52:20.672785-05:00","created_by":"import"}]} -{"id":"k-110","title":"Add test verifying JSON error output for metadata warnings","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:01:39.6942-05:00","updated_at":"2025-10-26T18:55:08.741639-05:00","closed_at":"2025-10-26T18:55:08.741639-05:00","dependencies":[{"issue_id":"k-110","depends_on_id":"k-105","type":"parent-child","created_at":"2025-10-21T14:01:39.695312-05:00","created_by":"cscheid"}]} -{"id":"k-111","title":"Run cargo check and cargo test for validation","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:01:39.708656-05:00","updated_at":"2025-10-26T18:49:18.075259-05:00","closed_at":"2025-10-26T18:49:18.075259-05:00","dependencies":[{"issue_id":"k-111","depends_on_id":"k-105","type":"parent-child","created_at":"2025-10-21T14:01:39.709787-05:00","created_by":"cscheid"}]} -{"id":"k-112","title":"Create test for --json-errors flag functionality","description":"Add automated test to verify that --json-errors flag properly formats all diagnostics (errors and warnings) as JSON, including metadata parsing warnings like Q-1-101","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:16:03.661971-05:00","updated_at":"2025-10-26T18:46:15.930561-05:00","closed_at":"2025-10-26T18:46:15.930561-05:00","dependencies":[{"issue_id":"k-112","depends_on_id":"k-105","type":"parent-child","created_at":"2025-10-21T14:16:03.663643-05:00","created_by":"cscheid"}]} -{"id":"k-113","title":"Add quarto-error-reporting dependency to qmd-syntax-helper","description":"Add quarto-error-reporting.workspace = true to crates/qmd-syntax-helper/Cargo.toml dependencies section","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T16:34:17.706058-05:00","updated_at":"2025-10-21T16:35:00.653765-05:00","closed_at":"2025-10-21T16:35:00.653765-05:00"} -{"id":"k-114","title":"Update parse_check.rs to use 4-parameter read() signature","description":"Remove 5th parameter from qmd::read() call in crates/qmd-syntax-helper/src/diagnostics/parse_check.rs (lines 22-35). Simple fix - only uses result.is_ok().","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T16:34:20.738673-05:00","updated_at":"2025-10-21T16:35:18.025299-05:00","closed_at":"2025-10-21T16:35:18.025299-05:00"} -{"id":"k-115","title":"Investigate SourceInfo API for row/column extraction","description":"Study crates/quarto-source-map/src/lib.rs to understand how to extract row/column from SourceInfo. Needed for div_whitespace.rs migration.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T16:34:23.737466-05:00","updated_at":"2025-10-21T16:35:42.091665-05:00","closed_at":"2025-10-21T16:35:42.091665-05:00"} -{"id":"k-116","title":"Update div_whitespace.rs to use DiagnosticMessage","description":"Update crates/qmd-syntax-helper/src/conversions/div_whitespace.rs: (1) Remove ParseError/ErrorLocation structs, (2) Remove 5th parameter from qmd::read() call, (3) Update get_parse_errors() to return Vec\u003cDiagnosticMessage\u003e, (4) Update find_div_whitespace_errors() to accept \u0026[DiagnosticMessage], (5) Extract location from DiagnosticMessage.location. See claude-notes/plans/2025-10-21-qmd-syntax-helper-diagnostic-migration.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T16:34:27.04793-05:00","updated_at":"2025-10-21T16:36:44.31465-05:00","closed_at":"2025-10-21T16:36:44.31465-05:00"} -{"id":"k-117","title":"Verify qmd-syntax-helper compiles and tests pass","description":"Run cargo check and cargo test on qmd-syntax-helper after DiagnosticMessage migration","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T16:34:30.307715-05:00","updated_at":"2025-10-21T16:37:44.061757-05:00","closed_at":"2025-10-21T16:37:44.061757-05:00"} -{"id":"k-118","title":"Add error code to simple format in DiagnosticMessage::to_text()","description":"Update line 335 in diagnostic.rs to include error code in simple tidyverse format, matching behavior before k-103 refactor. See claude-notes/plans/2025-10-21-fix-quarto-error-reporting-tests.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T16:45:03.592356-05:00","updated_at":"2025-10-21T16:45:38.861845-05:00","closed_at":"2025-10-21T16:45:38.861845-05:00"} -{"id":"k-119","title":"Add location fallback in DiagnosticMessage::to_text()","description":"Add location display for diagnostics without full source context. Shows 'at row:col' even when ariadne rendering unavailable. See claude-notes/plans/2025-10-21-fix-quarto-error-reporting-tests.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T16:45:06.723921-05:00","updated_at":"2025-10-21T16:46:14.190057-05:00","closed_at":"2025-10-21T16:46:14.190057-05:00"} -{"id":"k-12","title":"Add quarto-source-map dependency to quarto-error-reporting","description":"Update Cargo.toml to add quarto-source-map as dependency","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:58:04.8424-05:00","updated_at":"2025-10-18T15:58:49.265615-05:00","closed_at":"2025-10-18T15:58:49.265615-05:00"} -{"id":"k-120","title":"Update quarto-error-reporting test expectations for trailing newlines","description":"Update test_to_text_simple_error and test_to_text_with_code to expect trailing newlines in output. New behavior adds \\n to all lines for cleaner multi-line display.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T16:45:09.851066-05:00","updated_at":"2025-10-21T16:46:47.566335-05:00","closed_at":"2025-10-21T16:46:47.566335-05:00"} -{"id":"k-121","title":"Clean up compiler warnings in quarto-markdown-pandoc tests","description":"Remove unused imports and variables from test files: test_json_errors.rs, test_inline_locations.rs, test_warnings.rs, test_json_roundtrip.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T16:58:25.389625-05:00","updated_at":"2025-10-21T16:59:53.715645-05:00","closed_at":"2025-10-21T16:59:53.715645-05:00"} -{"id":"k-122","title":"Fix qmd-syntax-helper summary file count bug","description":"Summary only counts files with issues, not all files checked. Track file count separately and pass to print_check_summary. See claude-notes/plans/2025-10-21-qmd-syntax-helper-summary-bug.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-21T18:40:27.96443-05:00","updated_at":"2025-10-21T18:41:35.889473-05:00","closed_at":"2025-10-21T18:41:35.889473-05:00"} -{"id":"k-123","title":"Fix definition-lists rule false positive on table captions","description":"Definition list detector incorrectly flags table captions as definition lists. Add check for pipe characters (2+) in term line to distinguish table rows from definition terms. See claude-notes/plans/2025-10-21-definition-list-false-positive-revised.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-21T18:58:02.387963-05:00","updated_at":"2025-10-21T18:59:07.392181-05:00","closed_at":"2025-10-21T18:59:07.392181-05:00"} -{"id":"k-124","title":"Improve qmd-syntax-helper output context in non-verbose mode","description":"Show filename before issues in non-verbose mode. Buffer results per file and only print filename if file has issues. See claude-notes/plans/2025-10-21-qmd-syntax-helper-output-context.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-21T19:08:28.243069-05:00","updated_at":"2025-10-21T19:10:10.754049-05:00","closed_at":"2025-10-21T19:10:10.754049-05:00"} -{"id":"k-125","title":"Fix glob expansion to check literal paths exist and warn on empty globs","description":"Non-existent literal files are added to file list and cause confusing errors. Check literal paths exist before adding them. Warn when glob patterns match no files. See claude-notes/plans/2025-10-21-qmd-syntax-helper-glob-no-match.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-21T19:17:55.457597-05:00","updated_at":"2025-10-21T19:19:24.518246-05:00","closed_at":"2025-10-21T19:19:24.518246-05:00"} -{"id":"k-126","title":"Fix definition list false positives on grid table captions","description":"Grid table captions (lines starting with : after grid table borders) are incorrectly detected as definition lists. See claude-notes/plans/2025-10-21-grid-table-false-positive.md for details.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-21T19:22:44.086173-05:00","updated_at":"2025-10-21T19:24:17.995116-05:00","closed_at":"2025-10-21T19:24:17.995116-05:00"} -{"id":"k-127","title":"Fix div-whitespace O(N²) performance bug","description":"The div-whitespace rule recalculates line start offsets for every error, causing O(N²) performance. Pre-compute offsets once. See claude-notes/plans/2025-10-21-div-whitespace-performance.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-21T20:23:59.169405-05:00","updated_at":"2025-10-21T20:26:37.015408-05:00","closed_at":"2025-10-21T20:26:37.015408-05:00"} -{"id":"k-128","title":"Optimize TreeSitterLogObserver::log() by eliminating HashMap","description":"Replace expensive HashMap\u003cString, String\u003e allocation on every log call with direct parameter extraction into Option variables. Expected 10-15% speedup in parsing. See claude-notes/tree-sitter-log-optimization-assessment.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T06:35:44.047976-05:00","updated_at":"2025-10-22T06:39:14.817675-05:00","closed_at":"2025-10-22T06:39:14.817675-05:00"} -{"id":"k-129","title":"Add self-health tests for location information on test suite","description":"When converting between (row,col) and byte offsets, we need tests to verify the conversions are correct. Specifically:\n\n1. Test that calculate_byte_offset and offset_to_location are proper inverses\n2. Test edge cases: EOF, empty files, files with/without trailing newlines\n3. Test that parse error locations have consistent start/end row values\n4. Add property-based tests that verify: offset_to_location(calculate_byte_offset(r,c)) == (r,c)\n\nThe bug manifested as: parse error at EOF had start.row=341 but end.row=22 because calculate_byte_offset returned an out-of-bounds offset (10188) for a 10188-byte file.","notes":"Phase 1 \u0026 2 complete. Tests successfully implemented and found real bugs (k-135). Test infrastructure complete and working. Discovered 24 location violations in 6 smoke test files. Next: either fix bugs or continue with Phase 3-5.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T09:44:40.935813-05:00","updated_at":"2025-10-26T18:42:03.011089-05:00","closed_at":"2025-10-26T18:42:03.011089-05:00"} -{"id":"k-13","title":"Add location field to DiagnosticMessage","description":"Add optional quarto_source_map::SourceInfo field to DiagnosticMessage struct","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:58:06.274133-05:00","updated_at":"2025-10-18T15:59:41.186788-05:00","closed_at":"2025-10-18T15:59:41.186788-05:00","dependencies":[{"issue_id":"k-13","depends_on_id":"k-12","type":"blocks","created_at":"2025-10-18T13:52:20.673506-05:00","created_by":"import"}]} -{"id":"k-130","title":"Phase 1: Create test infrastructure for location health checks","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T18:00:47.681619-05:00","updated_at":"2025-10-22T18:05:13.094318-05:00","closed_at":"2025-10-22T18:05:13.094318-05:00","dependencies":[{"issue_id":"k-130","depends_on_id":"k-129","type":"discovered-from","created_at":"2025-10-22T18:00:47.684188-05:00","created_by":"cscheid"}]} -{"id":"k-131","title":"Phase 2: Implement core property tests (well-formed, consistency, bounds)","description":"","notes":"Phase 2 complete: implemented and tested well-formed ranges, offset/row/col consistency, and bounds checking. All validators working on simple,nested, multiline, empty, and edge case files.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T18:00:50.786084-05:00","updated_at":"2025-10-22T18:08:33.467759-05:00","closed_at":"2025-10-22T18:08:34.467759-05:00","dependencies":[{"issue_id":"k-131","depends_on_id":"k-129","type":"discovered-from","created_at":"2025-10-22T18:00:50.787244-05:00","created_by":"cscheid"}]} -{"id":"k-132","title":"Phase 3: Implement structural tests (nesting, sequential)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T18:00:53.79185-05:00","updated_at":"2025-10-26T18:42:00.744388-05:00","closed_at":"2025-10-26T18:42:00.744388-05:00","dependencies":[{"issue_id":"k-132","depends_on_id":"k-129","type":"discovered-from","created_at":"2025-10-22T18:00:53.793409-05:00","created_by":"cscheid"}]} -{"id":"k-133","title":"Phase 4: Implement SourceMapping validation tests","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T18:00:56.919971-05:00","updated_at":"2025-10-26T18:42:01.495515-05:00","closed_at":"2025-10-26T18:42:01.495515-05:00","dependencies":[{"issue_id":"k-133","depends_on_id":"k-129","type":"discovered-from","created_at":"2025-10-22T18:00:56.921558-05:00","created_by":"cscheid"}]} -{"id":"k-134","title":"Phase 5: Integration - run on all smoke tests and edge cases","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T18:00:59.858531-05:00","updated_at":"2025-10-26T18:42:02.312977-05:00","closed_at":"2025-10-26T18:42:02.312977-05:00","dependencies":[{"issue_id":"k-134","depends_on_id":"k-129","type":"discovered-from","created_at":"2025-10-22T18:00:59.85978-05:00","created_by":"cscheid"}]} -{"id":"k-135","title":"Fix bug: End locations have row=0,col=0 instead of computed values","description":"","notes":"Investigation shows: The test_location_health.rs smoke tests currently PASS with 0 violations. The issue was created on 2025-10-22 reporting 24 violations in 6 files, but testing now shows no violations. Either: (1) bugs were fixed between then and now, (2) test detection was changed, or (3) issue is on different branch. Need to check main branch or clarify what specific violations remain.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-22T18:08:30.384258-05:00","updated_at":"2025-10-24T15:08:57.586887-05:00","closed_at":"2025-10-24T15:08:57.586887-05:00","dependencies":[{"issue_id":"k-135","depends_on_id":"k-129","type":"discovered-from","created_at":"2025-10-22T18:08:30.38721-05:00","created_by":"cscheid"}]} -{"id":"k-136","title":"Refactor SourceInfo struct into an enum","description":"Redesign SourceInfo to be an enum instead of a struct with a separate SourceMapping enum. This will make the API clearer by eliminating the confusing Range field that means different things in different contexts. Each variant should contain exactly the data it needs.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T19:27:06.106655-05:00","updated_at":"2025-10-26T18:31:45.414849-05:00","closed_at":"2025-10-26T18:31:45.414849-05:00"} -{"id":"k-137","title":"Refactor SourceInfo to use enum with offsets-only","description":"Remove Transformed variant, change to enum storing only offsets (not Location with row/column). This fixes confusion and a bug in error.rs. See claude-notes/plans/2025-10-22-sourceinfo-enum-refactor.md and claude-notes/sourceinfo-usage-analysis.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T21:11:38.931499-05:00","updated_at":"2025-10-22T21:59:40.261766-05:00","closed_at":"2025-10-22T21:59:40.261766-05:00"} -{"id":"k-138","title":"Phase 1: Implement new SourceInfo enum design","description":"Redesign SourceInfo as enum with Original/Substring/Concat variants, storing only offsets (no row/column). Remove Transformed variant entirely.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T21:11:54.193258-05:00","updated_at":"2025-10-22T21:15:27.352089-05:00","closed_at":"2025-10-22T21:15:27.352089-05:00","dependencies":[{"issue_id":"k-138","depends_on_id":"k-137","type":"discovered-from","created_at":"2025-10-22T21:11:54.194465-05:00","created_by":"cscheid"}]} -{"id":"k-139","title":"Phase 2: Add helper methods and update map_offset","description":"Implement helper methods: length(), start_offset(), end_offset(), from_range(). Update map_offset() to work with new enum.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T21:11:57.232324-05:00","updated_at":"2025-10-22T21:19:09.658039-05:00","closed_at":"2025-10-22T21:19:09.658039-05:00","dependencies":[{"issue_id":"k-139","depends_on_id":"k-137","type":"discovered-from","created_at":"2025-10-22T21:11:57.233836-05:00","created_by":"cscheid"}]} -{"id":"k-14","title":"Update DiagnosticMessageBuilder with with_location()","description":"Add .with_location() method to builder API","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:58:07.82472-05:00","updated_at":"2025-10-18T16:00:10.563035-05:00","closed_at":"2025-10-18T16:00:10.563035-05:00","dependencies":[{"issue_id":"k-14","depends_on_id":"k-13","type":"blocks","created_at":"2025-10-18T13:52:20.678529-05:00","created_by":"import"}]} -{"id":"k-140","title":"Phase 3: Update all quarto-source-map tests","description":"Update all tests in quarto-source-map to work with new enum design and offset-only storage.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T21:12:00.460817-05:00","updated_at":"2025-10-22T21:19:09.671979-05:00","closed_at":"2025-10-22T21:19:09.671979-05:00","dependencies":[{"issue_id":"k-140","depends_on_id":"k-137","type":"discovered-from","created_at":"2025-10-22T21:12:00.462591-05:00","created_by":"cscheid"}]} -{"id":"k-141","title":"Phase 4: Migrate quarto-yaml to new SourceInfo API","description":"Update quarto-yaml parser and error handling to use new SourceInfo API. Fix error.rs bug where it accesses .range.start.row directly.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T21:12:03.838807-05:00","updated_at":"2025-10-22T21:27:28.482932-05:00","closed_at":"2025-10-22T21:27:28.482932-05:00","dependencies":[{"issue_id":"k-141","depends_on_id":"k-137","type":"discovered-from","created_at":"2025-10-22T21:12:03.840678-05:00","created_by":"cscheid"}]} -{"id":"k-142","title":"Phase 5: Migrate quarto-markdown-pandoc to new SourceInfo API","description":"Update all quarto-markdown-pandoc usage of SourceInfo to work with new enum design.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T21:12:07.15497-05:00","updated_at":"2025-10-22T21:57:13.812166-05:00","closed_at":"2025-10-22T21:57:13.812166-05:00","dependencies":[{"issue_id":"k-142","depends_on_id":"k-137","type":"discovered-from","created_at":"2025-10-22T21:12:07.156224-05:00","created_by":"cscheid"}]} -{"id":"k-143","title":"Fix error message rendering: incorrect Substring offsets in error diagnostics","description":"Error messages are not showing ariadne source snippets because Substring SourceInfo is being created with absolute file offsets instead of parent-relative offsets. This causes map_offset() to compute out-of-bounds offsets and return None. Fix: Convert absolute offsets to relative when creating Substring in qmd_error_messages.rs lines 437-441 and 472-476.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-23T07:24:59.119442-05:00","updated_at":"2025-10-23T07:34:44.71287-05:00","closed_at":"2025-10-23T07:34:44.71287-05:00"} -{"id":"k-144","title":"Add test for error corpus ariadne rendering","description":"Add test to verify that all files in resources/error-corpus/*.qmd produce well-formatted ariadne output in text mode with source snippets and proper file:line:column information.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T07:25:08.057917-05:00","updated_at":"2025-10-23T07:34:44.727911-05:00","closed_at":"2025-10-23T07:34:44.727911-05:00","dependencies":[{"issue_id":"k-144","depends_on_id":"k-143","type":"discovered-from","created_at":"2025-10-23T07:25:08.059281-05:00","created_by":"cscheid"}]} -{"id":"k-145","title":"Add test for error corpus JSON source locations","description":"Add test to verify that all files in resources/error-corpus/*.qmd produce JSON errors with proper source location information (file_id and offsets that can be mapped back to row/column).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T07:25:18.540142-05:00","updated_at":"2025-10-23T07:34:44.741261-05:00","closed_at":"2025-10-23T07:34:44.741261-05:00","dependencies":[{"issue_id":"k-145","depends_on_id":"k-143","type":"discovered-from","created_at":"2025-10-23T07:25:18.542403-05:00","created_by":"cscheid"}]} -{"id":"k-146","title":"Fix JSON deserialization to populate SourceContext with files","description":"","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-23T08:12:06.976558-05:00","updated_at":"2025-10-23T08:20:40.23168-05:00","closed_at":"2025-10-23T08:20:40.23168-05:00"} -{"id":"k-147","title":"Serialize line break information in JSON format","description":"","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-23T08:28:34.835065-05:00","updated_at":"2025-10-23T08:32:42.732198-05:00","closed_at":"2025-10-23T08:32:42.732198-05:00"} -{"id":"k-148","title":"Refactor JSON format to use single files array instead of parallel filenames/fileInformation arrays","description":"","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-23T08:40:01.343984-05:00","updated_at":"2025-10-23T08:45:31.672631-05:00","closed_at":"2025-10-23T08:45:31.672631-05:00"} -{"id":"k-149","title":"Implement Phase 1: SourceInfo Reconstruction","description":"Implement ts-packages/rust-qmd-json/src/source-map.ts with SourceInfoReconstructor class. Support Original, Substring, and Concat SourceInfo types with caching. See plan: claude-notes/plans/2025-10-23-json-to-annotated-parse-conversion.md Phase 1","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T12:42:26.416788-05:00","updated_at":"2025-10-23T12:45:20.485265-05:00","closed_at":"2025-10-23T12:45:20.485265-05:00"} -{"id":"k-15","title":"Update rendering to include location","description":"Update to_text() to accept optional SourceContext and to_json() to include location. Handle display formatting (1-based)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:58:09.274555-05:00","updated_at":"2025-10-18T16:01:41.486977-05:00","closed_at":"2025-10-18T16:01:41.486977-05:00"} -{"id":"k-150","title":"Implement Phase 2: Metadata Conversion","description":"Implement ts-packages/rust-qmd-json/src/meta-converter.ts with MetadataConverter class. Convert all MetaValue types to AnnotatedParse. Handle tagged YAML values. See plan: claude-notes/plans/2025-10-23-json-to-annotated-parse-conversion.md Phase 2","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T12:42:34.276871-05:00","updated_at":"2025-10-23T12:47:04.698524-05:00","closed_at":"2025-10-23T12:47:04.698524-05:00","dependencies":[{"issue_id":"k-150","depends_on_id":"k-149","type":"blocks","created_at":"2025-10-23T12:42:34.278634-05:00","created_by":"cscheid"}]} -{"id":"k-151","title":"Implement Phase 3: Integration and Testing","description":"Implement ts-packages/rust-qmd-json/src/index.ts main entry point and types.ts. Write comprehensive tests for all phases. Document API usage. See plan: claude-notes/plans/2025-10-23-json-to-annotated-parse-conversion.md Phase 3","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T12:42:41.537826-05:00","updated_at":"2025-10-23T12:48:48.740615-05:00","closed_at":"2025-10-23T12:48:48.740615-05:00","dependencies":[{"issue_id":"k-151","depends_on_id":"k-150","type":"blocks","created_at":"2025-10-23T12:42:41.539603-05:00","created_by":"cscheid"}]} -{"id":"k-152","title":"Replace any with unknown and add runtime type checks","description":"Replace all 'any' types with 'unknown' in ts-packages/rust-qmd-json and add proper runtime type checking where needed. This improves type safety.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T13:32:20.002258-05:00","updated_at":"2025-10-23T13:35:50.557744-05:00","closed_at":"2025-10-23T13:35:50.557744-05:00"} -{"id":"k-153","title":"Phase 1: TypeScript Type Declarations for Pandoc AST","description":"Create complete TypeScript type definitions for Pandoc JSON schema using discriminated unions. Define Block, Inline, Attr, and supporting types. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T08:19:02.150332-05:00","updated_at":"2025-10-24T08:36:00.404196-05:00","closed_at":"2025-10-24T08:36:00.404196-05:00"} -{"id":"k-154","title":"Phase 2: Inline Converter implementation","description":"Implement InlineConverter class to convert Pandoc Inline nodes to AnnotatedParse. Handle all inline types: Str, Space, Emph, Strong, Code, Math, Span, Link, Image, etc. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T08:19:06.347103-05:00","updated_at":"2025-10-25T16:07:52.581349-05:00","closed_at":"2025-10-25T16:07:52.581349-05:00","dependencies":[{"issue_id":"k-154","depends_on_id":"k-153","type":"blocks","created_at":"2025-10-24T08:19:52.622549-05:00","created_by":"cscheid"}]} -{"id":"k-155","title":"Phase 3: Block Converter (Core Blocks)","description":"Implement BlockConverter class for core Pandoc Block nodes. Handle Para, Header, Lists, CodeBlock, Div, Figure, etc. Excludes DefinitionList and Table (separate phases). See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T08:19:11.188646-05:00","updated_at":"2025-10-25T16:14:20.529174-05:00","closed_at":"2025-10-25T16:14:20.529174-05:00","dependencies":[{"issue_id":"k-155","depends_on_id":"k-153","type":"blocks","created_at":"2025-10-24T08:19:52.638698-05:00","created_by":"cscheid"},{"issue_id":"k-155","depends_on_id":"k-154","type":"blocks","created_at":"2025-10-24T08:19:52.652647-05:00","created_by":"cscheid"}]} -{"id":"k-156","title":"Phase 3b: Definition List Support with desugaring","description":"Handle DefinitionList with proper source mapping through div.definition-list desugaring. Must verify source info preservation through the desugaring step in postprocess.rs. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T08:19:15.386033-05:00","updated_at":"2025-10-25T16:14:24.618835-05:00","closed_at":"2025-10-25T16:14:24.618835-05:00","dependencies":[{"issue_id":"k-156","depends_on_id":"k-155","type":"blocks","created_at":"2025-10-24T08:19:52.666164-05:00","created_by":"cscheid"}]} -{"id":"k-157","title":"Phase 3c: Table Support (most complex)","description":"Handle Table blocks with complete structure (Attr, Caption, ColSpec, TableHead, TableBody[], TableFoot). Most complex block type requiring careful component structure design. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T08:19:19.656839-05:00","updated_at":"2025-10-25T16:14:28.790889-05:00","closed_at":"2025-10-25T16:14:28.790889-05:00","dependencies":[{"issue_id":"k-157","depends_on_id":"k-155","type":"blocks","created_at":"2025-10-24T08:19:52.680563-05:00","created_by":"cscheid"}]} -{"id":"k-158","title":"Phase 4: Document Converter API","description":"Create DocumentConverter to orchestrate all converters. Provide API: parseRustQmdDocument, parseRustQmdBlocks, parseRustQmdBlock, parseRustQmdInline. Update exports and README. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T08:19:24.214798-05:00","updated_at":"2025-10-25T16:16:37.445561-05:00","closed_at":"2025-10-25T16:16:37.445561-05:00","dependencies":[{"issue_id":"k-158","depends_on_id":"k-153","type":"blocks","created_at":"2025-10-24T08:19:52.694058-05:00","created_by":"cscheid"},{"issue_id":"k-158","depends_on_id":"k-154","type":"blocks","created_at":"2025-10-24T08:19:52.707363-05:00","created_by":"cscheid"},{"issue_id":"k-158","depends_on_id":"k-155","type":"blocks","created_at":"2025-10-24T08:19:52.721137-05:00","created_by":"cscheid"},{"issue_id":"k-158","depends_on_id":"k-156","type":"blocks","created_at":"2025-10-24T08:19:52.734911-05:00","created_by":"cscheid"},{"issue_id":"k-158","depends_on_id":"k-157","type":"blocks","created_at":"2025-10-24T08:19:52.74872-05:00","created_by":"cscheid"}]} -{"id":"k-159","title":"Phase 5: Testing \u0026 Validation","description":"Comprehensive testing of all converters. Create test fixtures with quarto-markdown-pandoc, write end-to-end tests, validate source mappings, performance testing. Document linting use case examples. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T08:19:28.532737-05:00","updated_at":"2025-10-26T18:29:52.156094-05:00","closed_at":"2025-10-26T18:29:52.156094-05:00","dependencies":[{"issue_id":"k-159","depends_on_id":"k-158","type":"blocks","created_at":"2025-10-24T08:19:52.762384-05:00","created_by":"cscheid"}]} -{"id":"k-16","title":"Add conversion helpers in pandoc::location","description":"Add to_source_map_info() and to_source_map_info_with_mapping() to pandoc::location::SourceInfo for temporary bridge","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:58:10.719999-05:00","updated_at":"2025-10-18T16:02:22.538397-05:00","closed_at":"2025-10-18T16:02:22.538397-05:00","dependencies":[{"issue_id":"k-16","depends_on_id":"k-14","type":"discovered-from","created_at":"2025-10-18T13:52:28.273282-05:00","created_by":"import"}]} -{"id":"k-160","title":"Phase 6: quarto-cli Integration (deferred)","description":"Integration with quarto-cli validation infrastructure for linting support. Deferred until API is stable and use cases are clear. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-24T08:19:32.846057-05:00","updated_at":"2025-10-24T08:19:32.846057-05:00","dependencies":[{"issue_id":"k-160","depends_on_id":"k-159","type":"blocks","created_at":"2025-10-24T08:19:52.775517-05:00","created_by":"cscheid"}]} -{"id":"k-161","title":"Design solution for recursive type annotation problem","description":"Create a small self-contained TypeScript prototype to design a solution for recursively transforming nested type references when annotating AST nodes. The intersection approach (Type \u0026 { s: number }) doesn't transform nested Inline[] to Annotated_Inline[]. See claude-notes/2025-10-24-recursive-annotation-problem.md for full problem description. Prototype should explore: conditional types, mapped types, type-level recursion to handle arrays/tuples/cross-references.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T09:12:41.397527-05:00","updated_at":"2025-10-24T10:27:04.140204-05:00","closed_at":"2025-10-24T10:27:04.140204-05:00","dependencies":[{"issue_id":"k-161","depends_on_id":"k-153","type":"blocks","created_at":"2025-10-24T09:12:41.402602-05:00","created_by":"cscheid"}]} -{"id":"k-162","title":"Implement Attr/Target source location sideloading in quarto-markdown-pandoc","description":"Extend quarto-markdown-pandoc to output attrS, targetS, and citationIdS fields for tuple-based Pandoc structures that cannot have 's' fields added directly. See claude-notes/plans/2025-10-24-attr-target-sideloading.md for complete design.","notes":"Affects 15 node types: 4 inline (Code, Link, Image, Span), 5 block (CodeBlock, Header, Table, Figure, Div), 5 table components (TableHead, TableBody, TableFoot, Row, Cell), plus Citation. Implementation plan in claude-notes/plans/2025-10-24-attr-target-sideloading.md. Required for k-163 (TypeScript types).","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-24T10:26:21.119278-05:00","updated_at":"2025-10-24T15:48:31.557376-05:00","closed_at":"2025-10-24T15:48:31.557376-05:00"} -{"id":"k-163","title":"Implement full annotated Pandoc AST types in annotated-qmd","description":"Implement complete parallel type hierarchies (Base and Annotated) for all Pandoc AST types in TypeScript. Includes handling attrS, targetS, and citationIdS sideloaded fields. Uses parallel hierarchy approach validated in src/recursive-annotation-type-experiments.ts. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md and claude-notes/2025-10-24-recursive-annotation-problem.md.","notes":"Supersedes and incorporates work originally planned in k-154, k-155, and k-158. Design validated in src/recursive-annotation-type-experiments.ts. Blocked by k-162 (Rust sideloading implementation).","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-24T10:26:32.108233-05:00","updated_at":"2025-11-23T07:21:55.528209-06:00","closed_at":"2025-11-23T07:21:56.528209-06:00","dependencies":[{"issue_id":"k-163","depends_on_id":"k-162","type":"blocks","created_at":"2025-10-24T10:26:32.11259-05:00","created_by":"cscheid"}]} -{"id":"k-164","title":"Fix compilation errors in readers/json.rs (15 errors)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T10:43:37.065085-05:00","updated_at":"2025-10-24T10:54:27.54397-05:00","closed_at":"2025-10-24T10:54:27.54397-05:00","dependencies":[{"issue_id":"k-164","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T10:45:32.30762-05:00","created_by":"cscheid"}]} -{"id":"k-165","title":"Fix compilation errors in writers/native.rs (2 errors)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T10:43:41.161199-05:00","updated_at":"2025-10-24T10:55:13.953795-05:00","closed_at":"2025-10-24T10:55:13.953795-05:00","dependencies":[{"issue_id":"k-165","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T10:45:32.33787-05:00","created_by":"cscheid"}]} -{"id":"k-166","title":"Fix compilation errors in filters.rs (5 errors)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T10:43:45.055881-05:00","updated_at":"2025-10-24T10:56:24.260185-05:00","closed_at":"2025-10-24T10:56:24.260185-05:00","dependencies":[{"issue_id":"k-166","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T10:45:32.36663-05:00","created_by":"cscheid"}]} -{"id":"k-167","title":"Fix compilation errors in pandoc/meta.rs (6 errors)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T10:43:49.079872-05:00","updated_at":"2025-10-24T10:57:52.681088-05:00","closed_at":"2025-10-24T10:57:52.681088-05:00","dependencies":[{"issue_id":"k-167","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T10:45:32.394456-05:00","created_by":"cscheid"}]} -{"id":"k-168","title":"Fix compilation errors in pandoc/inline.rs (2 errors)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T10:43:53.114748-05:00","updated_at":"2025-10-24T10:46:36.162552-05:00","closed_at":"2025-10-24T10:46:36.162552-05:00","dependencies":[{"issue_id":"k-168","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T10:45:32.421854-05:00","created_by":"cscheid"}]} -{"id":"k-169","title":"Fix compilation errors in pandoc/shortcode.rs (3 errors)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T10:43:56.897935-05:00","updated_at":"2025-10-24T10:47:34.756365-05:00","closed_at":"2025-10-24T10:47:34.756365-05:00","dependencies":[{"issue_id":"k-169","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T10:45:32.450003-05:00","created_by":"cscheid"}]} -{"id":"k-17","title":"Add error_at/warn_at to DiagnosticCollector","description":"Add convenience methods error_at() and warn_at() that accept location parameter","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:58:12.306284-05:00","updated_at":"2025-10-18T16:02:50.910791-05:00","closed_at":"2025-10-18T16:02:50.910791-05:00","dependencies":[{"issue_id":"k-17","depends_on_id":"k-14","type":"discovered-from","created_at":"2025-10-18T13:52:28.273998-05:00","created_by":"import"}]} -{"id":"k-170","title":"Fix compilation errors in treesitter_utils/postprocess.rs (7 errors)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T10:44:00.747482-05:00","updated_at":"2025-10-24T11:06:00.607724-05:00","closed_at":"2025-10-24T11:06:00.607724-05:00","dependencies":[{"issue_id":"k-170","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T10:45:32.478936-05:00","created_by":"cscheid"}]} -{"id":"k-171","title":"Fix compilation errors in treesitter_utils/pipe_table.rs (6 errors)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T10:44:04.763726-05:00","updated_at":"2025-10-24T11:06:59.864233-05:00","closed_at":"2025-10-24T11:06:59.864233-05:00","dependencies":[{"issue_id":"k-171","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T10:45:32.507524-05:00","created_by":"cscheid"}]} -{"id":"k-172","title":"Fix compilation errors in treesitter_utils/editorial_marks.rs (4 errors)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T10:44:09.065723-05:00","updated_at":"2025-10-24T11:07:40.188106-05:00","closed_at":"2025-10-24T11:07:40.188106-05:00","dependencies":[{"issue_id":"k-172","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T10:45:32.536276-05:00","created_by":"cscheid"}]} -{"id":"k-173","title":"Fix compilation errors in treesitter_utils/code_span.rs (3 errors)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T10:44:13.13615-05:00","updated_at":"2025-10-24T11:08:25.332487-05:00","closed_at":"2025-10-24T11:08:25.332487-05:00","dependencies":[{"issue_id":"k-173","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T10:45:32.56381-05:00","created_by":"cscheid"}]} -{"id":"k-174","title":"Fix compilation errors in treesitter_utils/section.rs (2 errors)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T10:44:17.307694-05:00","updated_at":"2025-10-24T11:09:22.376036-05:00","closed_at":"2025-10-24T11:09:22.376036-05:00","dependencies":[{"issue_id":"k-174","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T10:45:32.591297-05:00","created_by":"cscheid"}]} -{"id":"k-175","title":"Fix compilation errors in treesitter_utils/document.rs (2 errors)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T10:44:21.126357-05:00","updated_at":"2025-10-24T11:09:25.967312-05:00","closed_at":"2025-10-24T11:09:25.967312-05:00","dependencies":[{"issue_id":"k-175","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T10:45:32.618718-05:00","created_by":"cscheid"}]} -{"id":"k-176","title":"Fix compilation errors in 8 remaining treesitter_utils files (8 errors)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T10:44:25.086682-05:00","updated_at":"2025-10-24T11:12:39.359469-05:00","closed_at":"2025-10-24T11:12:39.359469-05:00","dependencies":[{"issue_id":"k-176","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T10:45:32.646871-05:00","created_by":"cscheid"}]} -{"id":"k-177","title":"Phase 2-6: Implement parser, serialization, and tests for attr/target source tracking","description":"Complete the remaining phases of attr/target source tracking implementation. See claude-notes/2025-10-24-test-plan-attr-source-tracking.md for details.\n\nPhase 1 (Structure Tests) is complete with 26 passing tests.\n\nRemaining work:\n- Phase 2A: Parser unit tests (track source locations during parsing)\n- Phase 2B: Integration tests (end-to-end parsing)\n- Phase 3: JSON serialization tests (output attrS/targetS/citationIdS)\n- Phase 4: JSON deserialization tests (input with backward compatibility)\n- Phase 5: Roundtrip property tests (qmd → JSON → qmd)\n- Phase 6: Complexity tests (nested tables, performance)\n\nTest plan document: claude-notes/2025-10-24-test-plan-attr-source-tracking.md\nTest file: tests/test_attr_source_structure.rs (26 passing tests)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T11:30:20.31147-05:00","updated_at":"2025-11-21T15:21:20.650903-06:00","closed_at":"2025-11-21T15:21:20.650903-06:00"} -{"id":"k-178","title":"Fix remaining IntermediateAttr pattern match errors (9 files)","description":"Apply the pattern: IntermediateAttr(a) -\u003e IntermediateAttr(a, as_) to extract attr_source in: treesitter.rs, code_span.rs, editorial_marks.rs, fenced_code_block.rs, fenced_div_block.rs, image.rs, info_string.rs, inline_link.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T11:43:59.373153-05:00","updated_at":"2025-10-24T11:46:42.75862-05:00","closed_at":"2025-10-24T11:46:42.75862-05:00","dependencies":[{"issue_id":"k-178","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T11:43:59.375983-05:00","created_by":"cscheid"}]} -{"id":"k-179","title":"Use extracted attr_source in all parser functions","description":"Replace all pattern matches IntermediateAttr(a, _) with IntermediateAttr(a, as_) and pass attr_source to final AST node constructors instead of .empty(). Affects: treesitter.rs, inline_link.rs, image.rs, fenced_div_block.rs, code_span.rs, fenced_code_block.rs, editorial_marks.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T11:48:44.890911-05:00","updated_at":"2025-10-24T11:54:23.889669-05:00","closed_at":"2025-10-24T11:54:23.889669-05:00","dependencies":[{"issue_id":"k-179","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T11:48:44.893361-05:00","created_by":"cscheid"}]} -{"id":"k-18","title":"Restore location to caption-without-table warning in postprocess.rs","description":"Update postprocess.rs to use warn_at() with caption_block.source_info for the 'Caption found without table' warning","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:58:14.138418-05:00","updated_at":"2025-11-23T14:42:33.122903-06:00","closed_at":"2025-11-23T14:42:33.122903-06:00"} -{"id":"k-180","title":"Write unit tests for attr_source tracking","description":"Add tests that verify attr_source correctly captures source locations for IDs, classes, and key-value pairs in attributes. Test cases: Span{#id}, Link{.class1 .class2}, CodeBlock{key=value}, etc.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T11:48:48.569893-05:00","updated_at":"2025-10-24T12:15:46.089637-05:00","closed_at":"2025-10-24T12:15:46.089637-05:00","dependencies":[{"issue_id":"k-180","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T11:48:48.572468-05:00","created_by":"cscheid"}]} -{"id":"k-181","title":"Implement JSON serialization for attrS fields","description":"Extend JSON writer to serialize attrS (AttrSourceInfo) fields alongside Attr fields for all relevant Pandoc AST nodes. Format: {attr: [...], attrS: {id: {...}, classes: [...], kvs: [...]}}.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T11:48:52.197387-05:00","updated_at":"2025-10-24T12:49:29.713001-05:00","closed_at":"2025-10-24T12:49:29.713001-05:00","dependencies":[{"issue_id":"k-181","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T11:48:52.199099-05:00","created_by":"cscheid"}]} -{"id":"k-182","title":"Implement JSON deserialization for attrS fields","description":"Extend JSON reader to deserialize attrS fields from JSON and populate AttrSourceInfo in AST nodes. Handle optional attrS fields gracefully (default to empty when missing).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T11:48:55.947772-05:00","updated_at":"2025-10-24T12:57:51.624207-05:00","closed_at":"2025-10-24T12:57:51.624207-05:00","dependencies":[{"issue_id":"k-182","depends_on_id":"k-162","type":"discovered-from","created_at":"2025-10-24T11:48:55.949604-05:00","created_by":"cscheid"}]} -{"id":"k-183","title":"Improve attr_source tests to validate actual source locations","description":"Replace weak assert_ne\\! checks with proper validation of byte offsets and ranges. Tests should verify that attr_source fields point to the correct locations in the input string, not just that they exist. Example: For '[text]{#my-id}', verify id source points to bytes 7-13 ('#my-id').","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T13:30:35.041231-05:00","updated_at":"2025-10-24T13:36:18.082815-05:00","closed_at":"2025-10-24T13:36:18.082815-05:00"} -{"id":"k-184","title":"Fix table caption attr_source merging bug in postprocess.rs","description":"The code extracts caption_attr_source but never merges it into table.attr_source, causing compiler warnings and missing source location data for table attributes that come from captions. See claude-notes/plans/2025-10-24-table-caption-attr-source-fix.md for complete analysis and implementation plan.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-24T13:43:13.361287-05:00","updated_at":"2025-10-24T13:55:21.564143-05:00","closed_at":"2025-10-24T13:55:21.564143-05:00","dependencies":[{"issue_id":"k-184","depends_on_id":"k-183","type":"discovered-from","created_at":"2025-10-24T13:43:13.365295-05:00","created_by":"cscheid"}]} -{"id":"k-185","title":"Table caption parsing fails without blank line before caption","description":"Table captions using the colon syntax require a blank line before the caption line, but Pandoc doesn't require this. Example that fails: '| Header |\\n|--------|\\n| Data |\\n: Caption'. Works with blank line: '| Header |\\n|--------|\\n| Data |\\n\\n: Caption'. This is a parser-level issue in the tree-sitter grammar or processing.","notes":"ROOT CAUSE IDENTIFIED:\n\nThe caption rule in grammar.js:257 requires $._blank_line as first element. When no blank line precedes ': Caption', the pipe table parser treats ':' as valid punctuation in cell contents, creating an extra table row instead of a caption.\n\nKEY INSIGHT: In qmd, ': ' at line start is ONLY used for captions (no definition lists). This means zero ambiguity - we can safely recognize captions without requiring blank lines.\n\nSOLUTION: Two-part fix:\n1. Remove blank line requirement from caption grammar rule\n2. Modify external scanner to terminate pipe tables when next line starts with ': ' (single colon for caption, not '::' for fenced div)\n\nSee detailed plan: claude-notes/plans/2025-10-27-table-caption-blank-line-fix.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-10-24T13:53:14.564757-05:00","updated_at":"2025-10-27T12:39:58.87696-05:00","closed_at":"2025-10-27T12:39:58.87696-05:00","dependencies":[{"issue_id":"k-185","depends_on_id":"k-184","type":"discovered-from","created_at":"2025-10-24T13:53:14.570237-05:00","created_by":"cscheid"}]} -{"id":"k-186","title":"Phase 1: Define TypeScript types with attrS/targetS/citationIdS","description":"Define complete parallel type hierarchies for Annotated_Inline and Annotated_Block with proper nested references. Add AttrSourceInfo, TargetSourceInfo types. Add attrS, targetS, citationIdS fields to appropriate types.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:51:11.189912-05:00","updated_at":"2025-10-24T15:53:20.459575-05:00","closed_at":"2025-10-24T15:53:20.459575-05:00","dependencies":[{"issue_id":"k-186","depends_on_id":"k-163","type":"blocks","created_at":"2025-10-24T15:51:11.192646-05:00","created_by":"cscheid"}]} -{"id":"k-187","title":"Phase 2: Implement InlineConverter for all inline types","description":"Create InlineConverter class following MetadataConverter pattern. Convert all 20 inline types to AnnotatedParse. Handle attrS, targetS, citationIdS sideloaded fields.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:51:32.476424-05:00","updated_at":"2025-10-24T15:59:11.937345-05:00","closed_at":"2025-10-24T15:59:11.937345-05:00","dependencies":[{"issue_id":"k-187","depends_on_id":"k-186","type":"blocks","created_at":"2025-10-24T15:51:32.47813-05:00","created_by":"cscheid"}]} -{"id":"k-188","title":"Phase 3: Implement BlockConverter for core block types","description":"Create BlockConverter class with dependency on InlineConverter. Convert core blocks (Para, Plain, Header, CodeBlock, BulletList, OrderedList, Div, etc.). Exclude DefinitionList and Table (handled in Phase 3b/3c).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:51:36.397143-05:00","updated_at":"2025-10-24T16:01:25.654773-05:00","closed_at":"2025-10-24T16:01:25.654773-05:00","dependencies":[{"issue_id":"k-188","depends_on_id":"k-186","type":"blocks","created_at":"2025-10-24T15:51:36.398701-05:00","created_by":"cscheid"}]} -{"id":"k-189","title":"Phase 3b: Add DefinitionList support to BlockConverter","description":"Handle DefinitionList with proper source mapping through desugaring. Structure is [(term, [definitions])]. Test with div.definition-list fixtures.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:51:40.326918-05:00","updated_at":"2025-10-24T16:02:20.215088-05:00","closed_at":"2025-10-24T16:02:20.215088-05:00","dependencies":[{"issue_id":"k-189","depends_on_id":"k-186","type":"blocks","created_at":"2025-10-24T15:51:40.328785-05:00","created_by":"cscheid"}]} -{"id":"k-19","title":"Add tests for location rendering in diagnostics","description":"Test location rendering in to_text() and to_json(), with and without context","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:58:15.679399-05:00","updated_at":"2025-10-18T16:19:18.95104-05:00","closed_at":"2025-10-18T16:19:18.95104-05:00"} -{"id":"k-190","title":"Phase 3c: Add Table support to BlockConverter","description":"Handle complete Table structure: Attr, Caption, ColSpec[], TableHead, TableBody[], TableFoot. Convert Rows and Cells recursively. Define Annotated_Caption, Annotated_Cell, Annotated_Row types with attrS fields.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:51:44.305597-05:00","updated_at":"2025-10-24T18:55:37.16502-05:00","closed_at":"2025-10-24T18:55:37.16502-05:00","dependencies":[{"issue_id":"k-190","depends_on_id":"k-186","type":"blocks","created_at":"2025-10-24T15:51:44.308373-05:00","created_by":"cscheid"}]} -{"id":"k-191","title":"Phase 4: Implement DocumentConverter","description":"Create DocumentConverter that orchestrates InlineConverter and BlockConverter. Provide convenience functions: parseRustQmdDocument, parseRustQmdBlocks, parseRustQmdBlock, parseRustQmdInline. Update index.ts exports.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:51:48.386415-05:00","updated_at":"2025-10-24T19:02:11.691055-05:00","closed_at":"2025-10-24T19:02:11.691055-05:00","dependencies":[{"issue_id":"k-191","depends_on_id":"k-186","type":"blocks","created_at":"2025-10-24T15:51:48.389066-05:00","created_by":"cscheid"}]} -{"id":"k-192","title":"Phase 5: Write comprehensive tests for annotated Pandoc AST","description":"Create test fixtures from quarto-markdown-pandoc. Write end-to-end tests for complex documents. Validate AnnotatedParse output (result, source, components, start/end). Performance test with large documents. Write documentation with examples.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:51:52.408933-05:00","updated_at":"2025-11-22T14:09:44.542169-06:00","closed_at":"2025-11-22T14:09:44.542169-06:00","dependencies":[{"issue_id":"k-192","depends_on_id":"k-186","type":"blocks","created_at":"2025-10-24T15:51:52.410579-05:00","created_by":"cscheid"},{"issue_id":"k-192","depends_on_id":"k-226","type":"parent-child","created_at":"2025-10-26T14:49:45.979371-05:00","created_by":"cscheid"},{"issue_id":"k-192","depends_on_id":"k-227","type":"parent-child","created_at":"2025-10-26T14:49:45.996428-05:00","created_by":"cscheid"},{"issue_id":"k-192","depends_on_id":"k-199","type":"parent-child","created_at":"2025-10-26T14:49:46.011527-05:00","created_by":"cscheid"},{"issue_id":"k-192","depends_on_id":"k-228","type":"parent-child","created_at":"2025-10-26T14:49:46.025887-05:00","created_by":"cscheid"},{"issue_id":"k-192","depends_on_id":"k-229","type":"parent-child","created_at":"2025-10-26T14:49:46.041169-05:00","created_by":"cscheid"},{"issue_id":"k-192","depends_on_id":"k-230","type":"parent-child","created_at":"2025-10-26T14:49:46.056499-05:00","created_by":"cscheid"}]} -{"id":"k-193","title":"Create helper APIs for navigating flattened list structures in AnnotatedParse","description":"Create helper functions/APIs to navigate the flattened components arrays in BulletList, OrderedList, and DefinitionList AnnotatedParse nodes. These types have nested structure (items, definitions) that is flattened in components for simplicity, but consumers need convenient APIs to navigate the structure.\n\nExamples needed:\n- getListItems(bulletListAP): AnnotatedParse[][] - extract blocks grouped by item\n- getOrderedListItems(orderedListAP): AnnotatedParse[][] - extract blocks grouped by item \n- getDefinitionListEntries(defListAP): {term: AnnotatedParse[], definitions: AnnotatedParse[][]}[] - extract terms and their definitions\n\nThe result field contains the full Pandoc JSON structure, so reconstruction is possible by correlating indices. Consider adding these to a new navigation-helpers.ts module or as methods on a wrapper class.\n\nSee comments in src/block-converter.ts at BulletList, OrderedList, and DefinitionList cases.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-24T16:45:56.281991-05:00","updated_at":"2025-11-22T11:57:47.434955-06:00","closed_at":"2025-11-22T11:57:47.434955-06:00","dependencies":[{"issue_id":"k-193","depends_on_id":"k-215","type":"parent-child","created_at":"2025-10-26T08:48:26.552213-05:00","created_by":"cscheid"}]} -{"id":"k-194","title":"Phase 1: Add source tracking for structural elements in Rust","description":"Add source_info fields to table and list structural elements in quarto-markdown-pandoc to enable proper navigation in TypeScript AnnotatedParse.\n\n**Context**: See detailed design in claude-notes/2025-10-24-structural-components-design.md\n\n**Scope**:\n1. Study filters.rs to understand impact on filter traversal\n2. Add source_info: SourceInfo to table types:\n - Row\n - Cell\n - TableHead\n - TableBody\n - TableFoot\n - Caption (structure itself)\n3. Update table parser to capture structural boundaries\n4. Update JSON serializer to emit 's' field for these structures\n5. Consider list item source tracking (ListItem, DefinitionListItem, Definition)\n6. Update filter infrastructure if needed\n7. Add tests verifying source locations\n\n**Deliverables**:\n- Updated Rust types with source_info\n- Parser captures boundaries\n- JSON output includes 's' for structural elements\n- Filter system handles new elements\n- Tests pass\n\n**Blocks**: k-195 (Phase 2 TypeScript implementation)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T17:25:15.296125-05:00","updated_at":"2025-11-21T15:27:19.855441-06:00","closed_at":"2025-11-21T15:27:19.855441-06:00"} -{"id":"k-195","title":"Phase 2: Implement structural AnnotatedParse nodes in TypeScript","description":"Implement structural AnnotatedParse nodes (table-row, table-cell, etc.) in TypeScript annotated-qmd package to preserve navigation structure.\n\n**Context**: See detailed design in claude-notes/2025-10-24-structural-components-design.md\n\n**Scope**:\n1. Update TypeScript types to include 's: number' for Row, Cell, TableHead, TableBody, TableFoot, Caption\n2. Define synthetic StructuralKind types (table-head, table-row, table-cell, caption-short, caption-long, etc.)\n3. Implement table converter with structural nodes:\n - convertTableHead()\n - convertTableBody()\n - convertTableFoot()\n - convertRow()\n - convertCell()\n - convertCaptionStructured()\n4. Update list converters if Phase 1 includes list support\n5. Add tests validating structural navigation\n\n**Deliverables**:\n- Updated TypeScript types\n- Synthetic kind definitions\n- Table converter with full structural preservation\n- List converters with structural nodes (if applicable)\n- Comprehensive tests\n\n**Dependencies**: Requires k-194 (Rust source tracking) to be complete first","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T17:25:27.833695-05:00","updated_at":"2025-11-21T16:43:30.621215-06:00","closed_at":"2025-11-21T16:43:30.621215-06:00","dependencies":[{"issue_id":"k-195","depends_on_id":"k-194","type":"blocks","created_at":"2025-10-24T17:25:27.835671-05:00","created_by":"cscheid"}]} -{"id":"k-196","title":"Add source tracking for list structural elements","description":"Add source_info fields for list item structures to enable proper navigation in TypeScript AnnotatedParse.\n\n**Context**: Deferred from k-194 (table source tracking). See claude-notes/2025-10-24-structural-components-design.md and claude-notes/2025-10-24-phase1-source-tracking-plan.md\n\n**Problem**: List items are currently represented as tuples/vectors without dedicated structs:\n- BulletList: content: Vec\u003cBlocks\u003e (items are just Vec\u003cBlock\u003e)\n- OrderedList: content: Vec\u003cBlocks\u003e\n- DefinitionList: content: Vec\u003c(Inlines, Vec\u003cBlocks\u003e)\u003e\n\n**Scope**:\n1. Create new structs: ListItem, DefinitionListItem with source_info fields\n2. Update parser to capture source ranges for list items\n3. Update filters.rs to handle new struct types\n4. Update JSON serialization/deserialization\n5. Add tests verifying source locations\n\n**Alternative**: Add parallel source_info arrays instead of changing from tuples to structs\n\n**Dependencies**: Should wait until k-194 (table source tracking) is complete to learn from that implementation\n\n**Blocks**: k-195 (TypeScript structural nodes) - list support will be limited without this","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-24T18:00:06.630322-05:00","updated_at":"2025-11-22T11:16:20.11464-06:00","dependencies":[{"issue_id":"k-196","depends_on_id":"k-194","type":"related","created_at":"2025-10-24T18:00:06.633899-05:00","created_by":"cscheid"}]} -{"id":"k-197","title":"Create test fixtures for missing block types","description":"Add test fixtures and tests for block types not currently covered: OrderedList, DefinitionList, Div with attributes, Figure with caption, HorizontalRule, Null, RawBlock. Generate .qmd files and process with quarto-markdown-pandoc to create .json fixtures. Write integration tests validating conversion.","notes":"STATUS: Partial completion - see claude-notes/k-197-progress.md for detailed progress. ✅ OrderedList, Div, Figure, HorizontalRule, RawBlock completed. ❌ DefinitionList blocked on syntax issue. ❌ Null block not started. 46/49 tests passing. Continue with k-201.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T16:22:53.752307-05:00","updated_at":"2025-10-25T17:04:34.595797-05:00","closed_at":"2025-10-25T17:04:34.595797-05:00","dependencies":[{"issue_id":"k-197","depends_on_id":"k-192","type":"blocks","created_at":"2025-10-25T16:22:53.754059-05:00","created_by":"cscheid"}]} -{"id":"k-198","title":"Create test fixtures for missing inline types","description":"Add test fixtures and tests for inline types not currently covered: Image, Span with attributes, Cite (citations), Note (footnotes), Quoted (single/double), Strikeout, Superscript, Subscript, SmallCaps, Underline, RawInline, SoftBreak, LineBreak. Generate .qmd files and process with quarto-markdown-pandoc to create .json fixtures. Write integration tests validating conversion.","notes":"STATUS: Significant progress - 10/13 inline type tests passing (60/63 total tests). Created inline-types.qmd fixture, generated JSON, wrote comprehensive tests. Fixed critical bugs in inline-converter.ts to handle programmatic attributes without source locations (classes and kvs). Remaining work: Fix 3 failing tests (Image, Note, Quoted). See ts-packages/annotated-qmd/test/inline-types.test.ts","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T16:22:57.988998-05:00","updated_at":"2025-10-26T08:29:10.499327-05:00","closed_at":"2025-10-26T08:29:10.499327-05:00","dependencies":[{"issue_id":"k-198","depends_on_id":"k-192","type":"blocks","created_at":"2025-10-25T16:22:57.991309-05:00","created_by":"cscheid"}]} -{"id":"k-199","title":"Create tests for empty content edge cases","description":"Add test fixtures for edge cases: empty paragraphs, empty lists, empty metadata, empty code blocks, empty strings, null values. Verify converters handle gracefully without errors. Ensure AnnotatedParse structures are valid for empty content.","notes":"Phase 3: Edge Cases Testing. Test empty content, minimal documents, boundary values, null/missing fields, and source mapping edge cases. Create ~25-30 tests with validation helpers. See claude-notes/plans/2025-10-26-k199-edge-cases.md for detailed plan.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T16:23:02.252196-05:00","updated_at":"2025-10-26T15:10:34.7612-05:00","closed_at":"2025-10-26T15:10:34.7612-05:00"} -{"id":"k-1c5v","title":"Phase 1: Core template infrastructure","description":"Add quarto-doctemplate dependency, create src/template/ module with bundle.rs (TemplateBundle struct, JSON parsing), context.rs (MetaValue to TemplateValue conversion), render.rs (orchestration), and mod.rs (re-exports, feature gates).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T11:43:58.95429-06:00","updated_at":"2025-12-05T11:52:57.650458-06:00","closed_at":"2025-12-05T11:52:57.650458-06:00","dependencies":[{"issue_id":"k-1c5v","depends_on_id":"k-y2f3","type":"blocks","created_at":"2025-12-05T11:43:58.956968-06:00","created_by":"cscheid"}]} -{"id":"k-1d4c","title":"Phase 5: WASM entry points for templates","description":"Add render_with_template entry point to wasm_entry_points accepting bundle JSON, update wasm-qmd-parser with wasm_bindgen function.","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-05T11:44:34.098318-06:00","updated_at":"2025-12-05T11:44:34.098318-06:00","dependencies":[{"issue_id":"k-1d4c","depends_on_id":"k-y2f3","type":"blocks","created_at":"2025-12-05T11:44:34.102241-06:00","created_by":"cscheid"},{"issue_id":"k-1d4c","depends_on_id":"k-5u7d","type":"blocks","created_at":"2025-12-05T11:45:09.08709-06:00","created_by":"cscheid"}]} -{"id":"k-1qlj","title":"Phase 5: pampa integration","description":"Create pampa/src/config_meta.rs conversion layer. Implement config_to_meta(). Handle Interpretation::Markdown and PlainString. Update document rendering to use MergedConfig. Integration tests. Plan: claude-notes/plans/2025-12-07-config-merging-design.md Phase 5","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-07T14:04:03.803304-06:00","updated_at":"2025-12-07T14:04:03.803304-06:00","dependencies":[{"issue_id":"k-1qlj","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2025-12-07T14:04:03.805176-06:00","created_by":"cscheid"}]} -{"id":"k-2","title":"Phase A: Add rendering methods to quarto-error-reporting","description":"Implement to_text() and to_json() methods for DiagnosticMessage. Add generic_error() builder helper that uses Q-0-99 and accepts file!() line!() for tracking error origins.\n\nFiles to modify:\n- crates/quarto-error-reporting/src/diagnostic.rs\n- crates/quarto-error-reporting/src/rendering.rs (new)\n- crates/quarto-error-reporting/src/builder.rs\n\nJSON format should match current simple format from ErrorCollector.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T14:41:43.567512-05:00","updated_at":"2025-10-18T15:03:54.064275-05:00","closed_at":"2025-10-18T15:03:54.064275-05:00","dependencies":[{"issue_id":"k-2","depends_on_id":"k-1","type":"parent-child","created_at":"2025-10-18T14:41:43.569059-05:00","created_by":"cscheid"}]} -{"id":"k-20","title":"Run full test suite after location integration","description":"Run cargo test on quarto-error-reporting and quarto-markdown-pandoc, verify all pass","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:58:17.237402-05:00","updated_at":"2025-10-18T16:19:23.558381-05:00","closed_at":"2025-10-18T16:19:23.558381-05:00"} -{"id":"k-200","title":"Performance testing and benchmarking for annotated-qmd","description":"Create performance test suite for annotated-qmd converters. Test with large documents (1000+ blocks), deeply nested structures (10+ levels deep), and complex combinations. Establish baseline performance metrics. Document acceptable performance thresholds. Create benchmark fixtures that can be run periodically to detect regressions.","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-25T16:23:06.346576-05:00","updated_at":"2025-11-22T11:16:20.097895-06:00"} -{"id":"k-201","title":"Fix remaining k-197 test failures and complete fixtures","description":"1. Investigate and fix DefinitionList syntax (currently parser errors on ~ syntax). 2. Fix div-attrs test - custom attributes have null source IDs, test needs adjustment. 3. Create Null block fixture if possible (investigate if user-creatable). 4. Ensure all 49 tests pass. See claude-notes/k-197-progress.md for details.","notes":"Continuation of k-197. Full details in claude-notes/k-197-progress.md. Focus on: 1) DefinitionList syntax investigation, 2) div-attrs test fix for null attrS.kvs, 3) Null block research.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T16:36:25.616275-05:00","updated_at":"2025-10-25T17:04:25.755776-05:00","closed_at":"2025-10-25T17:04:25.755776-05:00","dependencies":[{"issue_id":"k-201","depends_on_id":"k-197","type":"blocks","created_at":"2025-10-25T16:36:25.618156-05:00","created_by":"cscheid"}]} -{"id":"k-202","title":"Create test helper functions for block-types tests","description":"Create helper functions: 1) loadSourceFile(name) to load .qmd alongside JSON, 2) extractTextFromComponents(component) to recursively get text, 3) validateSourceOffset(component, expectedText, sourceFile) to verify offsets point to correct text","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T17:03:23.195605-05:00","updated_at":"2025-10-25T17:05:48.09025-05:00","closed_at":"2025-10-25T17:05:48.09025-05:00","dependencies":[{"issue_id":"k-202","depends_on_id":"k-201","type":"discovered-from","created_at":"2025-10-25T17:03:23.201177-05:00","created_by":"cscheid"}]} -{"id":"k-203","title":"Improve OrderedList test with precise validation","description":"Replace shallow presence checks with precise validation: Check exact count (3 lists), validate text content (First/Second/Third, Fifth/Sixth/Seventh), verify start=5 for custom list, validate nested structure (parent 2 items, nested 2 items), check source locations","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T17:03:33.336516-05:00","updated_at":"2025-10-25T17:12:44.09454-05:00","closed_at":"2025-10-25T17:12:44.09454-05:00","dependencies":[{"issue_id":"k-203","depends_on_id":"k-201","type":"discovered-from","created_at":"2025-10-25T17:03:33.338047-05:00","created_by":"cscheid"},{"issue_id":"k-203","depends_on_id":"k-202","type":"blocks","created_at":"2025-10-25T17:03:33.338782-05:00","created_by":"cscheid"}]} -{"id":"k-204","title":"Improve DefinitionList test with precise validation","description":"Replace shallow presence checks with precise validation: Check exact count (3 definition items), validate term text (Term 1, Term 2, Formatted Term), check Term 2 has 2 definitions, validate definition content text, check source locations","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T17:03:42.53158-05:00","updated_at":"2025-10-25T17:19:35.159696-05:00","closed_at":"2025-10-25T17:19:35.159696-05:00","dependencies":[{"issue_id":"k-204","depends_on_id":"k-201","type":"discovered-from","created_at":"2025-10-25T17:03:42.533218-05:00","created_by":"cscheid"},{"issue_id":"k-204","depends_on_id":"k-202","type":"blocks","created_at":"2025-10-25T17:03:42.533949-05:00","created_by":"cscheid"}]} -{"id":"k-205","title":"Improve Div attributes test with precise validation","description":"Complete the partially-done test: Check actual class values (callout-note, important, panel, outer, inner), validate nested div structure (outer contains inner), check inner div content, validate all attribute source locations point to correct text","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T17:03:50.94275-05:00","updated_at":"2025-10-25T17:23:17.56792-05:00","closed_at":"2025-10-25T17:23:17.56792-05:00","dependencies":[{"issue_id":"k-205","depends_on_id":"k-201","type":"discovered-from","created_at":"2025-10-25T17:03:50.945526-05:00","created_by":"cscheid"},{"issue_id":"k-205","depends_on_id":"k-202","type":"blocks","created_at":"2025-10-25T17:03:50.94629-05:00","created_by":"cscheid"}]} -{"id":"k-206","title":"Improve Figure test with precise validation","description":"Replace shallow presence checks with precise validation: Check exact count (3 figures), validate IDs (fig-simple, fig-with-caption, fig-layout), check caption text content, verify image sources, validate source locations","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T17:03:59.330056-05:00","updated_at":"2025-10-25T17:32:59.817754-05:00","closed_at":"2025-10-25T17:32:59.817754-05:00","dependencies":[{"issue_id":"k-206","depends_on_id":"k-201","type":"discovered-from","created_at":"2025-10-25T17:03:59.331788-05:00","created_by":"cscheid"},{"issue_id":"k-206","depends_on_id":"k-202","type":"blocks","created_at":"2025-10-25T17:03:59.332669-05:00","created_by":"cscheid"}]} -{"id":"k-207","title":"Improve RawBlock test with precise validation","description":"Complete the partially-done test: Validate actual HTML content text (check for expected HTML string), validate actual LaTeX content text (check for expected LaTeX commands), ensure content matches source file text, validate source locations","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T17:04:08.479852-05:00","updated_at":"2025-10-25T17:36:04.510263-05:00","closed_at":"2025-10-25T17:36:04.510263-05:00","dependencies":[{"issue_id":"k-207","depends_on_id":"k-201","type":"discovered-from","created_at":"2025-10-25T17:04:08.481511-05:00","created_by":"cscheid"},{"issue_id":"k-207","depends_on_id":"k-202","type":"blocks","created_at":"2025-10-25T17:04:08.482339-05:00","created_by":"cscheid"}]} -{"id":"k-208","title":"Fix Image inline test - validate target structure","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-26T08:18:01.862451-05:00","updated_at":"2025-10-26T08:19:08.044421-05:00","closed_at":"2025-10-26T08:19:08.044421-05:00","dependencies":[{"issue_id":"k-208","depends_on_id":"k-198","type":"blocks","created_at":"2025-10-26T08:18:01.864848-05:00","created_by":"cscheid"}]} -{"id":"k-209","title":"Fix Note (footnote) inline test - validate footnote structure","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-26T08:18:02.811801-05:00","updated_at":"2025-10-26T08:28:59.968188-05:00","closed_at":"2025-10-26T08:28:59.968188-05:00","dependencies":[{"issue_id":"k-209","depends_on_id":"k-198","type":"blocks","created_at":"2025-10-26T08:18:02.813053-05:00","created_by":"cscheid"}]} -{"id":"k-21","title":"Replace SourceFile.content with FileInformation struct","description":"Replace the full content string storage in SourceFile with a FileInformation struct that stores line break offsets for efficient offset-\u003elocation conversion. This is a prerequisite for the larger quarto-source-map migration.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T17:02:48.466002-05:00","updated_at":"2025-10-18T17:05:55.916257-05:00","closed_at":"2025-10-18T17:05:55.916257-05:00"} -{"id":"k-210","title":"Fix Quoted inline test - validate SingleQuote and DoubleQuote","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-26T08:18:03.572465-05:00","updated_at":"2025-10-26T08:21:47.518356-05:00","closed_at":"2025-10-26T08:21:47.518356-05:00","dependencies":[{"issue_id":"k-210","depends_on_id":"k-198","type":"blocks","created_at":"2025-10-26T08:18:03.573788-05:00","created_by":"cscheid"}]} -{"id":"k-211","title":"Fix document-level source mapping in parseRustQmdDocument","description":"CRITICAL: parseRustQmdDocument returns AnnotatedParse with empty source (start=0, end=0, source.value=''). Should compute document span from first/last elements. User-reported bug blocking interactive usage. See TODO-AUDIT-2025-10-26.md and test/document-level-source.test.ts","notes":"Detailed implementation plan in claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md. Root cause: AnnotatedParse.source should be top-level MappedString, but currently uses local substrings. Need to fix SourceInfoReconstructor to maintain top-level references and update all converters to use new API.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-26T08:47:52.697172-05:00","updated_at":"2025-10-26T11:01:13.072053-05:00","closed_at":"2025-10-26T11:01:13.072053-05:00","dependencies":[{"issue_id":"k-211","depends_on_id":"k-215","type":"parent-child","created_at":"2025-10-26T08:48:26.490156-05:00","created_by":"cscheid"}]} -{"id":"k-212","title":"Improve YAML tagged value encoding in AnnotatedParse","description":"Currently encodes YAML tags in kind string (e.g. 'MetaInlines:tagged:expr'). Enhancement: add optional tag field to AnnotatedParse interface in @quarto/mapped-string package. See src/meta-converter.ts:288-290 and TODO-AUDIT-2025-10-26.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-26T08:47:59.83222-05:00","updated_at":"2025-10-26T14:11:24.255824-05:00","closed_at":"2025-10-26T14:11:24.255824-05:00","dependencies":[{"issue_id":"k-212","depends_on_id":"k-215","type":"parent-child","created_at":"2025-10-26T08:48:26.50839-05:00","created_by":"cscheid"}]} -{"id":"k-213","title":"Improve Concat SourceInfo error reporting","description":"Concat SourceInfo uses first piece's location. May cause confusion in error reporting if error is in later piece. Consider tracking all piece locations or using span of all pieces. See src/source-map.ts:267-268 and TODO-AUDIT-2025-10-26.md","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-26T08:48:06.121405-05:00","updated_at":"2025-10-26T11:58:31.135004-05:00","closed_at":"2025-10-26T11:58:31.135004-05:00","dependencies":[{"issue_id":"k-213","depends_on_id":"k-215","type":"parent-child","created_at":"2025-10-26T08:48:26.523697-05:00","created_by":"cscheid"}]} -{"id":"k-214","title":"Add circular reference detection to SourceInfo resolution","description":"SourceInfo resolution doesn't detect circular references. Could cause infinite loops with malformed data. Add visited ID tracking during resolveChain traversal. Low priority (Rust parser shouldn't produce malformed data). See src/source-map.ts:302-303 and TODO-AUDIT-2025-10-26.md","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-26T08:48:12.402972-05:00","updated_at":"2025-11-23T07:23:08.030986-06:00","dependencies":[{"issue_id":"k-214","depends_on_id":"k-215","type":"parent-child","created_at":"2025-10-26T08:48:26.537954-05:00","created_by":"cscheid"}]} -{"id":"k-215","title":"TODO Audit and Resolution for @quarto/annotated-qmd","description":"Comprehensive audit of TODOs in TypeScript package found 7 items (4 untracked, 3 tracked in k-193). Created tracking tasks k-211 (critical doc source), k-212 (YAML tags), k-213 (Concat), k-214 (circular refs). Must also update TODO comments to reference beads task IDs. See TODO-AUDIT-2025-10-26.md for full report.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-26T08:48:19.434375-05:00","updated_at":"2025-10-26T13:41:12.897767-05:00","closed_at":"2025-10-26T13:41:12.897767-05:00"} -{"id":"k-216","title":"Step 1: Add top-level MappedStrings to SourceInfoReconstructor","description":"Add topLevelMappedStrings field, validate file content in constructor, create MappedString for each file. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 1","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T10:41:30.621972-05:00","updated_at":"2025-10-26T10:51:28.968013-05:00","closed_at":"2025-10-26T10:51:28.968013-05:00","dependencies":[{"issue_id":"k-216","depends_on_id":"k-211","type":"parent-child","created_at":"2025-10-26T10:41:30.624152-05:00","created_by":"cscheid"}]} -{"id":"k-217","title":"Step 2: Fix handleOriginal() to use mappedSubstring","description":"Change handleOriginal() to use mappedSubstring of top-level instead of creating new MappedString. Maintains connection to top-level file. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 2","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T10:41:36.825677-05:00","updated_at":"2025-10-26T10:52:07.126355-05:00","closed_at":"2025-10-26T10:52:07.126355-05:00","dependencies":[{"issue_id":"k-217","depends_on_id":"k-211","type":"parent-child","created_at":"2025-10-26T10:41:36.827371-05:00","created_by":"cscheid"},{"issue_id":"k-217","depends_on_id":"k-216","type":"blocks","created_at":"2025-10-26T10:41:36.828284-05:00","created_by":"cscheid"}]} -{"id":"k-218","title":"Step 3: Add public API for AnnotatedParse source fields","description":"Add getTopLevelMappedString(), getSourceLocation(), and getAnnotatedParseSourceFields() methods to SourceInfoReconstructor. Primary API for converters. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 3","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T10:41:43.395494-05:00","updated_at":"2025-10-26T10:52:48.294202-05:00","closed_at":"2025-10-26T10:52:48.294202-05:00","dependencies":[{"issue_id":"k-218","depends_on_id":"k-211","type":"parent-child","created_at":"2025-10-26T10:41:43.397094-05:00","created_by":"cscheid"},{"issue_id":"k-218","depends_on_id":"k-217","type":"blocks","created_at":"2025-10-26T10:41:43.398116-05:00","created_by":"cscheid"}]} -{"id":"k-219","title":"Step 4: Update InlineConverter to use new API","description":"Replace source/start/end extraction with getAnnotatedParseSourceFields() in all convertInline cases, convertAttr, convertTarget, and convertCitation. Run inline-types.test.ts. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 4","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T10:41:50.590981-05:00","updated_at":"2025-10-26T10:55:17.061504-05:00","closed_at":"2025-10-26T10:55:17.061504-05:00","dependencies":[{"issue_id":"k-219","depends_on_id":"k-211","type":"parent-child","created_at":"2025-10-26T10:41:50.593038-05:00","created_by":"cscheid"},{"issue_id":"k-219","depends_on_id":"k-218","type":"blocks","created_at":"2025-10-26T10:41:50.594103-05:00","created_by":"cscheid"}]} -{"id":"k-22","title":"Create FileInformation struct in quarto-source-map","description":"Create new FileInformation struct with line_breaks: Vec\u003cusize\u003e, total_length: usize. Implement new(content: \u0026str) to build line breaks, and offset_to_location(offset: usize) -\u003e Option\u003cLocation\u003e using binary search.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T17:02:56.232581-05:00","updated_at":"2025-10-18T17:05:45.641994-05:00","closed_at":"2025-10-18T17:05:45.641994-05:00","dependencies":[{"issue_id":"k-22","depends_on_id":"k-21","type":"blocks","created_at":"2025-10-18T17:02:56.234246-05:00","created_by":"cscheid"}]} -{"id":"k-220","title":"Step 5: Update BlockConverter to use new API","description":"Replace source/start/end extraction with getAnnotatedParseSourceFields() in all convertBlock cases and convertCaption. Run block-types.test.ts. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 5","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T10:41:56.222441-05:00","updated_at":"2025-10-26T10:56:38.514039-05:00","closed_at":"2025-10-26T10:56:38.514039-05:00","dependencies":[{"issue_id":"k-220","depends_on_id":"k-211","type":"parent-child","created_at":"2025-10-26T10:41:56.224462-05:00","created_by":"cscheid"},{"issue_id":"k-220","depends_on_id":"k-218","type":"blocks","created_at":"2025-10-26T10:41:56.225308-05:00","created_by":"cscheid"}]} -{"id":"k-221","title":"Step 6: Update MetadataConverter to use new API","description":"Replace source/start/end extraction with getAnnotatedParseSourceFields() in convertMetaValue and convertMeta. Run meta-conversion.test.ts. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 6","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T10:42:01.393932-05:00","updated_at":"2025-10-26T10:59:03.606461-05:00","closed_at":"2025-10-26T10:59:03.606461-05:00","dependencies":[{"issue_id":"k-221","depends_on_id":"k-211","type":"parent-child","created_at":"2025-10-26T10:42:01.395591-05:00","created_by":"cscheid"},{"issue_id":"k-221","depends_on_id":"k-218","type":"blocks","created_at":"2025-10-26T10:42:01.396421-05:00","created_by":"cscheid"}]} -{"id":"k-222","title":"Step 7: Fix DocumentConverter for document-level source","description":"Update convertDocument() to use getTopLevelMappedString(0) for document source with start=0, end=content.length. Run document-level-source.test.ts. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 7","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T10:42:08.577908-05:00","updated_at":"2025-10-26T10:59:39.285131-05:00","closed_at":"2025-10-26T10:59:39.285131-05:00","dependencies":[{"issue_id":"k-222","depends_on_id":"k-211","type":"parent-child","created_at":"2025-10-26T10:42:08.579165-05:00","created_by":"cscheid"},{"issue_id":"k-222","depends_on_id":"k-219","type":"blocks","created_at":"2025-10-26T10:42:08.580001-05:00","created_by":"cscheid"},{"issue_id":"k-222","depends_on_id":"k-220","type":"blocks","created_at":"2025-10-26T10:42:08.580749-05:00","created_by":"cscheid"},{"issue_id":"k-222","depends_on_id":"k-221","type":"blocks","created_at":"2025-10-26T10:42:08.581418-05:00","created_by":"cscheid"}]} -{"id":"k-223","title":"Step 8: Fix test assertions in document-level-source.test.ts","description":"Fix incorrect assertions - document start IS 0. Change notStrictEqual to strictEqual for start and end checks. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 8","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T10:42:14.577444-05:00","updated_at":"2025-10-26T11:00:37.293217-05:00","closed_at":"2025-10-26T11:00:37.293217-05:00","dependencies":[{"issue_id":"k-223","depends_on_id":"k-211","type":"parent-child","created_at":"2025-10-26T10:42:14.579136-05:00","created_by":"cscheid"},{"issue_id":"k-223","depends_on_id":"k-222","type":"blocks","created_at":"2025-10-26T10:42:14.58011-05:00","created_by":"cscheid"}]} -{"id":"k-224","title":"Step 9: Remove TODO comment and verify all tests pass","description":"Remove TODO comment from document-converter.ts. Run full test suite (npm test) - all 64 tests should pass. Close k-211 with summary. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 9","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T10:42:20.667693-05:00","updated_at":"2025-10-26T11:01:03.217626-05:00","closed_at":"2025-10-26T11:01:03.217626-05:00","dependencies":[{"issue_id":"k-224","depends_on_id":"k-211","type":"parent-child","created_at":"2025-10-26T10:42:20.669219-05:00","created_by":"cscheid"},{"issue_id":"k-224","depends_on_id":"k-223","type":"blocks","created_at":"2025-10-26T10:42:20.670053-05:00","created_by":"cscheid"}]} -{"id":"k-225","title":"Fix Str node source mapping off-by-one error for \"information.\"","description":"The Str node for \"information.\" in links.qmd has result=\"information.\" but source range [81, 92] which only extracts \"information\" (missing the period at position 92). The end should be 93. This was discovered by comprehensive substring invariant tests that verify source.value.substring(start, end) matches expected text.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-26T11:23:55.000071-05:00","updated_at":"2025-10-26T11:58:22.696385-05:00","closed_at":"2025-10-26T11:58:22.696385-05:00"} -{"id":"k-226","title":"Phase 1: DocumentConverter Tests","description":"Create test/document-converter.test.ts with comprehensive tests for DocumentConverter class. Test convertDocument(), convertBlocks(), convertBlock(), convertInline(). Verify component ordering. See claude-notes/plans/2025-10-26-k192-comprehensive-testing.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-26T14:49:10.705274-05:00","updated_at":"2025-10-26T14:53:02.42503-05:00","closed_at":"2025-10-26T14:53:02.42503-05:00"} -{"id":"k-227","title":"Phase 2: Complex Document Tests","description":"Create test/complex-documents.test.ts with end-to-end tests using realistic complex documents. Create blog-post.qmd, academic-paper.qmd, tutorial.qmd fixtures. Validate full document structure. See claude-notes/plans/2025-10-26-k192-comprehensive-testing.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-26T14:49:22.874276-05:00","updated_at":"2025-10-26T14:59:08.815485-05:00","closed_at":"2025-10-26T14:59:08.815485-05:00"} -{"id":"k-228","title":"Phase 4: Components Tree Validation","description":"Create validateComponentsTree() helper function. Enhance existing tests with tree structure validation. Test component ordering, nesting, and navigation patterns. See claude-notes/plans/2025-10-26-k192-comprehensive-testing.md","notes":"Phase 4 complete - 27 tree validation tests created and committed. Successfully found and fixed 2 bugs: k-231 (metadata ordering) and k-233 (Figure source ranges). Current: 142/145 tests passing (98%). Remaining 3 failures need investigation: (1) Image attr-value ordering (Str@826 vs attr-value@876), (2) Child/parent start position mismatch, (3) Table attr-id nesting (child end 210 \u003e parent end 180). Code committed in 861dcb3.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-26T14:49:29.306526-05:00","updated_at":"2025-10-26T18:02:19.102887-05:00","closed_at":"2025-10-26T18:02:19.102887-05:00"} -{"id":"k-229","title":"Phase 5: Performance Baseline Tests","description":"Create test/performance.test.ts with performance baseline tests. Generate large test documents (100-200 blocks, deeply nested structures). Measure conversion time, set baseline expectations. See claude-notes/plans/2025-10-26-k192-comprehensive-testing.md","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-26T14:49:34.117898-05:00","updated_at":"2025-11-22T13:42:44.401741-06:00"} -{"id":"k-23","title":"Add comprehensive tests for FileInformation","description":"Test FileInformation::new and offset_to_location with: empty files, single line, multiple lines, offsets at line boundaries, out of bounds, Unicode content. Verify binary search correctness.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T17:03:02.484217-05:00","updated_at":"2025-10-18T17:05:50.600484-05:00","closed_at":"2025-10-18T17:05:50.600484-05:00","dependencies":[{"issue_id":"k-23","depends_on_id":"k-22","type":"blocks","created_at":"2025-10-18T13:52:28.274669-05:00","created_by":"import"},{"issue_id":"k-23","depends_on_id":"k-21","type":"blocks","created_at":"2025-10-18T17:03:02.485794-05:00","created_by":"cscheid"}]} -{"id":"k-230","title":"Phase 6: Documentation and Examples","description":"Expand README with linting examples, complete API reference, and cookbook recipes. Document AnnotatedParse tree structure and source mapping best practices. See claude-notes/plans/2025-10-26-k192-comprehensive-testing.md","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-26T14:49:39.672447-05:00","updated_at":"2025-11-22T14:09:34.747691-06:00","closed_at":"2025-11-22T14:09:34.747691-06:00"} -{"id":"k-231","title":"Bug: Metadata components not in source order","description":"","notes":"Tree validation tests found that metadata (mapping) components are not in source order. Example from simple.json: components array has [key@26, value@34, key@4, value@11] instead of [key@4, value@11, key@26, value@34]. This violates the source ordering invariant. Bug is in meta-converter.ts.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-26T15:23:27.043263-05:00","updated_at":"2025-10-26T16:07:37.710896-05:00","closed_at":"2025-10-26T16:07:37.710896-05:00","dependencies":[{"issue_id":"k-231","depends_on_id":"k-228","type":"discovered-from","created_at":"2025-10-26T15:23:27.045846-05:00","created_by":"cscheid"}]} -{"id":"k-232","title":"Bug: Invalid source ranges (start=0, end=0) for Plain/Figure blocks","description":"","notes":"Tree validation found Plain blocks inside Figure elements with invalid source ranges (start=0, end=0). Root cause: Figure contains nested blocks (block.c[2]) that don't have their own source info IDs in the Rust JSON output. These are synthetic Plain blocks created by Pandoc for figure captions and image wrappers. Options: 1) Skip validation for synthetic blocks, 2) Derive source ranges from parent/children context, 3) Fix Rust parser to provide source info for these blocks.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-26T15:23:27.903527-05:00","updated_at":"2025-10-26T15:37:15.19283-05:00","closed_at":"2025-10-26T15:37:15.19283-05:00","dependencies":[{"issue_id":"k-232","depends_on_id":"k-228","type":"discovered-from","created_at":"2025-10-26T15:23:27.904896-05:00","created_by":"cscheid"}]} -{"id":"k-233","title":"Bug: quarto-markdown-pandoc provides invalid source ranges for Figure blocks","description":"","notes":"Rust parser bug: Figure blocks and their nested Plain blocks have source ranges [0, 0] in sourceInfoPool. Diagnosed with minimal test case (examples/minimal-figure.qmd). Root cause: Source tracking not working for Figure AST construction. See detailed diagnosis in claude-notes/plans/2025-10-26-k233-figure-source-bug.md. Blocking: k-228 tree validation (5 failing tests).","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-26T15:36:24.625848-05:00","updated_at":"2025-10-26T15:54:16.50351-05:00","closed_at":"2025-10-26T15:54:16.50351-05:00","dependencies":[{"issue_id":"k-233","depends_on_id":"k-228","type":"discovered-from","created_at":"2025-10-26T15:36:24.628465-05:00","created_by":"cscheid"}]} -{"id":"k-234","title":"Bug: Image/Link components not in source order","description":"In inline-converter.ts, Image and Link elements construct their components array as [attr, content, target], but in the source the order is [content, target, attr]. This violates source ordering and causes tree validation failures. Example: blog-post.qmd has ![Quarto Logo](url){width=200} where caption is at 826-837 and attr is at 870-879, but components array has attr before caption.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-26T16:10:00.438422-05:00","updated_at":"2025-10-26T16:10:41.080365-05:00","closed_at":"2025-10-26T16:10:41.080365-05:00","dependencies":[{"issue_id":"k-234","depends_on_id":"k-228","type":"discovered-from","created_at":"2025-10-26T16:10:05.767312-05:00","created_by":"cscheid"}]} -{"id":"k-235","title":"Bug: Space element at position 0 inside Para at position 543","description":"Tree validation found a Space inline element with start position 0 inside a Para block starting at position 543 in academic-paper.qmd. This violates the nesting invariant (child start \u003e= parent start). Investigation needed to determine if this is a TypeScript converter issue or Rust parser issue. Test: 'children source ranges checked recursively' in tree-validation.test.ts.","notes":"ROOT CAUSE IDENTIFIED: Rust parser bug. Space after Cite element in footnote gets sourceInfoPool entry with range [0,0]. Found in academic-paper.qmd at source ID 148. The Space appears after '@ipcc2021' inside footnote '^[See @ipcc2021 for comprehensive discussion]'. Source ID 148 maps to range [0,0] instead of actual position (~558-559). This causes TypeScript tree validation to fail because Space reconstructs with start=0, end=0. Location: likely in inline parser when processing Cite elements inside Note content.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-26T16:12:20.784021-05:00","updated_at":"2025-10-26T16:28:19.311741-05:00","closed_at":"2025-10-26T16:28:19.311741-05:00","dependencies":[{"issue_id":"k-235","depends_on_id":"k-228","type":"discovered-from","created_at":"2025-10-26T16:12:36.605897-05:00","created_by":"cscheid"}]} -{"id":"k-236","title":"Bug: Table attr-id extends beyond table boundary","description":"Tree validation found a Table element with an attr-id child that extends beyond the table's end position (attr-id ends at 210, table ends at 180). This violates the nesting invariant (child end \u003c= parent end). Likely occurs when table attributes are positioned after the table in source. Test: 'comprehensive validation - all test documents' in tree-validation.test.ts.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-26T16:12:30.035402-05:00","updated_at":"2025-10-26T16:47:18.290867-05:00","closed_at":"2025-10-26T16:47:18.290867-05:00","dependencies":[{"issue_id":"k-236","depends_on_id":"k-228","type":"discovered-from","created_at":"2025-10-26T16:12:36.621635-05:00","created_by":"cscheid"}]} -{"id":"k-237","title":"Bug: Multi-citation component ordering violates source order","description":"Tree validation fails with 'Space start 811 \u003e= citation-id start 813' in academic-paper.qmd. In multi-citation contexts like [@doe2020; @smith2020], citation-id components are placed after all content (Str/Space), but should be interleaved by source position. Current: [Str, Space, Str, cit-id-1, cit-id-2]. Expected: [Str, cit-id-1, Space, Str, cit-id-2]. See claude-notes/plans/2025-10-26-k237-cite-ordering.md for detailed analysis.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-26T17:48:43.787387-05:00","updated_at":"2025-10-26T18:01:47.435407-05:00","closed_at":"2025-10-26T18:01:47.435407-05:00","dependencies":[{"issue_id":"k-237","depends_on_id":"k-236","type":"discovered-from","created_at":"2025-10-26T17:48:43.78987-05:00","created_by":"cscheid"}]} -{"id":"k-238","title":"Bug: Table nesting violation - Plain caption extends beyond Table boundary","description":"After fixing k-236 and k-237, a new table nesting issue appeared: 'Child Plain end 1168 should be \u003c= parent Table end 1132'. This indicates the table caption Plain element extends beyond the Table's end position. Need to investigate if k-236 fix over-extended table bounds or if caption Plain has wrong bounds.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-26T17:54:06.715172-05:00","updated_at":"2025-10-26T18:01:49.334469-05:00","closed_at":"2025-10-26T18:01:49.334469-05:00","dependencies":[{"issue_id":"k-238","depends_on_id":"k-237","type":"discovered-from","created_at":"2025-10-26T17:54:06.717747-05:00","created_by":"cscheid"}]} -{"id":"k-239","title":"bd-8 Phase 1: Audit existing Schema::from_yaml() implementation","description":"Audit the existing Rust Schema::from_yaml() implementation against quarto-cli patterns. Test all 12 YAML syntax patterns. Document what works, what's broken, what's missing. Deliverable: Comprehensive audit report written to claude-notes/.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T13:04:24.035941-05:00","updated_at":"2025-10-27T13:08:16.912137-05:00","closed_at":"2025-10-27T13:08:16.912137-05:00","dependencies":[{"issue_id":"k-239","depends_on_id":"k-8","type":"blocks","created_at":"2025-10-27T13:04:24.039229-05:00","created_by":"cscheid"}]} -{"id":"k-24","title":"Update SourceFile to use FileInformation","description":"Replace content: Option\u003cString\u003e with file_info: Option\u003cFileInformation\u003e in SourceFile struct. Update SourceContext::add_file to accept content and build FileInformation. Update without_content() method.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T17:03:07.306929-05:00","updated_at":"2025-10-18T17:05:50.601812-05:00","closed_at":"2025-10-18T17:05:50.601812-05:00","dependencies":[{"issue_id":"k-24","depends_on_id":"k-23","type":"blocks","created_at":"2025-10-18T13:52:28.275374-05:00","created_by":"import"},{"issue_id":"k-24","depends_on_id":"k-21","type":"blocks","created_at":"2025-10-18T17:03:07.308519-05:00","created_by":"cscheid"}]} -{"id":"k-240","title":"bd-8 Phase 2: Fix identified gaps in Schema::from_yaml()","description":"Fix all gaps identified in Phase 1 audit. Priority order: Critical (common use cases) → High (many quarto-cli schemas) → Medium (completeness) → Low (nice-to-have). Test-driven: failing test → implementation → passing test for each fix.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T13:04:30.876111-05:00","updated_at":"2025-10-27T14:08:07.071665-05:00","closed_at":"2025-10-27T14:08:07.071665-05:00","dependencies":[{"issue_id":"k-240","depends_on_id":"k-8","type":"blocks","created_at":"2025-10-27T13:04:30.877417-05:00","created_by":"cscheid"},{"issue_id":"k-240","depends_on_id":"k-239","type":"blocks","created_at":"2025-10-27T13:04:30.878289-05:00","created_by":"cscheid"}]} -{"id":"k-241","title":"bd-8 Phase 3: Comprehensive testing with real quarto-cli schemas","description":"Parse all quarto-cli definition schemas from definitions.yml. Parse schemas from document-execute.yml. Create round-trip validation tests. Ensure all quarto-cli schemas parse successfully without errors.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T13:04:36.879689-05:00","updated_at":"2025-10-27T14:12:40.073286-05:00","closed_at":"2025-10-27T14:12:40.073286-05:00","dependencies":[{"issue_id":"k-241","depends_on_id":"k-8","type":"blocks","created_at":"2025-10-27T13:04:36.882217-05:00","created_by":"cscheid"},{"issue_id":"k-241","depends_on_id":"k-240","type":"blocks","created_at":"2025-10-27T13:04:36.883698-05:00","created_by":"cscheid"}]} -{"id":"k-242","title":"bd-8 Phase 4: Documentation for Schema::from_yaml()","description":"Create comprehensive documentation: API docs with quarto-cli examples, pattern correspondence table mapping YAML → Rust, usage guide. File: private-crates/quarto-yaml-validation/SCHEMA-FROM-YAML.md","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T13:04:43.589719-05:00","updated_at":"2025-10-27T14:23:12.685582-05:00","closed_at":"2025-10-27T14:23:12.685582-05:00","dependencies":[{"issue_id":"k-242","depends_on_id":"k-8","type":"blocks","created_at":"2025-10-27T13:04:43.591469-05:00","created_by":"cscheid"},{"issue_id":"k-242","depends_on_id":"k-241","type":"blocks","created_at":"2025-10-27T13:04:43.592543-05:00","created_by":"cscheid"}]} -{"id":"k-243","title":"Refactor schema.rs into smaller modules before Phase 2 implementation","description":"schema.rs is 1299 lines and will grow significantly with Phase 2 additions (arrayOf, maybeArrayOf, record, etc.). Split into logical modules for better maintainability and reduced context size:\n\nProposed structure:\n- schema/mod.rs - Schema enum, types, SchemaRegistry\n- schema/types.rs - Schema struct definitions (Boolean, Number, String, etc.)\n- schema/annotations.rs - SchemaAnnotations and parsing\n- schema/parser.rs - from_yaml() entry point and dispatch\n- schema/parsers/primitive.rs - boolean, number, string, null, any parsers\n- schema/parsers/composite.rs - anyOf, allOf, array, object parsers\n- schema/parsers/enum.rs - enum parser\n- schema/parsers/ref.rs - ref parser\n- schema/helpers.rs - Helper functions (get_hash_string, yaml_to_json_value, etc.)\n\nBenefits:\n- Smaller files (\u003c300 lines each)\n- Reduced token usage when editing specific parsers\n- Easier to review and test\n- Clear separation of concerns\n- Prepares for Phase 2 additions\n\nThis refactoring should be completed BEFORE starting Phase 2 (k-240).","notes":"Detailed refactoring plan: claude-notes/plans/2025-10-27-schema-refactoring-structure.md\n\nModule structure:\n- schema/mod.rs (~150 lines) - Schema enum, public API\n- schema/types.rs (~250 lines) - All schema struct definitions\n- schema/annotations.rs (~100 lines) - SchemaAnnotations\n- schema/parser.rs (~100 lines) - from_yaml entry point\n- schema/parsers/primitive.rs (~200 lines) - boolean, number, string, null, any\n- schema/parsers/enum.rs (~100 lines) - enum parser\n- schema/parsers/ref.rs (~50 lines) - ref parser\n- schema/parsers/combinators.rs (~120 lines) - anyOf, allOf\n- schema/parsers/arrays.rs (~90 lines) - array parser\n- schema/parsers/objects.rs (~250 lines) - object parser\n- schema/parsers/wrappers.rs (~50 lines) - future use\n- schema/helpers.rs (~200 lines) - helper functions\n\nLargest file after Phase 2: ~280 lines (objects.rs)\nEstimated time: 2-3 hours","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T13:13:15.494043-05:00","updated_at":"2025-10-27T13:26:27.793481-05:00","closed_at":"2025-10-27T13:26:27.793481-05:00","dependencies":[{"issue_id":"k-243","depends_on_id":"k-240","type":"blocks","created_at":"2025-10-27T13:13:15.497054-05:00","created_by":"cscheid"},{"issue_id":"k-243","depends_on_id":"k-8","type":"blocks","created_at":"2025-10-27T13:13:21.198885-05:00","created_by":"cscheid"}]} -{"id":"k-244","title":"Implement P2/P3 YAML schema patterns for completeness","description":"Implement remaining YAML schema patterns identified in the bd-8 audit but deferred as lower priority. These patterns are not critical for current quarto-cli usage but would provide completeness.\n\nReference: claude-notes/plans/2025-10-27-bd-8-yaml-schema-from-yaml-comprehensive-plan.md\nReference: claude-notes/audits/2025-10-27-bd-8-phase1-schema-from-yaml-audit.md\n\nP2 Patterns (Medium priority - used in some quarto-cli schemas):\n- Nested property extraction (double setBaseSchemaProperties pattern)\n- Schema inheritance (super/baseSchema)\n- ResolveRef vs ref distinction\n- PropertyNames support\n- NamingConvention validation\n- AdditionalCompletions support\n\nP3 Patterns (Lower priority - rarely used):\n- Pattern as schema type\n\nCurrent status: All P0/P1 patterns complete with 100% success rate on tested schemas. These P2/P3 patterns are enhancements for edge cases and advanced usage.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-27T14:28:37.353676-05:00","updated_at":"2025-10-27T15:44:24.504843-05:00","closed_at":"2025-10-27T15:44:24.504843-05:00"} -{"id":"k-245","title":"Implement nested property extraction (double setBaseSchemaProperties)","description":"Implement the double property application pattern from quarto-cli where annotations can be applied at multiple levels.\n\nPattern: Properties defined at outer level should merge with/override properties at inner level.\n\nExample from quarto-cli:\n\n\nThe inner schema gets its own annotations, plus inherits/merges with outer annotations.\n\nSee: claude-notes/plans/2025-10-27-bd-8-yaml-schema-from-yaml-comprehensive-plan.md\nImplementation location: src/schema/parsers/wrappers.rs (TODO comment exists)\n\nEstimated: 2-3 hours","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T14:28:48.030448-05:00","updated_at":"2025-10-27T14:38:17.309306-05:00","closed_at":"2025-10-27T14:38:17.309306-05:00","dependencies":[{"issue_id":"k-245","depends_on_id":"k-244","type":"parent-child","created_at":"2025-10-27T14:28:48.034376-05:00","created_by":"cscheid"}]} -{"id":"k-246","title":"Implement schema inheritance (super/baseSchema)","description":"Implement schema inheritance pattern where schemas can extend base schemas. Pattern allows composing schemas by inheriting properties from a base schema. See claude-notes/plans/2025-10-27-bd-8-yaml-schema-from-yaml-comprehensive-plan.md for details. Estimated: 3-4 hours","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T14:28:55.328787-05:00","updated_at":"2025-10-27T15:44:06.294854-05:00","closed_at":"2025-10-27T15:44:06.294854-05:00","dependencies":[{"issue_id":"k-246","depends_on_id":"k-244","type":"parent-child","created_at":"2025-10-27T14:28:55.331193-05:00","created_by":"cscheid"}]} -{"id":"k-247","title":"Implement resolveRef vs ref distinction","description":"Implement distinction between ref and resolveRef for more sophisticated reference resolution. Currently both ref and $ref are treated identically. This pattern allows different resolution strategies. See claude-notes/plans/2025-10-27-bd-8-yaml-schema-from-yaml-comprehensive-plan.md. Estimated: 1-2 hours","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T14:29:01.798451-05:00","updated_at":"2025-10-27T14:46:02.772603-05:00","closed_at":"2025-10-27T14:46:02.772603-05:00","dependencies":[{"issue_id":"k-247","depends_on_id":"k-244","type":"parent-child","created_at":"2025-10-27T14:29:01.801143-05:00","created_by":"cscheid"}]} -{"id":"k-248","title":"Add propertyNames support to object schemas","description":"Add propertyNames validation to object schemas. This allows validating property names against a schema pattern (e.g., all property names must match a regex). JSON Schema standard feature. Implementation location: src/schema/parsers/objects.rs and src/schema/types.rs. Estimated: 2 hours","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T14:29:08.156793-05:00","updated_at":"2025-10-27T14:49:55.414023-05:00","closed_at":"2025-10-27T14:49:55.414023-05:00","dependencies":[{"issue_id":"k-248","depends_on_id":"k-244","type":"parent-child","created_at":"2025-10-27T14:29:08.158192-05:00","created_by":"cscheid"}]} -{"id":"k-249","title":"Add namingConvention validation support","description":"Add namingConvention validation for property names. Quarto extension that validates property names follow conventions like camelCase, snake_case, kebab-case. Implementation location: src/schema/parsers/objects.rs. Estimated: 2 hours","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T14:29:15.181382-05:00","updated_at":"2025-10-27T14:58:22.784063-05:00","closed_at":"2025-10-27T14:58:22.784063-05:00","dependencies":[{"issue_id":"k-249","depends_on_id":"k-244","type":"parent-child","created_at":"2025-10-27T14:29:15.183141-05:00","created_by":"cscheid"}]} -{"id":"k-25","title":"Update mapping.rs to use FileInformation","description":"In SourceInfo::map_offset, change from file.content.as_ref() + utils::offset_to_location to file.file_info.as_ref() + file_info.offset_to_location(). Update error handling.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T17:03:12.879249-05:00","updated_at":"2025-10-18T17:05:50.60262-05:00","closed_at":"2025-10-18T17:05:50.60262-05:00","dependencies":[{"issue_id":"k-25","depends_on_id":"k-24","type":"blocks","created_at":"2025-10-18T13:52:28.276125-05:00","created_by":"import"},{"issue_id":"k-25","depends_on_id":"k-21","type":"blocks","created_at":"2025-10-18T17:03:12.881031-05:00","created_by":"cscheid"}]} -{"id":"k-250","title":"Add additionalCompletions support","description":"Add additionalCompletions annotation support. This allows specifying additional sources for IDE completions beyond static values. Quarto extension for dynamic completion support. Implementation location: src/schema/annotations.rs. Estimated: 1-2 hours","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T14:29:20.831447-05:00","updated_at":"2025-10-27T15:06:09.812703-05:00","closed_at":"2025-10-27T15:06:09.812703-05:00","dependencies":[{"issue_id":"k-250","depends_on_id":"k-244","type":"parent-child","created_at":"2025-10-27T14:29:20.833199-05:00","created_by":"cscheid"}]} -{"id":"k-251","title":"Implement pattern as schema type (P3)","description":"Implement pattern as a primary schema type (not just a string validation constraint). Rarely used pattern from quarto-cli. Lower priority as not commonly needed. See claude-notes/plans/2025-10-27-bd-8-yaml-schema-from-yaml-comprehensive-plan.md. Estimated: 2-3 hours","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-27T14:29:27.504693-05:00","updated_at":"2025-11-23T15:31:46.507675-06:00","dependencies":[{"issue_id":"k-251","depends_on_id":"k-244","type":"parent-child","created_at":"2025-10-27T14:29:27.507027-05:00","created_by":"cscheid"}]} -{"id":"k-252","title":"Implement schema compilation with registry support","description":"Implement Schema::compile() method that resolves eager references and merges inheritance at compilation time. This enables two-phase schema processing: (1) stateless parsing without registry, (2) compilation with registry that produces structurally complete schemas ready for validation.\n\nKey components:\n- Schema::compile(\u0026registry) method with recursive compilation\n- Resolve eager refs (resolveRef) during compilation\n- Keep lazy refs (ref) for validation-time resolution\n- Support circular lazy references\n- Error handling for missing eager refs and circular eager refs\n- Comprehensive tests with real quarto-cli schemas\n\nSee claude-notes/designs/2025-10-27-schema-compilation-phase.md for full design.\n\nEstimated: 4-6 hours","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T15:31:24.990369-05:00","updated_at":"2025-10-27T15:49:23.30302-05:00","closed_at":"2025-10-27T15:49:23.30302-05:00","dependencies":[{"issue_id":"k-252","depends_on_id":"k-246","type":"blocks","created_at":"2025-10-27T15:31:24.994215-05:00","created_by":"cscheid"}]} -{"id":"k-253","title":"Improve YAML validation error reporting with contextual hints and JSON output","description":"Study and improve error messages in quarto-yaml-validation to provide contextual hints about validation failures and structured JSON output. Use validate-yaml binary as test bed. Compare with TypeScript validator implementation.","notes":"Study and improve error messages in quarto-yaml-validation to provide contextual hints about validation failures and structured JSON output. Use validate-yaml binary as test bed.\n\n**Plan**: See claude-notes/plans/2025-10-27-k-253-yaml-validation-error-reporting.md\n\n**Summary**: Comprehensive analysis complete. Found key issues:\n1. Source location tracking broken (shows \u003cunknown\u003e at line 0)\n2. No ariadne visual source highlighting (infrastructure exists but not wired up)\n3. No JSON output mode\n4. AnyOf error pruning not implemented (TypeScript has sophisticated heuristics)\n\n**Recommended phases**:\n- Phase 1 (Essential): Fix source location tracking (3-4h)\n- Phase 2 (High value): Enable ariadne visual reports (2-3h) \n- Phase 3 (Nice to have): Enhanced error messages (4-5h)\n- Phase 4 (Essential): JSON output mode (2-3h)\n- Phase 5 (Advanced): AnyOf error pruning (6-8h)\n\n**Next**: Review plan and decide which phases to implement.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T16:01:41.540528-05:00","updated_at":"2025-10-27T19:00:17.403934-05:00","closed_at":"2025-10-27T19:00:17.403934-05:00"} -{"id":"k-254","title":"Phase 1: Fix source location tracking in YAML validation","description":"Fix broken source location tracking in quarto-yaml-validation. Currently shows '\u003cunknown\u003e' at line 0. Need to thread SourceContext through validation pipeline.\n\n**Plan**: claude-notes/plans/2025-10-27-k-253-yaml-validation-error-reporting.md (Phase 1)\n\n**Changes**:\n1. Thread SourceContext through validate() and ValidationContext\n2. Update with_yaml_node() to properly extract file/line/column using SourceContext\n3. Update validate-yaml binary to build and pass SourceContext\n4. Test that errors show real file names and line numbers\n\n**Estimate**: 3-4 hours\n**Blocks**: k-253 (parent), k-255, k-256 (phases 2 \u0026 3 depend on this)","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-27T16:11:34.537137-05:00","updated_at":"2025-10-27T16:16:13.911919-05:00","closed_at":"2025-10-27T16:16:13.911919-05:00","dependencies":[{"issue_id":"k-254","depends_on_id":"k-253","type":"parent-child","created_at":"2025-10-27T16:11:34.541569-05:00","created_by":"cscheid"}]} -{"id":"k-255","title":"Phase 2: Enable ariadne visual reports for YAML validation","description":"Add beautiful ariadne source highlighting to YAML validation errors.\n\n**Plan**: claude-notes/plans/2025-10-27-k-253-yaml-validation-error-reporting.md (Phase 2)\n\n**Changes**:\n1. Store SourceInfo in ValidationError (instead of yaml_node)\n2. Update error_conversion to set location on DiagnosticMessage\n3. Update display_diagnostic to pass SourceContext for ariadne rendering\n4. Add tests for visual output\n\n**Expected**: Box-drawing output with source highlighting showing exact error location\n\n**Estimate**: 2-3 hours\n**Depends on**: Phase 1 (k-254)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T16:11:35.341424-05:00","updated_at":"2025-10-27T18:42:53.114542-05:00","closed_at":"2025-10-27T18:42:53.114542-05:00","dependencies":[{"issue_id":"k-255","depends_on_id":"k-253","type":"parent-child","created_at":"2025-10-27T16:11:35.342768-05:00","created_by":"cscheid"},{"issue_id":"k-255","depends_on_id":"k-254","type":"blocks","created_at":"2025-10-27T16:11:35.343534-05:00","created_by":"cscheid"}]} -{"id":"k-256","title":"Phase 3: Enhanced error messages for YAML validation","description":"Add richer contextual information to YAML validation error messages.\n\n**Plan**: claude-notes/plans/2025-10-27-k-253-yaml-validation-error-reporting.md (Phase 3)\n\n**Improvements**:\n1. Schema location hints (where in schema the constraint comes from)\n2. Expected value hints (show allowed enum values, number ranges)\n3. Property name suggestions (spell-check for unknown properties)\n4. Better schema path formatting (breadcrumbs instead of raw path)\n\n**Estimate**: 4-5 hours\n**Depends on**: Phase 1 (k-254)","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-27T16:11:36.370317-05:00","updated_at":"2025-11-22T11:16:20.080536-06:00","dependencies":[{"issue_id":"k-256","depends_on_id":"k-253","type":"parent-child","created_at":"2025-10-27T16:11:36.372338-05:00","created_by":"cscheid"},{"issue_id":"k-256","depends_on_id":"k-254","type":"blocks","created_at":"2025-10-27T16:11:36.373273-05:00","created_by":"cscheid"}]} -{"id":"k-257","title":"Phase 4: Add JSON output mode to validate-yaml","description":"Add structured JSON output mode for machine-readable error reporting.\n\n**Plan**: claude-notes/plans/2025-10-27-k-253-yaml-validation-error-reporting.md (Phase 4)\n\n**Changes**:\n1. Add --json flag to validate-yaml CLI\n2. JSON output for validation errors (using DiagnosticMessage::to_json())\n3. JSON output for success case\n4. Tests for JSON output structure\n\n**Use cases**: Editor integrations, CI/CD pipelines, programmatic error handling\n\n**Estimate**: 2-3 hours\n**Independent**: Can be done in parallel with Phase 1","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-27T16:11:37.388934-05:00","updated_at":"2025-10-27T16:17:17.713815-05:00","closed_at":"2025-10-27T16:17:17.713815-05:00","dependencies":[{"issue_id":"k-257","depends_on_id":"k-253","type":"parent-child","created_at":"2025-10-27T16:11:37.390293-05:00","created_by":"cscheid"}]} -{"id":"k-258","title":"Phase 5: Implement anyOf error pruning in YAML validator","description":"Port sophisticated anyOf error pruning heuristics from TypeScript validator.\n\n**Plan**: claude-notes/plans/2025-10-27-k-253-yaml-validation-error-reporting.md (Phase 5)\n\n**Features**:\n1. Error quality scoring based on error type\n2. Prefer 'required field' errors over 'invalid property' errors\n3. Select best error group by quality and span size\n4. Update validate_any_of() to use pruning\n\n**Complexity**: Complex heuristics, needs careful testing against TypeScript validator\n\n**Estimate**: 6-8 hours\n**Depends on**: Phase 1 (k-254)","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-27T16:11:39.556529-05:00","updated_at":"2025-11-22T11:16:20.060665-06:00","dependencies":[{"issue_id":"k-258","depends_on_id":"k-253","type":"parent-child","created_at":"2025-10-27T16:11:39.557941-05:00","created_by":"cscheid"},{"issue_id":"k-258","depends_on_id":"k-254","type":"blocks","created_at":"2025-10-27T16:11:39.558767-05:00","created_by":"cscheid"}]} -{"id":"k-259","title":"Redesign validation error architecture to match quarto-markdown-pandoc","description":"Redesign validation error structs to separate error data from presentation, following quarto-markdown-pandoc's architecture.\n\n**Current problem**:\n- ValidationError → DiagnosticMessage conversion loses machine-readable structure\n- JSON output is just rendered DiagnosticMessage, not purpose-built\n- Missing: full source ranges, schema paths, instance paths in structured format\n\n**Goal**:\n- Validator returns rich error struct with all information\n- Error struct can be rendered for humans (ariadne) or machines (JSON)\n- JSON output has full source ranges, paths, filenames in machine-readable format\n\n**Study**: Compare quarto-markdown-pandoc error architecture with validate-yaml\n**Output**: Written plan with proposed design","notes":"**Updated Plan (v2)**: See claude-notes/plans/2025-10-27-k-259-validation-error-architecture-redesign-v2.md\n\n**Key Changes from v1**:\n1. ✅ Use wrapper type (ValidationDiagnostic) instead of metadata field\n2. ✅ Use filename strings instead of file_id numbers\n3. ✅ Full SourceRange with start/end offsets + line/column\n\n**Architecture**:\n- Create ValidationDiagnostic wrapper type in quarto-yaml-validation\n- Wraps DiagnosticMessage for text rendering\n- Custom to_json() with purpose-built structure\n- SourceRange has filename + full range info\n\n**Benefits**:\n- Type-safe (no Option, no pattern matching)\n- Clean separation (DiagnosticMessage stays generic)\n- Filename-based JSON (no file registry needed)\n- Custom JSON tailored for validation\n- Extensible (other diagnostics can follow same pattern)\n\n**Timeline**: 6-9 hours (3-4h diagnostic + 1-2h binary + 2-3h testing)\n\n**Next**: Review v2 plan and start implementation","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-27T16:26:36.023571-05:00","updated_at":"2025-11-23T16:33:25.614765-06:00","closed_at":"2025-11-23T16:33:25.614765-06:00","dependencies":[{"issue_id":"k-259","depends_on_id":"k-253","type":"parent-child","created_at":"2025-10-27T16:26:36.026971-05:00","created_by":"cscheid"}]} -{"id":"k-26","title":"Update quarto-source-map tests for FileInformation","description":"Update all existing tests in context.rs and mapping.rs to work with FileInformation instead of content. Ensure serialization tests still pass. Run full test suite.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T17:03:18.170754-05:00","updated_at":"2025-10-18T17:05:50.603342-05:00","closed_at":"2025-10-18T17:05:50.603342-05:00","dependencies":[{"issue_id":"k-26","depends_on_id":"k-25","type":"blocks","created_at":"2025-10-18T13:52:28.276809-05:00","created_by":"import"},{"issue_id":"k-26","depends_on_id":"k-21","type":"blocks","created_at":"2025-10-18T17:03:18.171966-05:00","created_by":"cscheid"}]} -{"id":"k-260","title":"Phase 1: Create ValidationDiagnostic wrapper type","description":"Create ValidationDiagnostic wrapper type with structured error data.\n\n**Plan**: claude-notes/plans/2025-10-27-k-259-validation-error-architecture-redesign-v2.md (Phase 1)\n\n**Tasks**:\n1. Create private-crates/quarto-yaml-validation/src/diagnostic.rs\n2. Define ValidationDiagnostic, PathSegment, SourceRange structs\n3. Implement from_validation_error() with SourceContext\n4. Implement to_json() with custom structure\n5. Implement to_text() by building DiagnosticMessage\n6. Add unit tests for conversion and serialization\n\n**Key feature**: SourceRange has filename (not file_id) + full range with start/end offsets and line/column\n\n**Estimate**: 3-4 hours","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-27T16:46:55.734981-05:00","updated_at":"2025-10-27T16:49:11.657292-05:00","closed_at":"2025-10-27T16:49:11.657292-05:00","dependencies":[{"issue_id":"k-260","depends_on_id":"k-259","type":"parent-child","created_at":"2025-10-27T16:46:55.739438-05:00","created_by":"cscheid"}]} -{"id":"k-261","title":"Phase 2: Update validate-yaml to use ValidationDiagnostic","description":"Switch validate-yaml binary to use ValidationDiagnostic instead of error_conversion.\n\n**Plan**: claude-notes/plans/2025-10-27-k-259-validation-error-architecture-redesign-v2.md (Phase 2)\n\n**Tasks**:\n1. Import ValidationDiagnostic from quarto-yaml-validation\n2. Update error handling in main.rs to use ValidationDiagnostic\n3. Remove error_conversion.rs module\n4. Move error code inference to ValidationDiagnostic\n5. Test both JSON and text output modes\n\n**Expected**: JSON has structured paths, filename-based source ranges\n\n**Estimate**: 1-2 hours\n**Depends on**: Phase 1 (k-260)","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-27T16:46:56.721787-05:00","updated_at":"2025-10-27T17:32:26.093957-05:00","closed_at":"2025-10-27T17:32:26.093957-05:00","dependencies":[{"issue_id":"k-261","depends_on_id":"k-259","type":"parent-child","created_at":"2025-10-27T16:46:56.72309-05:00","created_by":"cscheid"},{"issue_id":"k-261","depends_on_id":"k-260","type":"blocks","created_at":"2025-10-27T16:47:06.657756-05:00","created_by":"cscheid"},{"issue_id":"k-261","depends_on_id":"k-263","type":"blocks","created_at":"2025-10-27T17:10:35.499324-05:00","created_by":"cscheid"}]} -{"id":"k-262","title":"Phase 3: Testing and documentation for ValidationDiagnostic","description":"Add comprehensive tests and documentation for new error architecture.\n\n**Plan**: claude-notes/plans/2025-10-27-k-259-validation-error-architecture-redesign-v2.md (Phase 3)\n\n**Tasks**:\n1. Add integration tests for JSON structure (instance_path, schema_path, source_range)\n2. Add integration tests for text output (ariadne visual display)\n3. Document JSON schema for downstream consumers\n4. Add usage examples to documentation\n5. Optional: Create TypeScript type definitions for JSON output\n\n**Success criteria**: \n- JSON output has structured arrays for paths\n- JSON has filename + full source ranges\n- Text output uses ariadne box-drawing\n- All tests pass\n\n**Estimate**: 2-3 hours\n**Depends on**: Phase 2 (k-261)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T16:46:57.559367-05:00","updated_at":"2025-10-27T18:47:22.612432-05:00","closed_at":"2025-10-27T18:47:22.612432-05:00","dependencies":[{"issue_id":"k-262","depends_on_id":"k-259","type":"parent-child","created_at":"2025-10-27T16:46:57.561059-05:00","created_by":"cscheid"},{"issue_id":"k-262","depends_on_id":"k-261","type":"blocks","created_at":"2025-10-27T16:47:07.339541-05:00","created_by":"cscheid"}]} -{"id":"k-263","title":"Add structured ValidationErrorKind enum to replace string parsing","description":"Replace string-based error messages with structured ValidationErrorKind enum.\n\n**Problem**: Current code parses error message strings to infer error codes and types. This is fragile and not machine-readable.\n\n**Solution**: Add ValidationErrorKind enum with variants like:\n- TypeMismatch { expected, got }\n- MissingRequiredProperty { property }\n- InvalidEnumValue { value, allowed }\n- etc.\n\n**Changes**:\n1. Create ValidationErrorKind enum in error.rs\n2. Update ValidationError to have 'kind' field\n3. Update validator.rs to create structured errors\n4. Update ValidationDiagnostic to use kind instead of parsing\n5. Add message() method to format human-readable text from kind\n\n**Benefits**:\n- No string parsing for error codes\n- Type-safe error handling\n- Better JSON output with structured data\n- Extensible for future error types\n\n**Estimate**: 3-4 hours (touches many validation sites)\n**Blocks**: k-261 (Phase 2)","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-27T17:10:32.279643-05:00","updated_at":"2025-10-27T17:18:56.921501-05:00","closed_at":"2025-10-27T17:18:56.921501-05:00","dependencies":[{"issue_id":"k-263","depends_on_id":"k-259","type":"parent-child","created_at":"2025-10-27T17:10:32.284202-05:00","created_by":"cscheid"}]} -{"id":"k-264","title":"Make ValidationDiagnostic JSON output machine-readable by serializing ValidationErrorKind directly","description":"Store ValidationErrorKind structurally in ValidationDiagnostic and serialize it to JSON instead of converting to strings early.\n\n**Plan**: claude-notes/plans/2025-10-27-machine-readable-validation-errors.md\n\n**Summary**: Currently ValidationDiagnostic converts ValidationErrorKind to strings at construction time, losing structured data. JSON consumers must parse strings instead of accessing typed fields.\n\n**Solution**: Add Serialize/Deserialize to ValidationErrorKind, store it in ValidationDiagnostic, serialize directly to JSON. Generate message/hints lazily only when needed for text output.\n\n**Estimate**: 2-3 hours","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-27T17:48:38.257347-05:00","updated_at":"2025-10-27T17:53:08.602927-05:00","closed_at":"2025-10-27T17:53:08.602927-05:00"} -{"id":"k-265","title":"Implement Pandoc AST to ANSI terminal writer","description":"Implement a complete Pandoc AST to ANSI terminal writer using crossterm for styling. This will enable rich formatted console output for diagnostic messages and other terminal content.\n\n**Design**: claude-notes/designs/pandoc-ast-to-ansi-writer.md\n\n**Approach**: Option B (Full writer with block support)\n- Use crossterm for terminal styling\n- Follow existing writer pattern in quarto-markdown-pandoc/src/writers/\n- Implement incrementally: inlines first, then blocks\n\n**Architecture**:\n- Location: quarto-markdown-pandoc/src/writers/ansi.rs\n- Pattern: AnsiWriter\u003cW: Write\u003e struct with recursive traversal\n- Config: Colors, width, indent settings\n\n**Integration**:\n- Complement ariadne (source context) with formatted content rendering\n- Use in DiagnosticMessage for rich message content\n- Reusable for debug output, help text, console messages","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-27T19:18:43.258418-05:00","updated_at":"2025-10-28T12:41:33.456561-05:00","closed_at":"2025-10-28T12:41:33.456561-05:00"} -{"id":"k-266","title":"Implement inline element rendering for ANSI writer","description":"Implement ANSI rendering for all Pandoc inline elements using crossterm.\n\n**Scope**: All inline types from src/pandoc/inline.rs\n\n**Minimal implementation for**:\n- Str, Space, SoftBreak, LineBreak (plain text)\n- Emph (italic via crossterm)\n- Strong (bold via crossterm)\n- Code (styled background/foreground)\n- Link (underline + cyan)\n- Math (yellow text)\n- Strikeout, Underline, Superscript, Subscript\n- SmallCaps, Quoted\n- Span (with attribute handling)\n\n**Defer complex rendering**:\n- Cite (render as plain text for now)\n- Note (render as superscript marker for now)\n- Image (render as [Image: alt text] for now)\n- RawInline (pass through or skip)\n\n**Testing**:\n- Unit tests for each inline type\n- Snapshot tests with ANSI escape codes\n- Test nested inlines (e.g., **bold with *italic* inside**)\n\n**Estimate**: 4-5 hours","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T19:18:53.377275-05:00","updated_at":"2025-10-28T12:41:10.099815-05:00","closed_at":"2025-10-28T12:41:10.099815-05:00","dependencies":[{"issue_id":"k-266","depends_on_id":"k-265","type":"parent-child","created_at":"2025-10-27T19:18:53.379559-05:00","created_by":"cscheid"}]} -{"id":"k-267","title":"Implement block element rendering for ANSI writer","description":"Implement ANSI rendering for Pandoc block elements using crossterm.\n\n**Phase 1 - Minimal blocks (initial implementation)**:\n- Plain: Render inlines directly\n- Para: Render inlines with newline after\n- **Panic on all other blocks** with helpful message\n\n**Phase 2 - Core blocks** (expand incrementally):\n- Header (levels 1-6 with styling)\n- BulletList (with indentation)\n- OrderedList (with numbering)\n- CodeBlock (with syntax highlighting via syntect?)\n- BlockQuote (with left border/indent)\n- HorizontalRule (line across terminal)\n\n**Phase 3 - Complex blocks** (future):\n- DefinitionList\n- Table (ASCII table layout)\n- Figure (with caption)\n- Div (with class/id styling)\n- LineBlock (preserve line breaks)\n\n**Implementation strategy**:\n- Start with Plain/Para only (panic on others)\n- Add blocks incrementally based on need\n- Each block added in separate commit\n- Update tests as blocks are implemented\n\n**Testing**:\n- Test Plain and Para thoroughly first\n- Verify panic messages are helpful\n- Add tests as each block type is implemented\n\n**Estimate**: \n- Phase 1: 2 hours\n- Phase 2: 8-10 hours\n- Phase 3: 8-12 hours (defer)","notes":"Implementation plan: claude-notes/plans/2025-10-27-ansi-writer-block-types.md\n\nPhase 2 in progress: Implementing Paragraph, consecutive Plain handling, Div with colors, BulletList with depth cycling, and OrderedList with calculated indentation.\n\nUsing context pattern from qmd.rs with DivContext for line-by-line color styling.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T19:19:04.115095-05:00","updated_at":"2025-10-28T12:41:16.899192-05:00","closed_at":"2025-10-28T12:41:16.899192-05:00","dependencies":[{"issue_id":"k-267","depends_on_id":"k-265","type":"parent-child","created_at":"2025-10-27T19:19:04.116988-05:00","created_by":"cscheid"},{"issue_id":"k-267","depends_on_id":"k-266","type":"blocks","created_at":"2025-10-27T19:19:04.117717-05:00","created_by":"cscheid"}]} -{"id":"k-268","title":"Parser fails to recognize horizontal rules (---) in qmd files","description":"The qmd parser is not correctly parsing horizontal rules (---). They appear to be getting confused with YAML metadata delimiters. When parsing a file with --- horizontal rules, they are completely omitted from the AST.\n\nTest case in test-fixtures/horizontal-rule.qmd shows the issue - only 2 paragraphs are parsed instead of 3 paragraphs with 2 horizontal rules between them.\n\nThis needs investigation in the tree-sitter grammar or block parser logic.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-28T10:30:49.77105-05:00","updated_at":"2025-10-28T11:15:27.884278-05:00","closed_at":"2025-10-28T11:15:27.884278-05:00"} -{"id":"k-269","title":"Implement smart terminal color detection using OSC 10/11 queries","description":"Terminals support querying their current foreground/background colors using OSC 10/11 escape sequences. This could enable smart color selection in the ANSI writer.\n\nImplementation would:\n- Query terminal colors using \\x1b]10;?\\x1b\\ and \\x1b]11;?\\x1b\\\n- Parse RGB response format (rgb:RRRR/GGGG/BBBB)\n- Detect dark vs light backgrounds\n- Adapt color palette for better contrast\n- Fall back to current defaults if query fails\n\nChallenges:\n- Requires raw terminal mode\n- Not available in pipes/redirects\n- Adds complexity and latency\n- Should be behind feature flag\n\nSee claude-notes/terminal-color-querying.md for detailed research and implementation notes.","status":"open","priority":4,"issue_type":"feature","created_at":"2025-10-28T10:52:38.687896-05:00","updated_at":"2025-11-23T14:12:12.904383-06:00"} -{"id":"k-27","title":"Migrate quarto-markdown-pandoc to use quarto-source-map","description":"Replace pandoc::location types with quarto-source-map throughout quarto-markdown-pandoc. Integrate quarto-yaml for YAML parsing with Substring mappings. Enable proper source location tracking for all errors. See docs/for-claude/quarto-source-map-integration-plan.md","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-18T17:16:55.284427-05:00","updated_at":"2025-10-20T15:01:48.597932-05:00","closed_at":"2025-10-20T15:01:48.597932-05:00","dependencies":[{"issue_id":"k-27","depends_on_id":"k-26","type":"blocks","created_at":"2025-10-18T13:52:28.277471-05:00","created_by":"import"}]} -{"id":"k-270","title":"Phase E: Retire old ErrorCollector implementations","description":"Remove TextErrorCollector and JsonErrorCollector implementations now that DiagnosticCollector has replaced them.\n\n**Files to modify**:\n- crates/quarto-markdown-pandoc/src/utils/error_collector.rs\n - Remove TextErrorCollector struct and impl\n - Remove JsonErrorCollector struct and impl\n - Keep ErrorCollector trait (used by DiagnosticCollector)\n - Move tests to diagnostic_collector.rs if needed\n\n**Verification**:\n- Run cargo test to ensure no code depends on old collectors\n- Only DiagnosticCollector should be used in production code\n- Old collectors exist only for their own tests currently","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-28T12:46:03.678537-05:00","updated_at":"2025-10-28T12:47:48.299992-05:00","closed_at":"2025-10-28T12:47:48.299992-05:00"} -{"id":"k-271","title":"Add HTML comment support to block parser (tree-sitter-markdown)","description":"Implement HTML_COMMENT external token in tree-sitter-markdown scanner to handle comments that span block boundaries. This is the critical first step - comments starting inline can span across what would be block markers (lists, headings, etc.) and must be consumed atomically. Reference: claude-notes/plans/2025-10-28-html-comment-REVISED.md","notes":"Block parser HTML comment support implemented and working! Cross-boundary test (test 36) successfully prevents list recognition inside comments. Block parser now consumes HTML comments atomically. Inline parser still needed for proper tokenization.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-28T16:28:16.360174-05:00","updated_at":"2025-10-28T16:32:43.820599-05:00","closed_at":"2025-10-28T16:32:43.820599-05:00"} -{"id":"k-272","title":"Add HTML comment support to inline parser (tree-sitter-markdown-inline)","description":"Implement HTML_COMMENT external token in tree-sitter-markdown-inline scanner. Handles simple inline comments that don't span blocks. Depends on block parser being done first. Reference: claude-notes/plans/2025-10-28-html-comment-REVISED.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-28T16:28:17.503552-05:00","updated_at":"2025-10-28T16:38:04.698925-05:00","closed_at":"2025-10-28T16:38:04.698925-05:00","dependencies":[{"issue_id":"k-272","depends_on_id":"k-271","type":"blocks","created_at":"2025-10-28T16:28:30.31504-05:00","created_by":"cscheid"}]} -{"id":"k-273","title":"Add HTML comment AST conversion in quarto-markdown-pandoc","description":"Add handlers to convert html_comment nodes to RawInline/RawBlock in Pandoc AST. Convert to format 'quarto-html-comment'. Requires both parsers to be complete. Reference: claude-notes/plans/2025-10-28-html-comment-REVISED.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-28T16:28:18.290599-05:00","updated_at":"2025-10-28T16:40:59.039113-05:00","closed_at":"2025-10-28T16:40:59.039113-05:00","dependencies":[{"issue_id":"k-273","depends_on_id":"k-271","type":"blocks","created_at":"2025-10-28T16:28:31.942545-05:00","created_by":"cscheid"},{"issue_id":"k-273","depends_on_id":"k-272","type":"blocks","created_at":"2025-10-28T16:28:31.96237-05:00","created_by":"cscheid"}]} -{"id":"k-274","title":"Refactor tree-sitter grammar processing for new node structure","description":"Major refactoring to handle completely redesigned tree-sitter grammar. All node names changed and grammar provides much more fine-grained syntax tree. Need to rewrite native_visitor processor one node at a time. See plan: claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md","status":"closed","priority":0,"issue_type":"epic","created_at":"2025-10-31T09:36:55.340098-05:00","updated_at":"2025-11-02T19:43:36.133317-06:00","closed_at":"2025-11-02T19:43:36.133317-06:00"} -{"id":"k-275","title":"Implement pandoc_str node handler","description":"First node to implement in refactoring. Handler for basic text strings. Test with simple 'hello' document. Should convert to Pandoc Str inline.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T09:37:34.058615-05:00","updated_at":"2025-10-31T09:48:36.628598-05:00","closed_at":"2025-10-31T09:48:36.628598-05:00","dependencies":[{"issue_id":"k-275","depends_on_id":"k-274","type":"parent-child","created_at":"2025-10-31T09:37:34.060102-05:00","created_by":"cscheid"}]} -{"id":"k-276","title":"Implement pandoc_emph node handler","description":"Implement handler for pandoc_emph (emphasis with * or _) in tree-sitter refactoring.\n\nTest-driven approach:\n1. Write test for basic emphasis: *hello*\n2. Verify test fails\n3. Implement handler in treesitter.rs\n4. Verify test passes\n5. Test with verbose mode (no MISSING warnings)\n\nComplexity: Medium - has children (recursive inline content)\nEstimate: 30-45 minutes\n\nSee: claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md (Phase 2)","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T10:57:12.683711-05:00","updated_at":"2025-10-31T15:18:54.857654-05:00","closed_at":"2025-10-31T15:18:54.857654-05:00","dependencies":[{"issue_id":"k-276","depends_on_id":"k-274","type":"parent-child","created_at":"2025-10-31T10:57:12.685965-05:00","created_by":"c2"}]} -{"id":"k-277","title":"Implement pandoc_strong node handler","description":"Implement handler for pandoc_strong (strong emphasis **text** or __text__). Use same pattern as pandoc_emph with delimiter space injection. See claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md and 2025-10-31-fix-emphasis-space-nodes.md for reference.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T12:22:18.614636-05:00","updated_at":"2025-10-31T12:24:44.809925-05:00","closed_at":"2025-10-31T12:24:44.809925-05:00","dependencies":[{"issue_id":"k-277","depends_on_id":"k-276","type":"blocks","created_at":"2025-10-31T12:22:18.617278-05:00","created_by":"c2"}]} -{"id":"k-278","title":"Implement pandoc_strikeout node handler","description":"Implement handler for pandoc_strikeout (strikeout ~~text~~). Use same pattern as pandoc_emph with delimiter space injection. See claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md and 2025-10-31-fix-emphasis-space-nodes.md for reference.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T12:22:20.386978-05:00","updated_at":"2025-10-31T12:26:10.708652-05:00","closed_at":"2025-10-31T12:26:10.708652-05:00","dependencies":[{"issue_id":"k-278","depends_on_id":"k-276","type":"blocks","created_at":"2025-10-31T12:22:20.388872-05:00","created_by":"c2"}]} -{"id":"k-279","title":"Implement pandoc_superscript node handler","description":"Implement handler for pandoc_superscript (superscript ^text^). Use same pattern as pandoc_emph with delimiter space injection. See claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md and 2025-10-31-fix-emphasis-space-nodes.md for reference.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T12:22:22.343854-05:00","updated_at":"2025-10-31T12:26:10.724745-05:00","closed_at":"2025-10-31T12:26:10.724745-05:00","dependencies":[{"issue_id":"k-279","depends_on_id":"k-276","type":"blocks","created_at":"2025-10-31T12:22:22.345596-05:00","created_by":"c2"}]} -{"id":"k-28","title":"Phase 1: Replace quarto-yaml::SourceInfo with quarto-source-map::SourceInfo","description":"Update all structs, function signatures in quarto-yaml to use quarto-source-map::SourceInfo. Remove old SourceInfo type. Update all tests. This makes quarto-yaml use the unified source tracking system.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T17:17:02.001689-05:00","updated_at":"2025-10-18T17:22:04.031733-05:00","closed_at":"2025-10-18T17:22:04.031733-05:00","dependencies":[{"issue_id":"k-28","depends_on_id":"k-27","type":"blocks","created_at":"2025-10-18T17:17:02.003204-05:00","created_by":"cscheid"}]} -{"id":"k-280","title":"Implement pandoc_subscript node handler","description":"Implement handler for pandoc_subscript (subscript ~text~). Use same pattern as pandoc_emph with delimiter space injection. See claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md and 2025-10-31-fix-emphasis-space-nodes.md for reference.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T12:22:24.211415-05:00","updated_at":"2025-10-31T12:26:10.740469-05:00","closed_at":"2025-10-31T12:26:10.740469-05:00","dependencies":[{"issue_id":"k-280","depends_on_id":"k-276","type":"blocks","created_at":"2025-10-31T12:22:24.214055-05:00","created_by":"c2"}]} -{"id":"k-281","title":"Implement pandoc_code_span node handler","description":"Implement handler for pandoc_code_span (inline code with backticks) in tree-sitter refactoring.\n\nTest-driven approach:\n1. Write tests for basic code spans: `code`\n2. Verify tests fail\n3. Implement handler in treesitter.rs\n4. Verify tests pass\n5. Test with verbose mode (no MISSING warnings)\n\nComplexity: Medium - has content extraction and optional attributes\nEstimate: 2-3 hours\n\nSee: claude-notes/plans/2025-10-31-implement-pandoc-code-span.md (Phase 2)","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T13:02:42.782274-05:00","updated_at":"2025-10-31T13:09:46.765-05:00","closed_at":"2025-10-31T13:09:46.765-05:00","dependencies":[{"issue_id":"k-281","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-10-31T13:02:42.784605-05:00","created_by":"c2"}]} -{"id":"k-282","title":"Fix backslash escape handling in pandoc_str","description":"Backslash escapes are currently captured inside pandoc_str nodes but not processed correctly.\n\n**Current behavior**:\nInput: hello\\*world\nOur output: Str \"hello\\\\*world\" (backslash preserved)\nPandoc output: Str \"hello*world\" (backslash consumed)\n\n**Root cause**:\nThe tree-sitter grammar captures backslashes as part of pandoc_str (see regex with \\\\. at tree-sitter-markdown/grammar.js:531). They need post-processing to convert escape sequences to literal characters.\n\n**Investigation needed**:\n- Determine if backslashes should be in separate backslash_escape nodes or handled within pandoc_str\n- Check if the grammar needs changes or just the handler logic\n- Add comprehensive tests for all escapable characters\n\n**Context**: Discovered during tree-sitter refactoring (k-274). See also: claude-notes/plans/2025-10-31-tree-sitter-qmd-cleanup-completion.md which mentions this as future work.\n\n**Estimate**: 2-3 hours (investigation + fix + tests)","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-31T15:22:28.124505-05:00","updated_at":"2025-10-31T16:26:24.646709-05:00","closed_at":"2025-10-31T16:26:24.646709-05:00","dependencies":[{"issue_id":"k-282","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-10-31T15:22:28.12671-05:00","created_by":"c2"}]} -{"id":"k-283","title":"Implement atx_heading node handler","description":"Implement handler for atx_heading (# Heading syntax) in tree-sitter refactoring.\n\n**Current behavior**:\nInput: # Heading\nError: [TOP-LEVEL MISSING NODE] Warning: Unhandled node kind: atx_heading\nPanic: Expected Block or Section, got IntermediateUnknown\n\n**Node structure** (from verbose output):\n- atx_heading (parent)\n - atx_h1_marker (# symbol)\n - pandoc_str (heading text)\n - Optional: attribute_specifier ({#id .class})\n\n**Handler needs to**:\n1. Extract heading level from marker (atx_h1_marker through atx_h6_marker)\n2. Process inline content (children between marker and end)\n3. Handle optional attribute specifier\n4. Return Pandoc Header block\n\n**Test-driven approach**:\n1. Write tests for all 6 heading levels (# through ######)\n2. Test with attributes: # Heading {#id}\n3. Test with inline formatting: # Heading with *emphasis*\n4. Verify tests fail\n5. Implement handler in treesitter.rs\n6. Verify tests pass\n\n**Complexity**: Medium - needs level extraction, inline content processing, attribute handling\n**Estimate**: 1-2 hours\n\n**Phase**: Phase 3 (Structure and Headings)\nSee: claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T15:22:40.410877-05:00","updated_at":"2025-10-31T15:27:18.613533-05:00","closed_at":"2025-10-31T15:27:18.613533-05:00","dependencies":[{"issue_id":"k-283","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-10-31T15:22:40.413555-05:00","created_by":"c2"}]} -{"id":"k-284","title":"Implement pandoc_math node handler","description":"Implement handler for pandoc_math (inline math with $...$) in tree-sitter refactoring.\n\n**Current behavior**:\nInput: $x + y$\nError: [TOP-LEVEL MISSING NODE] Warning: Unhandled node kind: pandoc_math\n\n**Node structure** (from verbose output):\n- pandoc_math (parent)\n - $ (opening delimiter)\n - (content - anonymous regex match)\n - $ (closing delimiter)\n\n**Pandoc expects**:\nMath InlineMath \"x + y\"\n\n**Handler needs to**:\n1. Extract content from middle child (between delimiters)\n2. Create Math inline with InlineMath type\n3. Return Pandoc Math inline\n\n**Test-driven approach**:\n1. Write tests for basic inline math: $x$, $x + y$\n2. Test with complex expressions: $\\frac{a}{b}$\n3. Verify tests fail\n4. Implement handler in treesitter.rs\n5. Verify tests pass\n\n**Complexity**: Medium - similar to code_span but simpler (no attributes)\n**Estimate**: 45-60 minutes\n\n**Phase**: Phase 4 (Links and Math)\nSee: claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T15:29:53.947253-05:00","updated_at":"2025-10-31T15:34:08.012522-05:00","closed_at":"2025-10-31T15:34:08.012522-05:00","dependencies":[{"issue_id":"k-284","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-10-31T15:29:53.949331-05:00","created_by":"c2"}]} -{"id":"k-285","title":"Implement pandoc_display_math node handler","description":"Implement handler for pandoc_display_math (display math with $$...$$) in tree-sitter refactoring.\n\n**Current behavior**:\nInput: $$x + y$$\nError: [TOP-LEVEL MISSING NODE] Warning: Unhandled node kind: pandoc_display_math\n\n**Node structure** (from verbose output):\n- pandoc_display_math (parent)\n - $$ (opening delimiter)\n - (content - anonymous regex match)\n - $$ (closing delimiter)\n\n**Pandoc expects**:\nMath DisplayMath \"x + y\"\n\n**Handler needs to**:\n1. Extract content from middle child (between delimiters)\n2. Create Math inline with DisplayMath type\n3. Return Pandoc Math inline\n\n**Test-driven approach**:\n1. Write tests for basic display math: $$x$$, $$x + y$$\n2. Test with complex expressions: $$\\frac{a}{b}$$\n3. Verify tests fail\n4. Implement handler in treesitter.rs\n5. Verify tests pass\n\n**Complexity**: Medium - nearly identical to pandoc_math\n**Estimate**: 30-45 minutes\n\n**Phase**: Phase 4 (Links and Math)\nSee: claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T15:30:04.83614-05:00","updated_at":"2025-10-31T15:34:25.41864-05:00","closed_at":"2025-10-31T15:34:25.41864-05:00","dependencies":[{"issue_id":"k-285","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-10-31T15:30:04.837439-05:00","created_by":"c2"}]} -{"id":"k-286","title":"Implement attribute processing for code_span nodes","description":"Add support for processing attribute nodes (id, classes, key-value pairs) in tree-sitter refactoring.\n\n**Current behavior**:\nInput: `code`{.lang}\nOutput: Code ( \"\" , [] , [] ) \"code\"\nExpected: Code ( \"\" , [ \"lang\" ] , [] ) \"code\"\n\n**Problem**: Attribute-related nodes are not handled in native_visitor:\n- attribute_specifier, attribute_id, attribute_class\n- key_value_specifier, key_value_key, key_value_value\n- Delimiter nodes: {, }, =\n\n**Solution**: Add handlers for all attribute nodes to convert them to intermediate types that existing processors expect.\n\n**Phases**:\n1. Add leaf node handlers (attribute_id, attribute_class, key_value nodes)\n2. Add key_value_specifier handler\n3. Add commonmark_specifier handler\n4. Add attribute_specifier handler\n5. Add comprehensive tests\n\n**Estimate**: 2 hours\n\n**Plan**: claude-notes/plans/2025-10-31-attribute-processing-plan.md","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T16:00:10.572098-05:00","updated_at":"2025-10-31T16:06:03.468672-05:00","closed_at":"2025-10-31T16:06:03.468672-05:00","dependencies":[{"issue_id":"k-286","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-10-31T16:00:10.575565-05:00","created_by":"c2"}]} -{"id":"k-287","title":"Implement pandoc_span and pandoc_image node handlers","description":"Implement handlers for spans, links, and images in tree-sitter refactoring.\n\n**Three node types to handle**:\n- pandoc_span with target → Link\n- pandoc_span without target → Span\n- pandoc_image → Image\n\n**QMD Design Difference**: [text] produces Span with empty attributes (differs from Pandoc which outputs literal brackets).\n\n**Phases**:\n1. Add leaf node handlers (url, title, delimiters)\n2. Add target handler\n3. Add content handler\n4. Add pandoc_span handler\n5. Add pandoc_image handler\n6. Add comprehensive tests\n\n**Plan**: claude-notes/plans/2025-10-31-spans-links-images.md\n\n**Estimate**: 2.5-3 hours\n\n**Note**: Figure block conversion for standalone images is deferred to future work.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T16:48:59.425928-05:00","updated_at":"2025-10-31T16:56:50.024368-05:00","closed_at":"2025-10-31T16:56:50.024368-05:00","dependencies":[{"issue_id":"k-287","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-10-31T16:48:59.430559-05:00","created_by":"c2"}]} -{"id":"k-288","title":"Implement pandoc_single_quote and pandoc_double_quote handlers","description":"Add support for quoted text (single and double quotes). See plan at claude-notes/plans/2025-10-31-quoted-nodes.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T17:27:44.235081-05:00","updated_at":"2025-10-31T17:31:33.507566-05:00","closed_at":"2025-10-31T17:31:33.507566-05:00"} -{"id":"k-289","title":"Refactor complex match arms in treesitter.rs to helper files","description":"Extract pandoc_span, pandoc_image, pandoc_single_quote, pandoc_double_quote, target, and content handlers into span_link_helpers.rs and quote_helpers.rs. See plan at claude-notes/plans/2025-10-31-refactor-helpers.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T17:40:20.839551-05:00","updated_at":"2025-10-31T17:45:27.917951-05:00","closed_at":"2025-10-31T17:45:27.917951-05:00"} -{"id":"k-29","title":"Phase 1: Add parent source tracking to YamlBuilder","description":"Add parent_source_info: Option\u003cSourceInfo\u003e field to YamlBuilder. Modify make_source_info() to create Substring mappings when parent exists. This enables parsing YAML extracted from .qmd files.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T17:17:08.484045-05:00","updated_at":"2025-10-18T17:38:35.985808-05:00","closed_at":"2025-10-18T17:38:35.985808-05:00","dependencies":[{"issue_id":"k-29","depends_on_id":"k-27","type":"blocks","created_at":"2025-10-18T17:17:08.485893-05:00","created_by":"cscheid"}]} -{"id":"k-290","title":"Implement pandoc_strikeout node handler","description":"Implement handler for pandoc_strikeout (strikethrough with ~~text~~) in tree-sitter refactoring. Similar pattern to emph/strong. Includes delimiter handling and content processing. Estimate: 45-60 minutes.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T18:21:41.619424-05:00","updated_at":"2025-10-31T18:25:35.363177-05:00","closed_at":"2025-10-31T18:25:35.363177-05:00"} -{"id":"k-291","title":"Implement editorial mark node handlers (insert, delete, highlight, edit_comment)","description":"Implement handlers for editorial marks in tree-sitter refactoring: pandoc_insert, pandoc_delete, pandoc_highlight, pandoc_edit_comment. These are used for tracking changes and comments. Similar patterns with delimiter + content. Estimate: 2-3 hours.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T18:21:48.712666-05:00","updated_at":"2025-10-31T18:43:51.66138-05:00","closed_at":"2025-10-31T18:43:51.66138-05:00"} -{"id":"k-292","title":"Implement citation node handler","description":"","notes":"See claude-notes/citation-grammar-limitation.md for detailed explanation of how bracketed citations are handled. The grammar parses [@cite] as a span containing a citation, so we unwrap and transform the citation mode in process_pandoc_span().","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T18:51:02.067565-05:00","updated_at":"2025-10-31T19:27:43.842428-05:00","closed_at":"2025-10-31T19:18:04.049524-05:00","dependencies":[{"issue_id":"k-292","depends_on_id":"k-274","type":"parent-child","created_at":"2025-10-31T18:51:02.069665-05:00","created_by":"c2"}]} -{"id":"k-293","title":"Implement inline_note node handler","description":"Implement handler for inline_note nodes (^[note text]) in tree-sitter refactoring. Current behavior: node is parsed but not handled, causing MISSING warnings. Estimate: 2-3 hours.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T18:51:13.479057-05:00","updated_at":"2025-10-31T19:33:23.693705-05:00","closed_at":"2025-10-31T19:33:23.693705-05:00","dependencies":[{"issue_id":"k-293","depends_on_id":"k-274","type":"parent-child","created_at":"2025-10-31T18:51:13.480558-05:00","created_by":"c2"}]} -{"id":"k-294","title":"Implement note_reference node handler","description":"Implement handler for note_reference nodes ([^note_id]) in tree-sitter refactoring. Current behavior: causes parse error. Needs grammar investigation and handler implementation. Estimate: 2-3 hours.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T18:51:23.953311-05:00","updated_at":"2025-10-31T19:55:15.367334-05:00","closed_at":"2025-10-31T19:55:15.367334-05:00","dependencies":[{"issue_id":"k-294","depends_on_id":"k-274","type":"parent-child","created_at":"2025-10-31T18:51:23.955036-05:00","created_by":"c2"}]} -{"id":"k-295","title":"Implement shortcode node handler","description":"Implement handler for shortcode nodes ({{\u003c shortcode \u003e}}) in tree-sitter refactoring. Current behavior: node is parsed but not handled, causing MISSING warnings. Needs to handle shortcode_name, parameters, and delimiters. Estimate: 3-4 hours.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T18:51:26.006737-05:00","updated_at":"2025-10-31T19:01:04.973064-05:00","closed_at":"2025-10-31T19:01:04.973064-05:00","dependencies":[{"issue_id":"k-295","depends_on_id":"k-274","type":"parent-child","created_at":"2025-10-31T18:51:26.008477-05:00","created_by":"c2"}]} -{"id":"k-296","title":"Fix citation whitespace handling - leading space should be Space node, not in Str content","description":"Citations currently include leading whitespace in their content Str instead of creating a separate Space node.\n\n**Current behavior**:\n- 'Hi @cite' produces: [Str \"Hi\", Cite [...] [Str \" @cite\"]]\n Note the leading space in \" @cite\"\n- 'Hi@cite' produces: [Str \"Hi\", Cite [...] [Str \"@cite\"]]\n\n**Expected behavior**:\n- 'Hi @cite' should produce: [Str \"Hi\", Space, Cite [...] [Str \"@cite\"]]\n- 'Hi@cite' should produce: [Str \"Hi\", Cite [...] [Str \"@cite\"]]\n\n**Root cause**:\nThe citation handler in treesitter.rs uses node_text() which includes leading whitespace from the tree-sitter node. Similar to inline_note_reference, citations need to detect leading whitespace and inject a Space node.\n\n**Location**: \n- Handler: crates/quarto-markdown-pandoc/src/pandoc/treesitter.rs:727-730\n- Helper: crates/quarto-markdown-pandoc/src/pandoc/treesitter_utils/citation.rs\n\n**Solution approach**:\nSimilar to the inline_note_reference fix, check if the node text starts with whitespace and return IntermediateInlines with [Space, Cite] instead of just IntermediateInline(Cite).\n\n**Related**: Same issue exists in inline_note_reference (currently being fixed).","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-10-31T20:43:05.55275-05:00","updated_at":"2025-10-31T20:48:55.67822-05:00","closed_at":"2025-10-31T20:48:55.67822-05:00"} -{"id":"k-297","title":"Implement pandoc_block_quote handler","description":"Block quotes (\u003e quote) currently crash with 'Expected Block or Section, got IntermediateUnknown'.\n\n**Status**: Handler commented out at line 1098\n**Helper**: process_block_quote exists in treesitter_utils/block_quote.rs\n**Impact**: CRASHES on any document with block quotes\n\n**Implementation**:\n1. Uncomment line 1098 in treesitter.rs\n2. Write failing test for basic block quote\n3. Verify helper works with new grammar\n4. Add edge case tests (empty, nested, multi-line)\n\n**Test cases needed**:\n- Basic single-line quote\n- Multi-line quote\n- Nested quotes\n- Quotes containing other blocks (paragraphs, lists)\n- Empty quotes\n\n**Priority**: CRITICAL - Phase 1, no dependencies","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T21:13:00.705623-05:00","updated_at":"2025-10-31T21:14:33.743053-05:00","closed_at":"2025-10-31T21:14:33.743053-05:00","dependencies":[{"issue_id":"k-297","depends_on_id":"k-274","type":"parent-child","created_at":"2025-10-31T21:13:00.708027-05:00","created_by":"cscheid"}]} -{"id":"k-298","title":"Implement pandoc_horizontal_rule handler","description":"Horizontal rules (---) currently crash.\n\n**Status**: Handler commented out at line 1101 (as 'thematic_break')\n**Helper**: process_thematic_break exists\n**Impact**: CRASHES on horizontal rules\n\n**Implementation**:\n1. Uncomment line 1101 in treesitter.rs\n2. Write tests (trivial - no children)\n\n**Test cases needed**:\n- Basic horizontal rule\n- Multiple rules in document\n- Rules between paragraphs\n\n**Priority**: CRITICAL - Phase 1, very simple","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T21:13:02.084294-05:00","updated_at":"2025-10-31T21:26:25.684869-05:00","closed_at":"2025-10-31T21:26:25.684869-05:00","dependencies":[{"issue_id":"k-298","depends_on_id":"k-274","type":"parent-child","created_at":"2025-10-31T21:13:02.086082-05:00","created_by":"cscheid"}]} -{"id":"k-299","title":"Implement pandoc_code_block handler","description":"Fenced code blocks (```code```) currently crash.\n\n**Status**: Handler commented out at line 943 (as 'fenced_code_block')\n**Helper**: process_fenced_code_block exists\n**Impact**: CRASHES on any fenced code block\n\n**Note**: Only backtick fences supported (no tildes, no indented code blocks)\n\n**Implementation**:\n1. Uncomment line 943 in treesitter.rs\n2. Write tests for code with/without language\n3. Test attribute handling\n4. Test multi-line code\n\n**Test cases needed**:\n- Code block without language\n- Code block with language\n- Code block with attributes\n- Empty code block\n- Multi-line code\n- Code with special characters\n\n**Priority**: CRITICAL - Phase 1","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T21:13:03.487717-05:00","updated_at":"2025-10-31T21:32:27.301036-05:00","closed_at":"2025-10-31T21:32:27.301036-05:00","dependencies":[{"issue_id":"k-299","depends_on_id":"k-274","type":"parent-child","created_at":"2025-10-31T21:13:03.489179-05:00","created_by":"cscheid"}]} -{"id":"k-2lz5","title":"Add tests for error types (quarto-csl, quarto-citeproc)","description":"Error handling code in quarto-csl/error.rs and quarto-citeproc/error.rs has 0% coverage. Add tests for error creation, display, and conversion.","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-31T10:02:11.501812-06:00","updated_at":"2025-12-31T10:13:09.415728-06:00","dependencies":[{"issue_id":"k-2lz5","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2025-12-31T10:02:11.502647-06:00","created_by":"daemon"}]} -{"id":"k-2po4","title":"Improve coverage: shortcode.rs","description":"Session baseline: 76.33% line coverage. Target: beat baseline. Focus on shortcode processing functions.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-03T13:42:58.391673-06:00","updated_at":"2026-01-03T13:55:59.90597-06:00","closed_at":"2026-01-03T13:55:59.90597-06:00","dependencies":[{"issue_id":"k-2po4","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-03T13:42:58.392865-06:00","created_by":"daemon"}]} -{"id":"k-2sts","title":"HTML writer incorrectly prefixes all attributes with data-","description":"The pampa HTML writer prefixes ALL key-value attributes with 'data-'. This causes: 1) Standard HTML5 attributes like style, title, dir to become data-style, data-title, data-dir. 2) Existing data-* attributes to be doubled (data-foo -\u003e data-data-foo). 3) ARIA attributes to become data-aria-*. See plan: claude-notes/plans/2025-12-27-html-attr-handling.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-27T13:29:42.542869-06:00","updated_at":"2025-12-27T14:03:00.91133-06:00","closed_at":"2025-12-27T14:03:00.91133-06:00"} -{"id":"k-2tu9","title":"Unify MetaValueWithSourceInfo and ConfigValue","description":"Replace MetaValueWithSourceInfo with ConfigValue throughout the codebase.\n\nCurrently we have two very similar types:\n- MetaValueWithSourceInfo (quarto-pandoc-types) - for document metadata\n- ConfigValue (quarto-config) - for configuration merging\n\nThis duplication causes:\n- Conversion functions between the types\n- Utility functions written twice\n- Growing complexity as codebase expands\n\nThe unification requires:\n1. Refactor ConfigValueKind: add Path/Glob/Expr variants, remove unused interpretation field\n2. Add ConfigMapEntry with key_source tracking (matches MetaMapEntry)\n3. Add InterpretationContext for default interpretation (doc vs project)\n4. Update yaml_to_meta_with_source_info to produce ConfigValue\n5. Migrate all 32 files that reference MetaValueWithSourceInfo\n6. Remove MetaValueWithSourceInfo\n\nKey insight: The current interpretation field is never read outside tests. Using explicit ConfigValueKind variants (Path, Glob, Expr) is cleaner and fixes the bug where !path is treated identically to !str.\n\nThis is a prerequisite for k-ic1o (ConfigValue integration into pipeline).\n\nPlan: claude-notes/plans/2025-12-29-unify-meta-and-config-types.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-29T10:58:54.378421-06:00","updated_at":"2025-12-29T21:55:24.256186-06:00","closed_at":"2025-12-29T21:55:24.256186-06:00","dependencies":[{"issue_id":"k-2tu9","depends_on_id":"k-ic1o","type":"blocks","created_at":"2025-12-29T10:58:54.380843-06:00","created_by":"daemon"}]} -{"id":"k-3","title":"Phase B: Create DiagnosticCollector bridge","description":"Create DiagnosticCollector that implements ErrorCollector trait but uses quarto-error-reporting internally.\n\nFiles to create:\n- crates/quarto-markdown-pandoc/src/utils/diagnostic_collector.rs\n\nFiles to modify:\n- crates/quarto-markdown-pandoc/Cargo.toml (add quarto-error-reporting dep)\n- crates/quarto-markdown-pandoc/src/utils/mod.rs\n\nShould be drop-in replacement for TextErrorCollector/JsonErrorCollector.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T14:41:44.514766-05:00","updated_at":"2025-10-18T15:14:40.405072-05:00","closed_at":"2025-10-18T15:14:40.405072-05:00","dependencies":[{"issue_id":"k-3","depends_on_id":"k-7","type":"blocks","created_at":"2025-10-18T13:52:20.680444-05:00","created_by":"import"},{"issue_id":"k-3","depends_on_id":"k-1","type":"parent-child","created_at":"2025-10-18T14:41:44.516351-05:00","created_by":"cscheid"},{"issue_id":"k-3","depends_on_id":"k-2","type":"blocks","created_at":"2025-10-18T14:41:52.642468-05:00","created_by":"cscheid"}]} -{"id":"k-30","title":"Phase 1: Add parse_with_parent API to quarto-yaml","description":"Add new parse_with_parent(content: \u0026str, parent: SourceInfo) function. Passes parent to YamlBuilder. Creates Substring mappings for all YAML nodes relative to parent.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T17:17:15.191598-05:00","updated_at":"2025-10-18T17:39:34.512581-05:00","closed_at":"2025-10-18T17:39:34.512581-05:00","dependencies":[{"issue_id":"k-30","depends_on_id":"k-27","type":"blocks","created_at":"2025-10-18T17:17:15.193351-05:00","created_by":"cscheid"}]} -{"id":"k-300","title":"Implement pandoc_list and list_item handlers","description":"Lists (bullet and ordered) currently crash.\n\n**Status**: Both handlers commented out at lines 1093-1094\n**Helpers**: process_list and process_list_item exist\n**Impact**: CRASHES on any list (bullet or ordered)\n\n**Complexity**: HIGH - recursive structure, list attributes, tight/loose spacing\n\n**Implementation**:\n1. Uncomment both handlers (lines 1093-1094)\n2. Write tests for bullet lists\n3. Write tests for ordered lists\n4. Test nested lists (recursion)\n5. Test tight vs loose spacing\n6. Test list attributes (start number, etc.)\n\n**Test cases needed**:\n- Simple bullet list\n- Simple ordered list\n- Nested bullet lists\n- Nested ordered lists\n- Mixed nesting\n- Tight lists\n- Loose lists\n- Lists with complex content (paragraphs, code blocks)\n- List start numbers\n\n**Priority**: CRITICAL - Phase 2, recursive structure","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T21:13:04.736166-05:00","updated_at":"2025-10-31T22:01:51.434711-05:00","closed_at":"2025-10-31T22:01:51.434711-05:00","dependencies":[{"issue_id":"k-300","depends_on_id":"k-274","type":"parent-child","created_at":"2025-10-31T21:13:04.737411-05:00","created_by":"cscheid"}]} -{"id":"k-301","title":"Implement pandoc_div handler","description":"Fenced divs (::: {.class}) currently crash.\n\n**Status**: Handler commented out at line 1099 (as 'fenced_div_block')\n**Helper**: process_fenced_div_block exists\n**Impact**: CRASHES on any fenced div\n\n**Implementation**:\n1. Uncomment line 1099 in treesitter.rs\n2. Write tests for divs without attributes\n3. Write tests for divs with attributes\n4. Test nested divs\n5. Test divs with complex content\n\n**Test cases needed**:\n- Basic div without attributes\n- Div with id and classes\n- Div with key-value attributes\n- Nested divs\n- Divs containing other blocks (lists, quotes, code)\n- Empty divs\n\n**Priority**: CRITICAL - Phase 3","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T21:13:06.000104-05:00","updated_at":"2025-10-31T21:38:59.095103-05:00","closed_at":"2025-10-31T21:38:59.095103-05:00","dependencies":[{"issue_id":"k-301","depends_on_id":"k-274","type":"parent-child","created_at":"2025-10-31T21:13:06.001425-05:00","created_by":"cscheid"}]} -{"id":"k-302","title":"Implement note_definition_fenced_block handler","description":"Fenced note definitions (::: ^ref) produce warnings and likely crash.\n\n**Status**: Handler commented out at lines 992-994\n**Helper**: process_note_definition_fenced_block exists\n**Impact**: Cannot use multi-block note definitions\n\n**Example**:\n```\n::: ^mynote\nMulti-block note content.\n\nSecond paragraph.\n:::\n```\n\n**Implementation**:\n1. Uncomment lines 992-994 in treesitter.rs\n2. Write tests for basic single-block notes\n3. Write tests for multi-block notes\n4. Test with complex content (lists, quotes)\n5. Verify integration with note references ([^mynote])\n\n**Test cases needed**:\n- Single-block note definition\n- Multi-block note definition\n- Note with lists\n- Note with quotes\n- Note with code blocks\n- Integration with [^ref] references\n\n**Priority**: HIGH - Phase 3, user-requested feature","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T21:13:07.372432-05:00","updated_at":"2025-10-31T21:42:05.00845-05:00","closed_at":"2025-10-31T21:42:05.00845-05:00","dependencies":[{"issue_id":"k-302","depends_on_id":"k-274","type":"parent-child","created_at":"2025-10-31T21:13:07.373635-05:00","created_by":"cscheid"}]} -{"id":"k-303","title":"Implement pipe_table handlers (6 sub-handlers)","description":"Pipe tables (| Header |) currently crash.\n\n**Status**: All 6 handlers commented out at lines 1111-1118\n**Helpers**: Complete suite exists\n**Impact**: CRASHES on any pipe table\n\n**Complexity**: VERY HIGH - multiple sub-nodes, alignment, caption\n\n**Sub-handlers needed**:\n1. pipe_table_delimiter_cell (line 1111)\n2. pipe_table_header | pipe_table_row (lines 1112-1113)\n3. pipe_table_delimiter_row (line 1115)\n4. pipe_table_cell (line 1116)\n5. caption (line 1117)\n6. pipe_table (line 1118)\n\n**Implementation**:\n1. Uncomment all 6 handlers\n2. Write test for basic 2x2 table\n3. Test column alignment (:---, :---:, ---:)\n4. Test with caption (: Caption text)\n5. Test with inline formatting in cells\n6. Test edge cases (empty cells, single column)\n\n**Test cases needed**:\n- Basic 2x2 table\n- Table with left alignment\n- Table with center alignment\n- Table with right alignment\n- Table with mixed alignment\n- Table with caption\n- Table with formatted cells (bold, code, etc.)\n- Single-column table\n- Tables with empty cells\n- Wide tables\n\n**Priority**: MEDIUM - Phase 4, most complex, can defer","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-31T21:13:08.806054-05:00","updated_at":"2025-10-31T23:14:26.674066-05:00","closed_at":"2025-10-31T23:14:26.674066-05:00","dependencies":[{"issue_id":"k-303","depends_on_id":"k-274","type":"parent-child","created_at":"2025-10-31T21:13:08.807316-05:00","created_by":"cscheid"}]} -{"id":"k-304","title":"Add caption node support to pipe_table grammar","description":"The tree-sitter grammar currently does NOT support captions for pipe tables, even though the handler code in process_pipe_table() has caption support (lines 188-194).\n\n**Current state**:\n- Grammar (tree-sitter-qmd): No caption rule for pipe tables\n- Handler code: Has caption processing logic (commented out in treesitter.rs:1123)\n- Pandoc syntax: Supports captions like:\n\n```\n| Col1 | Col2 |\n|------|------|\n| A | B |\n\n: Caption text here\n```\n\n**Work needed**:\n1. Add caption node to tree-sitter-qmd grammar in grammar.js\n2. Update pipe_table rule to optionally include caption\n3. Run tree-sitter generate and tree-sitter build\n4. Run tree-sitter test and verify\n5. Uncomment caption handler in treesitter.rs:1123\n6. Write tests for tables with captions\n7. Test multi-line captions\n8. Test captions with inline formatting\n\n**Files to modify**:\n- crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js\n- crates/quarto-markdown-pandoc/src/pandoc/treesitter.rs (line 1123)\n- tests/test_treesitter_refactoring.rs\n\n**Estimate**: 2-3 hours\n\n**Note**: Discovered during k-303 (pipe table implementation). See claude-notes/plans/2025-10-31-pipe-table-implementation.md line 101-104.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-31T23:21:51.580375-05:00","updated_at":"2025-11-01T07:28:54.43419-05:00","closed_at":"2025-11-01T07:28:54.43419-05:00"} -{"id":"k-305","title":"Implement caption support for pipe tables","description":"Implement caption support for pipe tables with dual grammar structure (immediate and separated captions).\n\n**Background**: Grammar supports captions in two ways:\n1. Immediate: Caption inside pipe_table node (no empty line)\n2. Separated: Caption as sibling block after pipe_table (with empty line)\n\nBoth need to produce same Pandoc output with caption attached to table.\n\n**Implementation phases**:\n1. Update process_caption() to handle new grammar (direct inline nodes)\n2. Uncomment caption handler in treesitter.rs:1123\n3. Add post-processing to process_section() to attach separated captions\n4. Write comprehensive tests (7 tests)\n\n**Plan**: claude-notes/plans/2025-10-31-caption-implementation.md\n\n**Estimate**: 3 hours\n\n**Files to modify**:\n- src/pandoc/treesitter_utils/caption.rs\n- src/pandoc/treesitter.rs (line 1123)\n- src/pandoc/treesitter_utils/section.rs\n- tests/test_treesitter_refactoring.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T07:24:22.361377-05:00","updated_at":"2025-11-01T07:28:42.208115-05:00","closed_at":"2025-11-01T07:28:42.208115-05:00"} -{"id":"k-306","title":"Fix reference note definition parsing causing document-level crashes","description":"tests/smoke/001.qmd with '^ he llo^' crashes with 'Expected Block or Section, got IntermediateUnknown'. Need to investigate tree-sitter node for reference note definitions and add handler. Blocks: test_do_not_smoke, unit_test_snapshots_qmd. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 1","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-01T14:50:31.823921-05:00","updated_at":"2025-11-02T20:04:50.201748-06:00","closed_at":"2025-11-02T20:04:50.201748-06:00","dependencies":[{"issue_id":"k-306","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-11-01T14:50:31.826047-05:00","created_by":"cscheid"}]} -{"id":"k-307","title":"Fix YAML frontmatter handling causing document crashes","description":"tests/snapshots/qmd/horizontal-rules-vs-metadata.qmd crashes when document has YAML frontmatter. Need to fix document-level parsing to handle metadata blocks. Blocks: unit_test_snapshots_qmd. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 1","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-01T14:50:33.208941-05:00","updated_at":"2025-11-02T19:50:25.625159-06:00","closed_at":"2025-11-02T19:50:25.625159-06:00","dependencies":[{"issue_id":"k-307","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-11-01T14:50:33.210209-05:00","created_by":"cscheid"}]} -{"id":"k-308","title":"Fix citation parsing logic - wrong mode and prefix/suffix distribution","description":"[prefix @c1 suffix; @c2; @c3] should produce single Cite with 3 citations (NormalCitation mode), but produces Spans with individual Cites (AuthorInText mode). Fix citation processing in pandoc/treesitter_utils/spans.rs. Blocks: unit_test_snapshots_native, test_qmd_roundtrip_consistency. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 2","notes":"Analysis complete. Found existing make_cite_inline() function in inline.rs that handles multi-citation parsing. Just need to call it from span_link_helpers.rs. See: claude-notes/investigations/2025-11-02-k-308-code-reuse-analysis.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-01T14:50:34.510781-05:00","updated_at":"2025-11-02T20:33:34.131856-06:00","closed_at":"2025-11-02T20:33:34.131856-06:00","dependencies":[{"issue_id":"k-308","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-11-01T14:50:34.512623-05:00","created_by":"cscheid"}]} -{"id":"k-309","title":"Fix LineBreak vs SoftBreak - hard line breaks not recognized","description":"'Line one \\nLine two' (two trailing spaces) should produce LineBreak but produces SoftBreak. Check tree-sitter grammar for hard_line_break node and add handler. Blocks: test_html_writer, test_json_writer. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 2","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-01T14:50:35.834553-05:00","updated_at":"2025-11-03T07:59:13.88545-06:00","closed_at":"2025-11-03T07:59:14.88545-06:00","dependencies":[{"issue_id":"k-309","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-11-01T14:50:35.835815-05:00","created_by":"cscheid"}]} -{"id":"k-31","title":"Phase 1: Update parse() to use new quarto-source-map system","description":"Update parse() and parse_file() to create FileId and SourceInfo, then call parse_with_parent. Maintain backward compatibility.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T17:17:21.470005-05:00","updated_at":"2025-10-18T17:41:22.376621-05:00","closed_at":"2025-10-18T17:41:22.376621-05:00","dependencies":[{"issue_id":"k-31","depends_on_id":"k-27","type":"blocks","created_at":"2025-10-18T17:17:21.471662-05:00","created_by":"cscheid"}]} -{"id":"k-310","title":"Add validation to reject raw attributes in QMD","description":"'# Hello {=world}' should fail to parse (raw attributes not allowed in QMD) but currently passes. Add validation logic. Blocks: test_disallowed_in_qmd_fails. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 2","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-01T14:50:38.318053-05:00","updated_at":"2025-11-03T08:06:29.11549-06:00","closed_at":"2025-11-03T08:06:29.11549-06:00","dependencies":[{"issue_id":"k-310","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-11-01T14:50:38.319457-05:00","created_by":"cscheid"}]} -{"id":"k-311","title":"Fix nested inline formatting - strikeout inside subscript","description":"'~he~~l~~lo~' should parse as subscript containing strikeout, but produces RawInline leftover. Grammar issue with nested ~ and ~~. Blocks: unit_test_corpus_matches_pandoc_commonmark. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 3","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-01T14:50:39.684354-05:00","updated_at":"2025-11-03T08:12:51.300456-06:00","closed_at":"2025-11-03T08:12:51.300456-06:00","dependencies":[{"issue_id":"k-311","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-11-01T14:50:39.685579-05:00","created_by":"cscheid"}]} -{"id":"k-312","title":"Add underline class to Underline inline conversion","description":"'[underline]{.underline}' should produce Underline inline, not Span. Add special case in span processing. Blocks: unit_test_corpus_matches_pandoc_markdown. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 3","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-01T14:50:41.081508-05:00","updated_at":"2025-11-01T15:00:04.740233-05:00","closed_at":"2025-11-01T15:00:04.740233-05:00","dependencies":[{"issue_id":"k-312","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-11-01T14:50:41.082734-05:00","created_by":"cscheid"}]} -{"id":"k-313","title":"Fix blockquote header roundtrip - extra Space in output","description":"'\u003e ## Header' roundtrips with extra Space at end. Fix header inline content generation. Blocks: test_empty_blockquote_roundtrip. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 3","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-01T14:50:42.533997-05:00","updated_at":"2025-11-03T08:18:53.658811-06:00","closed_at":"2025-11-03T08:18:53.658811-06:00","dependencies":[{"issue_id":"k-313","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-11-01T14:50:42.535244-05:00","created_by":"cscheid"}]} -{"id":"k-314","title":"Fix source map range calculation in tree-sitter processing","description":"Source info pool ranges are incorrect causing snapshot test failures. Review source location tracking. Blocks: unit_test_snapshots_json. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 4","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-01T14:50:43.951908-05:00","updated_at":"2025-11-03T08:41:02.451758-06:00","closed_at":"2025-11-03T08:41:02.451758-06:00","dependencies":[{"issue_id":"k-314","depends_on_id":"k-274","type":"discovered-from","created_at":"2025-11-01T14:50:43.953283-05:00","created_by":"cscheid"}]} -{"id":"k-315","title":"Fix list item block ending detection - lists not ending after blank lines","description":"List items never 'end' properly. Example: '- a\\n\\nb' keeps the list item open when it should end. Block quotes work correctly with the same pattern. Likely issue in scanner.c block ending logic.","notes":"Session 2 investigation: claude-notes/investigations/2025-11-01-session-2-approaches-tried.md. Confirmed Pandoc behavior, attempted 2 implementation approaches. Core issue: tree-sitter has no non-consuming lookahead API. Blank line ambiguity (continue vs end list) requires looking at what follows. All approaches blocked by lexer limitations. May need grammar-level restructuring or acceptance of Pandoc differences.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-01T15:28:42.009884-05:00","updated_at":"2025-11-03T09:05:33.123244-06:00","closed_at":"2025-11-03T09:05:33.123244-06:00"} -{"id":"k-316","title":"Fix quote delimiter space handling - spaces being lost between adjacent quoted elements","description":"Test tests/writers/json/quoted.md fails because spaces captured in quote delimiters are being lost. Need to modify process_quoted to handle delimiter spaces like emphasis/strong/code-span do. Plan: claude-notes/investigations/2025-11-03-quote-delimiter-space-handling-plan.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-03T09:45:18.757343-06:00","updated_at":"2025-11-03T09:54:03.088546-06:00","closed_at":"2025-11-03T09:54:03.088546-06:00"} -{"id":"k-317","title":"Fix table caption attribute handling and stray space","description":"Table captions with attributes (e.g., {tbl-colwidths=\"[30,70]\"}) are not properly parsed. The attribute should be applied to the Table element, and the trailing space before the attribute should be trimmed from caption text. See claude-notes/plans/2025-11-03-table-caption-attr-fix.md for details.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-03T11:30:59.098098-06:00","updated_at":"2025-11-03T11:45:28.627632-06:00","closed_at":"2025-11-03T11:45:28.627632-06:00"} -{"id":"k-318","title":"Replace HashMap with LinkedHashMap in Attr type for deterministic ordering","description":"The Attr type uses HashMap\u003cString, String\u003e which doesn't preserve insertion order, causing non-deterministic test output (e.g., test 030.qmd). Need to replace with LinkedHashMap to ensure attributes appear in insertion order consistently.","notes":"Plan: claude-notes/plans/2025-11-03-hashmap-to-linkedhashmap-migration.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-03T13:49:25.667321-06:00","updated_at":"2025-11-03T14:04:22.926055-06:00","closed_at":"2025-11-03T14:04:22.926055-06:00"} -{"id":"k-319","title":"Fix definition list div tests - add blank lines before closing fence","description":"After tree-sitter grammar overhaul, fenced divs containing bullet lists require a blank line before the closing :::. This is due to how the external scanner handles block closing tokens when lists are involved. The definition list processing code in postprocess.rs is working correctly, but the test files need to be updated to conform to the new grammar requirement.\n\nFiles to update:\n- tests/snapshots/native/definition-list-basic.qmd\n- tests/snapshots/native/definition-list-complex-term.qmd \n- tests/snapshots/native/definition-list-invalid-extra-blocks.qmd\n- tests/snapshots/native/definition-list-invalid-no-nested-list.qmd\n- tests/snapshots/native/definition-list-multiple-defs.qmd\n\nThe transformation logic in crates/quarto-markdown-pandoc/src/pandoc/treesitter_utils/postprocess.rs (lines 169-400) correctly:\n1. Validates div structure with is_valid_definition_list_div()\n2. Transforms valid divs into DefinitionList blocks with transform_definition_list_div()\n3. Applies the transformation via the .with_div() filter\n\nTest with blank line works correctly and produces expected output.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-03T14:26:40.029493-06:00","updated_at":"2025-11-03T14:29:15.855063-06:00","closed_at":"2025-11-03T14:29:15.855063-06:00"} -{"id":"k-32","title":"Phase 1: Add tests for substring parsing in quarto-yaml","description":"Test that offsets map correctly through Substring. Test with SourceContext to verify mapping back to original. Test nested YAML structures with parent SourceInfo.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T17:17:28.912005-05:00","updated_at":"2025-10-18T17:43:13.262464-05:00","closed_at":"2025-10-18T17:43:13.262464-05:00","dependencies":[{"issue_id":"k-32","depends_on_id":"k-5","type":"discovered-from","created_at":"2025-10-18T13:52:28.27812-05:00","created_by":"import"},{"issue_id":"k-32","depends_on_id":"k-27","type":"blocks","created_at":"2025-10-18T17:17:28.913739-05:00","created_by":"cscheid"}]} -{"id":"k-320","title":"Fix div fence to allow no space between ::: and attributes","description":"The div fence parser currently requires a space between ::: and attributes like :::{#id}. Pandoc supports both with and without space. Tests failing: test_div_with_id_has_attr_source, test_div_with_classes_has_attr_source","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-03T15:09:29.011271-06:00","updated_at":"2025-11-14T08:41:19.757841-06:00","closed_at":"2025-11-14T08:41:19.757841-06:00"} -{"id":"k-321","title":"Fix target source info for links and images not being serialized to JSON","description":"When links and images are serialized to JSON, the targetS field (containing source location info for URL and title) is null. Tests failing: test_link_target_source_json_serialization, test_link_target_source_without_title, test_image_target_source_json_serialization","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-03T15:09:35.606552-06:00","updated_at":"2025-11-03T15:13:26.130344-06:00","closed_at":"2025-11-03T15:13:26.130344-06:00"} -{"id":"k-322","title":"Update error corpus snapshot 004 for error message ordering","description":"The error corpus snapshot test for 004.qmd is failing because error messages are now appearing in a different order. Need to review and update the snapshot.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-03T15:22:04.247374-06:00","updated_at":"2025-11-03T15:37:04.679866-06:00","closed_at":"2025-11-03T15:37:04.679866-06:00"} -{"id":"k-323","title":"Implement iterative fixing with temporary files for qmd-syntax-helper","description":"Add iterative fixing capability using temporary file architecture to handle parser limitation where only first error location is reliable.\n\n**Problem**: Parser only reliably reports first error; subsequent errors have wrong locations after error recovery\n**Solution**: Iterate (fix → reparse → fix) until convergence, using temp files as working copies\n**Plan**: claude-notes/plans/2025-11-03-iterative-fixing-with-temp-files.md\n\n**Key changes**:\n- Add tempfile dependency\n- Create temp copy of file, work on temp (all modes)\n- Iterate until convergence (no fixes in iteration)\n- Finalize: copy temp→original (in-place) or print temp (not in-place) or discard (check)\n- Add --max-iterations and --no-iteration flags\n- Add oscillation detection\n\n**Fixes**: test_div_whitespace_conversion failing test","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-03T18:07:41.857396-06:00","updated_at":"2025-11-03T18:14:19.103121-06:00","closed_at":"2025-11-03T18:14:19.103121-06:00"} -{"id":"k-324","title":"Resolve parsing issues from large document corpus","description":"Systematically investigate and fix parsing failures in files from external-sites corpus after grammar migration. Use investigation template in claude-notes/plans/2025-11-04-parsing-failure-investigation-template.md","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-04T09:34:24.382556-06:00","updated_at":"2025-11-21T16:34:00.180804-06:00","closed_at":"2025-11-21T16:34:00.180804-06:00"} -{"id":"k-325","title":"Fix autolink token including leading whitespace","description":"Autolink tokens from tree-sitter scanner include leading whitespace consumed during indentation calculation. Example: token spans ' \u003chttps://example.com\u003e' instead of '\u003chttps://example.com\u003e'. Need to split token in Rust code similar to boundary marker handling. File: crates/quarto-markdown-pandoc/src/pandoc/treesitter_utils/uri_autolink.rs:25","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-04T09:34:32.944423-06:00","updated_at":"2025-11-04T09:49:05.993299-06:00","closed_at":"2025-11-04T09:49:05.993299-06:00","dependencies":[{"issue_id":"k-325","depends_on_id":"k-324","type":"parent-child","created_at":"2025-11-04T09:34:32.945786-06:00","created_by":"cscheid"}]} -{"id":"k-326","title":"Emit errors for unsupported constructs in native writer","description":"Inline note definitions ([^1]: content) are silently dropped by the native writer, producing malformed output. Need to emit clear DiagnosticMessage errors when encountering unsupported constructs. See plan: claude-notes/plans/2025-11-04-inline-note-writer-error-handling-v2.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-04T10:25:26.651564-06:00","updated_at":"2025-11-04T10:43:01.19087-06:00","closed_at":"2025-11-04T10:43:01.19087-06:00"} -{"id":"k-327","title":"Audit other Quarto extension types for silent writer failures","description":"After fixing inline note definitions (k-326), audit other Quarto extension types (Shortcode, EditorialMarks, etc.) to ensure they don't have similar silent failures in writers. Each type found should get its own issue.","notes":"AUDIT COMPLETE - Found 29 panic!() statements across 4 writers:\n\nCRITICAL (P0 - Crashes on valid input):\n- Native writer: 3 panics affecting 10 extension types + ColWidth::Percentage\n- JSON writer: 2 panics affecting 4 editorial marks + CaptionBlock\n- QMD writer: 1 panic on CaptionBlock\n\nMEDIUM (P2 - Incomplete):\n- ANSI writer: 10 panics (incomplete implementation)\n\nSee comprehensive analysis:\n- claude-notes/plans/2025-11-21-k-327-extension-type-audit.md\n- claude-notes/plans/2025-11-21-k-327-all-writer-panics.md\n\nRECOMMENDATION: Start with Phase 1 - Fix native writer panics (4-6 hours)\nThen address JSON writer based on user priorities.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-04T10:25:35.162814-06:00","updated_at":"2025-11-21T18:21:50.917881-06:00","closed_at":"2025-11-21T18:21:50.917881-06:00","dependencies":[{"issue_id":"k-327","depends_on_id":"k-326","type":"blocks","created_at":"2025-11-04T10:25:35.164217-06:00","created_by":"cscheid"}]} -{"id":"k-328","title":"Unicode offset bug in error diagnostics","description":"Error positions are incorrectly calculated when unicode characters precede the error. The checkmark ✓ (3-byte UTF-8) causes a 2-byte offset in error reporting.","notes":"CORRECTED ROOT CAUSE: We're passing byte offsets to ariadne but using default mode (IndexType::Char). Ariadne expects character offsets by default. Fix: Either use IndexType::Byte or convert byte offsets to char offsets. See: claude-notes/plans/2025-11-04-unicode-offset-bug.md","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-04T18:57:46.416514-06:00","updated_at":"2025-11-04T19:29:16.20037-06:00","closed_at":"2025-11-04T19:29:16.20037-06:00"} -{"id":"k-329","title":"Fix qmd roundtrip escaping bug - all punctuation characters lose backslash escapes","description":"When parsing escaped punctuation like $3.14, the parser correctly removes the backslash, but the writer doesn't re-escape it when writing back to qmd. This affects all 30 escapable punctuation characters defined in the grammar. See plan: claude-notes/plans/2025-11-05-fix-qmd-roundtrip-escaping.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-05T06:58:26.988444-06:00","updated_at":"2025-11-05T07:02:51.864538-06:00","closed_at":"2025-11-05T07:02:51.864538-06:00"} -{"id":"k-33","title":"Phase 2: Add SourceContext to ASTContext","description":"Add source_context: SourceContext field to ASTContext. Update constructors (new, with_filename, anonymous). Add helper primary_file_id() -\u003e Option\u003cFileId\u003e. Embed SourceContext inside ASTContext per Option B design.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T17:17:36.662455-05:00","updated_at":"2025-10-18T18:27:15.657617-05:00","closed_at":"2025-10-18T18:27:15.657617-05:00","dependencies":[{"issue_id":"k-33","depends_on_id":"k-27","type":"blocks","created_at":"2025-10-18T17:17:36.664041-05:00","created_by":"cscheid"}]} -{"id":"k-330","title":"Fix crash in error reporting with multi-byte characters","description":"Error reporting crashes when trying to display errors in text with multi-byte UTF-8 characters. The byte indices don't align with character boundaries when passed to ariadne. Repro file: ~/today/characters.qmd","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-05T13:42:56.551912-06:00","updated_at":"2025-11-05T13:46:40.46585-06:00","closed_at":"2025-11-05T13:46:40.46585-06:00"} -{"id":"k-331","title":"Update grammar to accept smart quotes and en-dash characters","description":"The parser currently rejects smart quotes (\", \") and en-dash (–) characters, treating them as parse errors. Need to update the pandoc_str rules in the grammar to accept these Unicode characters.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-05T13:48:08.446527-06:00","updated_at":"2025-11-05T14:01:28.613813-06:00","closed_at":"2025-11-05T14:01:28.613813-06:00","dependencies":[{"issue_id":"k-331","depends_on_id":"k-330","type":"discovered-from","created_at":"2025-11-05T13:48:08.44926-06:00","created_by":"cscheid"}]} -{"id":"k-332","title":"Fixed column offset calculation in error reporting","description":"calculate_byte_offset was treating tree-sitter column as character offset, but tree-sitter reports column as byte offset within the line. This caused error messages to highlight wrong positions when multi-byte UTF-8 characters were present.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-05T14:01:27.544639-06:00","updated_at":"2025-11-05T14:01:36.295285-06:00","closed_at":"2025-11-05T14:01:36.295285-06:00","dependencies":[{"issue_id":"k-332","depends_on_id":"k-330","type":"discovered-from","created_at":"2025-11-05T14:01:27.547324-06:00","created_by":"cscheid"}]} -{"id":"k-333","title":"Define CommonMark-compatible subset of qmd grammar","description":"Design and implement a formal subset of quarto-markdown that guarantees output compatibility with CommonMark 0.31.2. See claude-notes/plans/2025-11-06-commonmark-compatible-subset.md for full design.\n\nGoals:\n- 100% CommonMark spec test compliance (652 tests)\n- Validation tooling (--strict-commonmark flag)\n- Clear documentation of in/out features\n- Differential testing against reference implementation\n\nRationale: Provides migration confidence, testing foundation, and interoperability guarantees. CommonMark chosen over Pandoc because it's stable, formally specified, and testable.","notes":"REVISED PLAN - see claude-notes/plans/2025-11-06-commonmark-compatible-subset.md\n\nKEY INSIGHT: CommonMark spec only defines HTML output, not AST. We need to be precise about what we promise.\n\nREFERENCE IMPLEMENTATION: comrak (Rust CommonMark parser)\n- **Full compliance**: Passes 652/652 CommonMark 0.31.2 spec tests\n- **Critical**: Must configure for CommonMark-only mode (disable GFM extensions)\n- See claude-notes/plans/2025-11-06-comrak-ast-structure.md for detailed AST analysis\n\nAPPROACH: Whitelist subset where qmd_subset ⊂ qmd AND qmd_subset ⊂ CommonMark\n\nINCLUDED: ATX headings, fenced code, emphasis/strong, inline links, lists, blockquotes, hr\nEXCLUDED: qmd features (divs, callouts), edge cases (Setext, indented code, HTML, reference links)\n\nSEMANTIC GRAMMAR: Define subset in terms of abstract semantic structure (Document, Block, Inline, etc.)\n- Level 3: Abstract semantic structure (what we promise)\n- Level 4: Pandoc AST (how we verify - secondary test)\n- Level 5: HTML output (primary test - matches CommonMark spec)\n- Level 2: Tree-sitter CST (implementation detail - NOT what we promise)\n\nTESTING: \n- Primary: HTML output comparison (comrak HTML vs qmd HTML)\n- Secondary: Pandoc AST equivalence (comrak → HTML → Pandoc vs qmd → Pandoc)\n- Both using comrak configured for pure CommonMark (no GFM)\n\nVALIDATION: --validate-subset flag + tree-sitter queries\n\nESTIMATE: 6-9 weeks over 4 phases","status":"open","priority":2,"issue_type":"epic","created_at":"2025-11-06T09:28:34.372497-08:00","updated_at":"2025-11-06T14:35:30.578778-08:00"} -{"id":"k-334","title":"Convert naked HTML elements to warnings with auto-fix to RawInline","description":"Change Q-2-6 hard error to Q-2-9 warning. Auto-convert HTML elements like \u003cb\u003e, \u003cdiv\u003e to RawInline nodes with format='html'. See claude-notes/plans/2025-11-12-html-element-warning-autofix.md for details.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-12T08:30:30.884858-06:00","updated_at":"2025-11-12T08:36:00.378413-06:00","closed_at":"2025-11-12T08:36:00.378413-06:00"} -{"id":"k-335","title":"Add resolved source locations to JSON writer","description":"Add optional 'l' field to JSON output with fully resolved source positions (line/column/offset). See plan: claude-notes/plans/2025-11-12-json-resolved-locations.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-12T13:26:29.786637-06:00","updated_at":"2025-11-12T13:40:55.718065-06:00","closed_at":"2025-11-12T13:40:55.718065-06:00"} -{"id":"k-336","title":"Add JsonConfig struct and write_with_config function","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-12T13:31:19.647326-06:00","updated_at":"2025-11-12T13:32:36.891887-06:00","closed_at":"2025-11-12T13:32:36.891887-06:00","dependencies":[{"issue_id":"k-336","depends_on_id":"k-335","type":"discovered-from","created_at":"2025-11-12T13:31:19.649517-06:00","created_by":"cscheid"}]} -{"id":"k-337","title":"Add resolve_location helper with file_id support","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-12T13:31:20.568572-06:00","updated_at":"2025-11-12T13:33:41.519292-06:00","closed_at":"2025-11-12T13:33:41.519292-06:00","dependencies":[{"issue_id":"k-337","depends_on_id":"k-335","type":"discovered-from","created_at":"2025-11-12T13:31:20.569898-06:00","created_by":"cscheid"}]} -{"id":"k-338","title":"Update SourceInfoSerializer to support optional locations","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-12T13:31:21.519419-06:00","updated_at":"2025-11-12T13:36:15.751848-06:00","closed_at":"2025-11-12T13:36:15.751848-06:00","dependencies":[{"issue_id":"k-338","depends_on_id":"k-335","type":"discovered-from","created_at":"2025-11-12T13:31:21.520812-06:00","created_by":"cscheid"}]} -{"id":"k-339","title":"Update all node serialization sites (Inline/Block/etc)","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-12T13:31:22.959203-06:00","updated_at":"2025-11-12T13:36:15.771082-06:00","closed_at":"2025-11-12T13:36:15.771082-06:00","dependencies":[{"issue_id":"k-339","depends_on_id":"k-335","type":"discovered-from","created_at":"2025-11-12T13:31:22.96042-06:00","created_by":"cscheid"}]} -{"id":"k-34","title":"TypeScript/WASM Integration: SourceContext JSON Serialization","description":"Design and implement JSON serialization strategy for SourceContext/SourceInfo to enable TypeScript/quarto-cli consumption via WASM. Create bridge code to convert from Rust data structures to TypeScript MappedString. See claude-notes/source-context-typescript-integration.md for detailed analysis.","status":"closed","priority":2,"issue_type":"epic","created_at":"2025-10-18T19:24:21.492971-05:00","updated_at":"2025-11-22T11:48:16.603529-06:00","closed_at":"2025-11-22T11:48:16.603529-06:00"} -{"id":"k-340","title":"Add --json-source-location CLI flag to main.rs","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-12T13:31:24.309535-06:00","updated_at":"2025-11-12T13:37:36.301652-06:00","closed_at":"2025-11-12T13:37:36.301652-06:00","dependencies":[{"issue_id":"k-340","depends_on_id":"k-335","type":"discovered-from","created_at":"2025-11-12T13:31:24.310774-06:00","created_by":"cscheid"}]} -{"id":"k-341","title":"Write tests for resolved locations feature","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-12T13:31:25.229975-06:00","updated_at":"2025-11-12T13:40:55.699049-06:00","closed_at":"2025-11-12T13:40:55.699049-06:00","dependencies":[{"issue_id":"k-341","depends_on_id":"k-335","type":"discovered-from","created_at":"2025-11-12T13:31:25.231311-06:00","created_by":"cscheid"}]} -{"id":"k-342","title":"Implement error pruning based on outermost tree-sitter ERROR nodes","description":"Reduce excessive error diagnostics by grouping them into outermost ERROR node ranges and keeping only the first error per range.\n\nImplementation:\n- Strategy 1: Outermost ERROR nodes with first-error heuristic\n- For each ERROR range, keep earliest error (tiebreak with scoring function)\n- Add --no-prune-errors flag for debugging\n- Discard error diagnostics outside ERROR nodes\n\nSee plan: claude-notes/plans/2025-11-13-error-pruning-strategy.md\n\nTest case: ~/today/categorical-predictors.qmd (49 errors -\u003e 2 expected)","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-13T13:51:43.108527-06:00","updated_at":"2025-11-13T14:39:11.144489-06:00","closed_at":"2025-11-13T14:39:11.144489-06:00"} -{"id":"k-343","title":"Add Q-2-10 error detection for apostrophes in all inline constructs","description":"The apostrophe-as-quote-close error (Q-2-10) currently only detects cases in:\n- Plain text (010.qmd)\n- Bold text (011.qmd: **a' b.**)\n- Emphasis (012.qmd: *a' b.*)\n- Link text (013.qmd: [a' b](url))\n\nNeed to add error corpus examples for ALL inline constructs that contain _inlines:\n- Superscript: ^a' b.^\n- Subscript: ~a' b.~\n- Strikeout: ~~a' b.~~\n- Image alt text: ![a' b](url)\n- Span: [a' b]{.class}\n\nFor each construct:\n1. Create minimal example .qmd file\n2. Run --_internal-report-error-state to get parse state\n3. Create corresponding .json with Q-2-10 code and appropriate captures\n4. Rebuild error table with ./scripts/build_error_table.ts\n5. Test that error is properly detected\n\nThis ensures comprehensive coverage across all markdown inline syntax.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-14T10:12:24.91564-06:00","updated_at":"2025-11-14T10:15:41.543373-06:00","closed_at":"2025-11-14T10:15:41.543373-06:00"} -{"id":"k-344","title":"Add qmd-syntax-helper conversion rule for Q-2-10 apostrophe errors","description":"Now that we have comprehensive Q-2-10 error detection for apostrophes being misinterpreted as quote closes (covering 17 inline construct types), add an automatic conversion rule in qmd-syntax-helper to fix these errors.\n\n**Error Pattern**: Q-2-10 \"Closed Quote Without Matching Open Quote\"\n- Occurs when apostrophe followed by space is interpreted as closing single quote\n- Example: `**Humans' Conceptions**` triggers error at the apostrophe\n\n**Fix Strategy**: Escape the apostrophe with backslash\n- Input: `a' b.` → Output: `a\\' b.`\n- Input: `**Humans' Conceptions**` → Output: `**Humans\\' Conceptions**`\n\n**Coverage**: Works across all inline constructs (17 types):\n- Plain text, bold, emphasis, links, images, quotes\n- Superscript, subscript, strikeout\n- Editorial marks (insert, delete, edit comment, highlight)\n- Inline footnotes, headings\n- Both star and underscore variants\n\n**Implementation**:\n1. Detect Q-2-10 error code in parser output\n2. Extract error location from error message\n3. Insert backslash before the apostrophe at that location\n4. Preserve all other formatting\n\n**Testing**:\n- Test with all 17 error corpus examples (010.qmd through 026.qmd)\n- Verify fixed output parses cleanly\n- Verify formatting is preserved (especially in nested constructs)\n\n**Reference**: Error corpus examples in resources/error-corpus/010-026.qmd","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-14T10:27:03.553254-06:00","updated_at":"2025-11-14T11:10:24.027024-06:00","closed_at":"2025-11-14T11:10:24.027024-06:00"} -{"id":"k-345","title":"Add error messages and conversion rules for all unclosed inlines","description":"Add Q-2-12 through Q-2-26 error messages and conversion rules for 15 unclosed inline types: emphasis variants, superscript/subscript, strikeout, editorial marks, inline math, code spans, images, inline footnotes. Each gets error_catalog.json entry, error corpus files, and conversion rule.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-14T12:57:59.162421-06:00","updated_at":"2025-11-14T13:29:05.396509-06:00","closed_at":"2025-11-14T13:29:05.396509-06:00"} -{"id":"k-346","title":"Q-2-12: Unclosed Star Emphasis","description":"Add Q-2-12 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 028.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_12.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.004982-06:00","updated_at":"2025-11-14T13:05:14.240363-06:00","closed_at":"2025-11-14T13:05:14.240363-06:00","dependencies":[{"issue_id":"k-346","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.006482-06:00","created_by":"cscheid"}]} -{"id":"k-347","title":"Q-2-13: Unclosed Strong Star Emphasis","description":"Add Q-2-13 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 029.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_13.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.02468-06:00","updated_at":"2025-11-14T13:08:00.189647-06:00","closed_at":"2025-11-14T13:08:00.189647-06:00","dependencies":[{"issue_id":"k-347","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.026007-06:00","created_by":"cscheid"}]} -{"id":"k-348","title":"Q-2-14: Unclosed Underscore Emphasis","description":"Add Q-2-14 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 030.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_14.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.042977-06:00","updated_at":"2025-11-14T13:10:12.751588-06:00","closed_at":"2025-11-14T13:10:12.751588-06:00","dependencies":[{"issue_id":"k-348","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.04431-06:00","created_by":"cscheid"}]} -{"id":"k-349","title":"Q-2-15: Unclosed Strong Underscore Emphasis","description":"Add Q-2-15 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 031.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_15.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.061834-06:00","updated_at":"2025-11-14T13:11:35.251671-06:00","closed_at":"2025-11-14T13:11:35.251671-06:00","dependencies":[{"issue_id":"k-349","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.063109-06:00","created_by":"cscheid"}]} -{"id":"k-35","title":"Add comprehensive SourceInfo JSON serialization tests","description":"Add tests in quarto-source-map that serialize various SourceInfo structures (Original, Substring, Concat, Transformed) to JSON and verify the format. Document expected JSON schema. Include examples with nested structures matching real .qmd frontmatter use case.","notes":"Tests added for all SourceMapping types (Original, Substring, Concat, Transformed) with 6 new comprehensive tests. Blocked on k-54 (unify 'l' and 's' keys) before documenting final JSON schema.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-18T19:24:29.181738-05:00","updated_at":"2025-11-21T18:04:48.90086-06:00","closed_at":"2025-11-21T18:04:48.90086-06:00","dependencies":[{"issue_id":"k-35","depends_on_id":"k-34","type":"parent-child","created_at":"2025-10-18T19:24:29.183558-05:00","created_by":"cscheid"}]} -{"id":"k-350","title":"Q-2-16: Unclosed Superscript","description":"Add Q-2-16 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 032.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_16.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.080788-06:00","updated_at":"2025-11-14T13:17:10.408383-06:00","closed_at":"2025-11-14T13:17:10.408383-06:00","dependencies":[{"issue_id":"k-350","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.081943-06:00","created_by":"cscheid"}]} -{"id":"k-351","title":"Q-2-17: Unclosed Subscript","description":"Add Q-2-17 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 033.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_17.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.099573-06:00","updated_at":"2025-11-14T13:17:10.410164-06:00","closed_at":"2025-11-14T13:17:10.410164-06:00","dependencies":[{"issue_id":"k-351","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.10086-06:00","created_by":"cscheid"}]} -{"id":"k-352","title":"Q-2-18: Unclosed Strikeout","description":"Add Q-2-18 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 034.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_18.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.11789-06:00","updated_at":"2025-11-14T13:17:10.410723-06:00","closed_at":"2025-11-14T13:17:10.410723-06:00","dependencies":[{"issue_id":"k-352","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.119159-06:00","created_by":"cscheid"}]} -{"id":"k-353","title":"Q-2-19: Unclosed Editorial Insert","description":"Add Q-2-19 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 035.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_19.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.136989-06:00","updated_at":"2025-11-14T13:23:39.416458-06:00","closed_at":"2025-11-14T13:23:39.416458-06:00","dependencies":[{"issue_id":"k-353","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.138231-06:00","created_by":"cscheid"}]} -{"id":"k-354","title":"Q-2-20: Unclosed Editorial Delete","description":"Add Q-2-20 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 036.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_20.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.155625-06:00","updated_at":"2025-11-14T13:23:39.418322-06:00","closed_at":"2025-11-14T13:23:39.418322-06:00","dependencies":[{"issue_id":"k-354","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.156745-06:00","created_by":"cscheid"}]} -{"id":"k-355","title":"Q-2-21: Unclosed Editorial Comment","description":"Add Q-2-21 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 037.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_21.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.174441-06:00","updated_at":"2025-11-14T13:23:39.418988-06:00","closed_at":"2025-11-14T13:23:39.418988-06:00","dependencies":[{"issue_id":"k-355","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.175671-06:00","created_by":"cscheid"}]} -{"id":"k-356","title":"Q-2-22: Unclosed Editorial Highlight","description":"Add Q-2-22 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 038.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_22.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.192589-06:00","updated_at":"2025-11-14T13:23:39.419721-06:00","closed_at":"2025-11-14T13:23:39.419721-06:00","dependencies":[{"issue_id":"k-356","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.194523-06:00","created_by":"cscheid"}]} -{"id":"k-357","title":"Q-2-23: Unclosed Inline Math","description":"Add Q-2-23 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 039.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_23.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.211717-06:00","updated_at":"2025-11-14T13:28:54.946892-06:00","closed_at":"2025-11-14T13:28:54.946892-06:00","dependencies":[{"issue_id":"k-357","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.212863-06:00","created_by":"cscheid"}]} -{"id":"k-358","title":"Q-2-24: Unclosed Code Span","description":"Add Q-2-24 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 040.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_24.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.230901-06:00","updated_at":"2025-11-14T13:28:54.948769-06:00","closed_at":"2025-11-14T13:28:54.948769-06:00","dependencies":[{"issue_id":"k-358","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.232144-06:00","created_by":"cscheid"}]} -{"id":"k-359","title":"Q-2-25: Unclosed Image","description":"Add Q-2-25 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 041.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_25.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.249212-06:00","updated_at":"2025-11-14T13:28:54.949325-06:00","closed_at":"2025-11-14T13:28:54.949325-06:00","dependencies":[{"issue_id":"k-359","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.250854-06:00","created_by":"cscheid"}]} -{"id":"k-36","title":"Design and document SourceInfo JSON schema for TypeScript","description":"Create formal documentation of the JSON schema produced by SourceInfo serialization. Include TypeScript type definitions for the deserialized structure. Document how each SourceMapping variant is represented in JSON. Create example JSON for each variant type.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-18T19:24:36.076544-05:00","updated_at":"2025-11-21T18:04:49.82297-06:00","closed_at":"2025-11-21T18:04:49.82297-06:00","dependencies":[{"issue_id":"k-36","depends_on_id":"k-34","type":"parent-child","created_at":"2025-10-18T19:24:36.078209-05:00","created_by":"cscheid"}]} -{"id":"k-360","title":"Q-2-26: Unclosed Inline Footnote","description":"Add Q-2-26 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 042.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_26.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T12:58:14.268605-06:00","updated_at":"2025-11-14T13:28:54.949855-06:00","closed_at":"2025-11-14T13:28:54.949855-06:00","dependencies":[{"issue_id":"k-360","depends_on_id":"k-345","type":"parent-child","created_at":"2025-11-14T12:58:14.269943-06:00","created_by":"cscheid"}]} -{"id":"k-361","title":"Implement prefixes feature for error corpus","description":"Add support for 'prefixes' field in error corpus JSON files to automatically generate variant test cases. See claude-notes/analysis/2025-11-14-prefixes-feature-design.md for detailed design.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-14T19:01:01.646988-06:00","updated_at":"2025-11-14T19:04:00.707457-06:00","closed_at":"2025-11-14T19:04:00.707457-06:00"} -{"id":"k-362","title":"Fix byte vs character offset bug in error URL generation","description":"Error text shows column 113 but clickable URL shows column 118, likely due to multi-byte characters. Need to ensure both use character offsets, not byte offsets.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-19T16:09:27.976177-06:00","updated_at":"2025-11-19T16:18:08.69016-06:00","closed_at":"2025-11-19T16:18:08.69016-06:00"} -{"id":"k-363","title":"Fix source location tracking for recursive qmd parsing in YAML metadata","description":"When YAML metadata values are parsed as markdown (e.g., in include-in-header.text), warnings show incorrect source locations (e.g., line 1:1 instead of line 12). The recursive parse creates a new context with filename '\u003cmetadata\u003e' and offsets relative to the substring, but diagnostics are added to the parent without adjusting offsets.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-19T16:23:50.854501-06:00","updated_at":"2025-11-20T14:27:40.567512-06:00","closed_at":"2025-11-20T14:27:40.567512-06:00"} -{"id":"k-364","title":"Analyze downsides of Option 1 for YAML recursive parse fix","description":"Deep analysis of Option 1 (post-process diagnostics) approach","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-19T16:27:01.147969-06:00","updated_at":"2025-11-20T14:26:22.926768-06:00","closed_at":"2025-11-20T14:26:22.926768-06:00","dependencies":[{"issue_id":"k-364","depends_on_id":"k-363","type":"discovered-from","created_at":"2025-11-19T16:27:01.154129-06:00","created_by":"cscheid"}]} -{"id":"k-365","title":"Q-2-28 Phase 1: Error Detection (catalog + corpus)","description":"Implement Q-2-28 error detection for line breaks before escaped shortcode closing delimiter \u003e}}}\n\nTasks:\n- Add Q-2-28 entry to error_catalog.json\n- Create Q-2-28.json corpus file with prefixes and suffixes\n- Run build_error_table.ts to generate 241 test cases\n- Verify all cargo tests pass\n\nPlan document: claude-notes/plans/2025-11-20-q-2-28-escaped-shortcode-linebreak.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T10:06:53.436565-06:00","updated_at":"2025-11-20T10:10:30.541919-06:00","closed_at":"2025-11-20T10:10:30.541919-06:00"} -{"id":"k-366","title":"Q-2-28 Phase 2: Automatic Fix (qmd-syntax-helper rule)","description":"Implement qmd-syntax-helper conversion rule to automatically fix Q-2-28 errors\n\nTasks:\n- Create crates/qmd-syntax-helper/src/conversions/q_2_28.rs\n- Implement violation detection from diagnostics\n- Implement fix logic (remove line breaks before \u003e}}})\n- Register in mod.rs\n- Add tests for conversion rule\n- Test end-to-end\n\nDepends on: k-365 (Phase 1 must complete first)\nPlan document: claude-notes/plans/2025-11-20-q-2-28-escaped-shortcode-linebreak.md","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-20T10:07:03.809077-06:00","updated_at":"2025-11-20T10:28:28.684132-06:00","closed_at":"2025-11-20T10:28:28.684132-06:00","dependencies":[{"issue_id":"k-366","depends_on_id":"k-365","type":"blocks","created_at":"2025-11-20T10:07:03.810434-06:00","created_by":"cscheid"}]} -{"id":"k-367","title":"Add error diagnostic for indented footnote content","description":"Pattern found in lino-galiana corpus:\n\nUsers are writing footnotes with indented content (Pandoc syntax):\n\n```markdown\nSome text[^ref].\n\n[^ref]:\n Indented content here\n with multiple lines\n```\n\nThis is **not supported** in quarto-markdown (we don't support pure-indentation blocks).\n\nThe parser currently emits generic 'Parse error: unexpected character or token here'.\n\n**Action**: Add specific error code (e.g., Q-2-XX) that:\n1. Detects footnote definitions followed by indented content\n2. Explains that indented footnotes are not supported\n3. Shows the correct alternative syntax (if any exists in qmd)\n\n**Files affected in lino-galiana corpus**:\n- getting-started/intro/_pourquoi_python_data.qmd (4 errors)\n- getting-started/intro/_intro.qmd\n- NLP/01_intro/exercise2.qmd\n- Others (5+ files total)\n\n**Impact**: Would fix ~5+ files in validation corpus\n\nSee: claude-notes/investigations/2025-11-20-lino-galiana-uncoded-errors.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T12:58:59.089641-06:00","updated_at":"2025-11-20T13:59:11.904645-06:00","closed_at":"2025-11-20T13:59:11.904645-06:00"} -{"id":"k-368","title":"Fix parser handling of multi-byte emoji characters","description":"The tree-sitter grammar fails to parse multi-byte emoji characters (particularly numbered emojis like 1️⃣, 2️⃣, 3️⃣).\n\n**Minimal reproduction**:\n```markdown\n::: {.content-visible when-profile=\"fr\"}\n1️⃣ Trouver le tableau\n:::\n```\n\n**Error**: 'Parse error: unexpected character or token here' at the emoji position\n\n**Technical details**:\n- Emoji like 1️⃣ is a multi-byte UTF-8 sequence:\n - Digit '1' (U+0031): `31`\n - Variation Selector-16 (U+FE0F): `efb88f`\n - Combining Enclosing Keycap (U+20E3): `e283a3`\n- Simplified emoji test cases parse correctly\n- Error only occurs in real corpus files with complex context\n- Likely issue with tree-sitter grammar's UTF-8 handling in certain states\n\n**Files affected in lino-galiana corpus**:\n- 04_webscraping/_exo1_solution.qmd (23 errors)\n- 04_webscraping/_exo2b_suite.qmd (2 errors)\n- git/exogit.qmd (4 errors)\n\n**Impact**: ~29+ errors across 3+ files\n\n**Priority**: High - this is the highest impact uncoded error pattern\n\nSee: claude-notes/investigations/2025-11-20-lino-galiana-uncoded-errors.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-20T12:59:17.190448-06:00","updated_at":"2025-11-20T13:25:44.888949-06:00","closed_at":"2025-11-20T13:25:44.888949-06:00"} -{"id":"k-369","title":"Add error diagnostic for inline code execution in image URLs","description":"Pattern found in lino-galiana corpus:\n\nUsers are attempting to use inline code execution inside image URLs:\n\n```markdown\n![](\\`{python} url_image\\`)\n```\n\nThis syntax is **not valid** in Quarto markdown. The parser currently emits generic 'Parse error: unexpected character or token here'.\n\n**Action**: Add specific error code (e.g., Q-2-XX) that:\n1. Detects backtick-based inline code execution attempts inside image URLs\n2. Explains this syntax is not allowed\n3. Suggests alternatives:\n - Use OJS: `![]({url_image})`\n - Use output block to generate markdown\n - Compute URL in earlier chunk and use variable\n\n**Files affected in lino-galiana corpus**:\n- manipulation/04_api/_exo3_solution.qmd\n\n**Impact**: 1 file, but likely a common user error pattern\n\n**Priority**: Medium - easy win (just add error code), clear user benefit\n\nSee: claude-notes/investigations/2025-11-20-lino-galiana-uncoded-errors.md","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-20T12:59:31.788492-06:00","updated_at":"2025-11-20T14:52:07.524457-06:00","closed_at":"2025-11-20T14:52:07.524457-06:00"} -{"id":"k-37","title":"Implement TypeScript source-map-bridge module in quarto-cli","description":"Create src/core/lib/source-map-bridge.ts in quarto-cli. Implement functions to convert Rust SourceInfo JSON to TypeScript MappedString. Handle all SourceMapping variants (Original, Substring, Concat, Transformed). Include helper to resolve SourceContext FileId to file content.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-18T19:24:43.515818-05:00","updated_at":"2025-11-22T11:48:04.808557-06:00","closed_at":"2025-11-22T11:48:04.808557-06:00","dependencies":[{"issue_id":"k-37","depends_on_id":"k-34","type":"parent-child","created_at":"2025-10-18T19:24:43.517076-05:00","created_by":"cscheid"},{"issue_id":"k-37","depends_on_id":"k-36","type":"blocks","created_at":"2025-10-18T19:24:43.518067-05:00","created_by":"cscheid"}]} -{"id":"k-370","title":"Add error code for spaces in link targets","description":"Found in Tail-Winds corpus validation: 3 files with spaces in image filenames cause parse errors.\n\nExample files:\n- frm/pot_survey.qmd: ![](images/CFRM schema.png)\n- frm/rec_survey.qmd: ![](images/RFRM schema.png) \n- news/index.qmd: ![](images/FW detection 1 panel 30Sept2023.png)\n\nError: Parse error - unexpected character or token (no code)\nLocation: At the space character in the link target\n\nProposed fix strategy: \n- Add error code (e.g., Q-2-33)\n- Error message: 'Link targets cannot contain spaces. Replace spaces with %20'\n- Hint: Show the corrected link with %20 encoding\n\nExample:\nBad: ![](images/CFRM schema.png)\nGood: ![](images/CFRM%20schema.png)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-21T10:50:12.507563-06:00","updated_at":"2025-11-21T10:52:18.540504-06:00","closed_at":"2025-11-21T10:52:18.540504-06:00"} -{"id":"k-371","title":"Add error code for unquoted shortcode parameter starting with digit","description":"Found in Tail-Winds corpus validation: shortcode parameter without quotes that starts with a number followed by non-numeric character.\n\nExample file:\n- team/index.qmd: {{\u003c fa envelope size=1x \u003e}}\n\nError: Parse error - unexpected character or token (no code)\nLocation: At the parameter value '1x' (digit followed by letter, unquoted)\n\nMinimal reproduction: {{\u003c a k=1b \u003e}}\n\nProposed fix strategy:\n- Add error code (e.g., Q-2-34)\n- Error message: 'Shortcode parameter values starting with digits must be quoted'\n- Hint: 'Use quotes around the parameter value: k=\"1b\"'\n\nExample:\nBad: {{\u003c fa envelope size=1x \u003e}}\nGood: {{\u003c fa envelope size=\"1x\" \u003e}}","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-21T10:50:24.46839-06:00","updated_at":"2025-11-21T10:52:19.237997-06:00","closed_at":"2025-11-21T10:52:19.237997-06:00"} -{"id":"k-372","title":"Fix Math+Attr source tracking in postprocess.rs","description":"Implement proper source tracking for Math+Attr pattern in postprocess.rs:667. Currently uses SourceInfo::default() when wrapping Math with following Attr in a Span.\n\n**Pattern**: $math$ {.attr} → Span wrapping Math\n\n**Solution**: Create AttrSourceInfo::combine_all() helper to extract overall SourceInfo from attribute pieces, then combine with math.source_info.\n\n**Plan**: claude-notes/plans/2025-11-21-math-attr-source-tracking.md\n\n**Changes**:\n1. Add combine_all() method to AttrSourceInfo in attr.rs\n2. Update postprocess.rs:667 to use math.source_info.combine(attr.combine_all())\n3. Write comprehensive tests\n\n**Estimate**: 3-4 hours\n\n**Benefits**:\n- Complete source tracking for Math+Attr constructs\n- Better error messages\n- No AST structure changes needed","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-21T15:47:32.899369-06:00","updated_at":"2025-11-21T16:17:43.181211-06:00","closed_at":"2025-11-21T16:17:43.181211-06:00","dependencies":[{"issue_id":"k-372","depends_on_id":"k-373","type":"blocks","created_at":"2025-11-21T15:54:51.848447-06:00","created_by":"cscheid"}]} -{"id":"k-373","title":"CRITICAL: Math+Attr feature completely broken - attributes silently dropped","description":"The Math+Attr desugaring feature documented in docs/syntax/desugaring/math-attributes.qmd is completely non-functional. Attributes following math expressions (e.g., $x$ {.eq}) are being silently dropped.\n\n**Root Cause**: paragraph.rs only handles IntermediateInline and IntermediateInlines, silently dropping IntermediateAttr.\n\n**Impact**: \n- Documented feature doesn't work\n- No error messages (silent failure)\n- Affects both inline and display math\n\n**Example**:\nInput: $E = mc^2$ {#eq-einstein}\nExpected: Span wrapping Math with id\nActual: Just Math, attribute disappears\n\n**Fix**: Add IntermediateAttr case to paragraph.rs (3 line change)\n\n**Plan**: claude-notes/plans/2025-11-21-math-attr-bug-fix.md\n\n**Blocks**: k-372 (source tracking improvement depends on this working)\n\n**Estimate**: 4-4.5 hours (mostly tests)","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-21T15:54:46.725587-06:00","updated_at":"2025-11-21T16:08:41.290257-06:00","closed_at":"2025-11-21T16:08:41.290257-06:00"} -{"id":"k-374","title":"Fix panic!() crashes in native writer","description":"The native writer has 3 panic!() statements that crash the program instead of emitting helpful DiagnosticMessage errors:\n\n1. Line 667: Unsupported block types (BlockMetadata, CaptionBlock)\n2. Line 355: Unsupported inline types (Shortcode, Insert, Delete, Highlight, EditComment, Attr, NoteReference)\n3. Line 94: ColWidth::Percentage (valid Pandoc type!)\n\nThese should emit errors with codes Q-3-20 through Q-3-36.\n\nSee: claude-notes/plans/2025-11-21-k-327-all-writer-panics.md\n\nFiles:\n- crates/quarto-markdown-pandoc/src/writers/native.rs\n\nEstimate: 4-6 hours","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-21T18:21:37.217509-06:00","updated_at":"2025-11-21T18:25:25.520456-06:00","closed_at":"2025-11-21T18:25:25.520456-06:00","dependencies":[{"issue_id":"k-374","depends_on_id":"k-327","type":"discovered-from","created_at":"2025-11-21T18:21:37.219891-06:00","created_by":"cscheid"}]} -{"id":"k-375","title":"Fix panic!() crashes in JSON writer","description":"The JSON writer has panic!() statements for extension types that should emit defensive errors instead:\n\n1. Line 542: Editorial marks (Insert, Delete, Highlight, EditComment) - defensive check since they're desugared\n2. Line 993: CaptionBlock - defensive (should be processed in postprocess but might reach via filters)\n3. Line 1070: Non-MetaMap metadata - defensive\n\nReplace with proper DiagnosticMessage errors.\n\nSee: claude-notes/plans/2025-11-21-k-327-all-writer-panics.md\n\nFiles:\n- crates/quarto-markdown-pandoc/src/writers/json.rs\n\nEstimate: 2-3 hours","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-21T18:21:38.639455-06:00","updated_at":"2025-11-23T07:22:18.115493-06:00","closed_at":"2025-11-23T07:22:19.115493-06:00","dependencies":[{"issue_id":"k-375","depends_on_id":"k-327","type":"discovered-from","created_at":"2025-11-21T18:21:38.641076-06:00","created_by":"cscheid"}]} -{"id":"k-376","title":"Fix panic!() crashes in QMD writer","description":"The QMD writer has defensive panic!() statements that should emit proper errors:\n\n1. Line 1284: CaptionBlock - defensive (should be processed in postprocess but might reach via filters)\n2. Line 272: Non-MetaMap metadata - defensive\n\nReplace with proper DiagnosticMessage errors.\n\nSee: claude-notes/plans/2025-11-21-k-327-all-writer-panics.md\n\nFiles:\n- crates/quarto-markdown-pandoc/src/writers/qmd.rs\n\nEstimate: 1-2 hours","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-21T18:21:39.731796-06:00","updated_at":"2025-11-21T19:24:47.758567-06:00","closed_at":"2025-11-21T19:24:47.758567-06:00","dependencies":[{"issue_id":"k-376","depends_on_id":"k-327","type":"discovered-from","created_at":"2025-11-21T18:21:39.733149-06:00","created_by":"cscheid"}]} -{"id":"k-377","title":"Fix panic!() crashes in ANSI writer","description":"The ANSI writer has 10 panic!() statements for unimplemented features. Since ANSI writer is user-facing, these should emit proper errors:\n\n1. LineBlock, CodeBlock, Table, Figure (standard Pandoc types)\n2. BlockMetadata, NoteDefinitionPara, NoteDefinitionFencedBlock, CaptionBlock (extension types)\n\nOptions:\n- Implement the missing features\n- Or emit clear 'not supported in ANSI format' errors\n\nSee: claude-notes/plans/2025-11-21-k-327-all-writer-panics.md\n\nFiles:\n- crates/quarto-markdown-pandoc/src/writers/ansi.rs\n\nEstimate: 3-5 hours (depends on implement vs error approach)","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-21T18:21:41.226518-06:00","updated_at":"2025-11-21T19:54:03.547745-06:00","closed_at":"2025-11-21T19:54:03.547745-06:00","dependencies":[{"issue_id":"k-377","depends_on_id":"k-327","type":"discovered-from","created_at":"2025-11-21T18:21:41.22778-06:00","created_by":"cscheid"}]} -{"id":"k-378","title":"Add diagnostic error reporting to JSON writer","description":"The JSON writer currently uses panic!() and eprintln!() for defensive error cases. It needs proper diagnostic reporting like the native writer.\n\nCurrent issues:\n- Editorial marks (Insert, Delete, Highlight, EditComment) use eprintln!\n- Shortcode, NoteReference, Attr use eprintln!\n- CaptionBlock uses eprintln!\n- Non-MetaMap metadata uses eprintln!\n\nThese should emit proper DiagnosticMessage errors that work with --json-errors.\n\nRefactoring needed:\n1. Change write() signature from io::Result\u003c()\u003e to Result\u003c(), Vec\u003cDiagnosticMessage\u003e\u003e\n2. Thread errors Vec through write_pandoc, write_block, write_inline, etc.\n3. Replace eprintln! with errors.push(DiagnosticMessageBuilder...)\n4. Add error codes to catalog (or reuse Q-3-20 through Q-3-36 from native writer)\n\nDependencies: k-375 (blocked until this is done)\nEstimate: 3-4 hours","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-21T18:29:53.651635-06:00","updated_at":"2025-11-21T18:39:09.781466-06:00","closed_at":"2025-11-21T18:39:09.781466-06:00","dependencies":[{"issue_id":"k-378","depends_on_id":"k-375","type":"discovered-from","created_at":"2025-11-21T18:29:53.653978-06:00","created_by":"cscheid"}]} -{"id":"k-379","title":"Port Pandoc template functionality to quarto-markdown-pandoc","description":"Replicate Pandoc's complete template system in Rust, including template syntax parsing, variable interpolation, control flow (if/else/for), partials, pipes, and integration with all writers. This will enable standalone document generation with customizable headers, footers, and metadata handling.","notes":"Plans:\n- Initial analysis: claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md\n- Evaluator implementation: claude-notes/plans/pandoc-template-port/2025-11-24-evaluator-implementation-plan.md","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-23T16:46:21.90456-06:00","updated_at":"2025-11-25T13:42:04.043711-06:00","closed_at":"2025-11-25T13:42:04.043711-06:00"} -{"id":"k-38","title":"Add unit tests for TypeScript source-map-bridge","description":"Create comprehensive unit tests in quarto-cli for source-map-bridge module. Test conversion of all SourceMapping variants. Test offset resolution through nested Substring chains. Test edge cases (empty strings, out-of-bounds, etc). Verify MappedString.map() behavior matches expectations.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-18T19:24:50.328408-05:00","updated_at":"2025-11-22T11:48:05.641805-06:00","closed_at":"2025-11-22T11:48:05.641805-06:00","dependencies":[{"issue_id":"k-38","depends_on_id":"k-34","type":"parent-child","created_at":"2025-10-18T19:24:50.329977-05:00","created_by":"cscheid"},{"issue_id":"k-38","depends_on_id":"k-37","type":"blocks","created_at":"2025-10-18T19:24:50.330756-05:00","created_by":"cscheid"}]} -{"id":"k-380","title":"Extract quarto-parse-errors shared crate from qmd error system","description":"Extract the error generation infrastructure from quarto-markdown-pandoc into a shared quarto-parse-errors crate that can be reused by both qmd and template parsers.\n\nThis implements Phase 0.1 from the template port plan.\n\nDeliverables:\n- New quarto-parse-errors crate with generic error types\n- Generic TreeSitterLogObserver (grammar-agnostic)\n- Generic error generation functions\n- Shared build_error_table.ts script (parameterized)\n- include_error_table! macro for compile-time embedding\n- Comprehensive tests\n\nKey types to extract and generalize:\n- ErrorTable, ErrorTableEntry\n- ErrorInfo, ErrorCapture, ErrorNote\n- TreeSitterLogObserver, TreeSitterParseLog\n- ConsumedToken, ProcessMessage\n- produce_diagnostic_messages() function\n\nDependencies:\n- quarto-error-reporting (DiagnosticMessage)\n- quarto-source-map (SourceInfo)\n- tree-sitter (logging)\n- serde, serde_json\n\nReference: claude-notes/plans/pandoc-template-port/2025-11-23-tree-sitter-parsing-subplan.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T08:00:16.27122-06:00","updated_at":"2025-11-24T15:49:58.89596-06:00","closed_at":"2025-11-24T15:49:58.89596-06:00","dependencies":[{"issue_id":"k-380","depends_on_id":"k-379","type":"parent-child","created_at":"2025-11-24T08:00:16.273907-06:00","created_by":"cscheid"}]} -{"id":"k-381","title":"Refactor qmd writer to use QmdWriterContext for emphasis delimiter tracking","description":"Refactor the qmd writer to introduce a QmdWriterContext struct that wraps the errors vector and adds an emphasis_stack field. This will allow us to track parent emphasis delimiters and avoid generating ambiguous *** sequences that quarto-markdown doesn't support. See claude-notes/plans/2025-11-24-qmd-writer-context-refactoring.md for detailed analysis and implementation plan.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T11:19:47.394864-06:00","updated_at":"2025-11-24T11:54:04.183731-06:00","closed_at":"2025-11-24T11:54:04.183731-06:00"} -{"id":"k-382","title":"Create quarto-doctemplate crate structure","description":"Create the basic crate structure for quarto-doctemplate:\n\n- Cargo.toml with dependencies (tree-sitter-doctemplate, quarto-parse-errors, quarto-error-reporting, quarto-source-map)\n- src/lib.rs with module declarations\n- src/ast.rs placeholder\n- src/parser.rs placeholder\n- src/context.rs placeholder\n- src/evaluator.rs placeholder\n- src/error.rs placeholder\n\nThis is the foundation for the template engine implementation.\n\nReference: Phase 1, Task 1 from claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T15:48:06.944414-06:00","updated_at":"2025-11-24T15:54:34.349376-06:00","closed_at":"2025-11-24T15:54:34.349376-06:00","dependencies":[{"issue_id":"k-382","depends_on_id":"k-379","type":"parent-child","created_at":"2025-11-24T15:48:06.948307-06:00","created_by":"cscheid"}]} -{"id":"k-383","title":"Define template AST types","description":"Define the Rust AST types for parsed templates in src/ast.rs:\n\n- TemplateNode enum with variants:\n - Literal(String)\n - Variable(VariableRef)\n - Conditional { branches, else_branch }\n - ForLoop { var, separator, body }\n - Partial { name, var, separator, pipes }\n - Nesting(children)\n - BreakableSpace(children)\n - Comment(String)\n\n- VariableRef struct with:\n - path: Vec\u003cString\u003e (e.g., [\"employee\", \"salary\"])\n - pipes: Vec\u003cPipe\u003e\n\n- Pipe struct with:\n - name: String\n - args: Vec\u003cPipeArg\u003e\n\n- PipeArg enum for pipe parameters\n\nReference: Phase 1, Task 2 from claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T15:48:15.693141-06:00","updated_at":"2025-11-24T16:05:32.336525-06:00","closed_at":"2025-11-24T16:05:32.336525-06:00","dependencies":[{"issue_id":"k-383","depends_on_id":"k-379","type":"parent-child","created_at":"2025-11-24T15:48:15.695478-06:00","created_by":"cscheid"},{"issue_id":"k-383","depends_on_id":"k-382","type":"blocks","created_at":"2025-11-24T15:48:15.697276-06:00","created_by":"cscheid"}]} -{"id":"k-384","title":"Define TemplateValue and TemplateContext types","description":"Define the value and context types in src/context.rs:\n\nTemplateValue enum (NO Pandoc dependencies!):\n- String(String)\n- Bool(bool)\n- List(Vec\u003cTemplateValue\u003e)\n- Map(HashMap\u003cString, TemplateValue\u003e)\n- Null\n\nTemplateContext struct:\n- variables: HashMap\u003cString, TemplateValue\u003e\n- parent: Option\u003cBox\u003cTemplateContext\u003e\u003e for nested scopes (for loops)\n\nKey methods:\n- TemplateValue::is_truthy() - truthiness rules for conditionals\n- TemplateValue::get_path() - nested field access (e.g., \"employee.salary\")\n- TemplateContext::get() - variable lookup with parent chain\n- TemplateContext::with_scope() - create child scope for loops\n\nNote: Numbers are represented as Strings (formatted when converted from JSON).\n\nReference: Phase 1, Task 3 from claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T15:48:25.696993-06:00","updated_at":"2025-11-24T16:05:33.710566-06:00","closed_at":"2025-11-24T16:05:33.710566-06:00","dependencies":[{"issue_id":"k-384","depends_on_id":"k-379","type":"parent-child","created_at":"2025-11-24T15:48:25.699466-06:00","created_by":"cscheid"},{"issue_id":"k-384","depends_on_id":"k-382","type":"blocks","created_at":"2025-11-24T15:48:25.700525-06:00","created_by":"cscheid"}]} -{"id":"k-385","title":"Implement tree-sitter CST to AST conversion","description":"Implement the conversion from tree-sitter parse tree to template AST in src/parser.rs.\n\nModel the implementation on quarto-markdown-pandoc's bottom-up traversal pattern:\n- Use tree-sitter cursor to traverse the parse tree\n- Convert each node type to corresponding AST node\n- Handle nested structures (conditionals, loops, partials)\n- Preserve source locations for error reporting\n\nKey conversions:\n- source_file -\u003e Vec\u003cTemplateNode\u003e\n- text -\u003e Literal\n- interpolation -\u003e Variable\n- conditional -\u003e Conditional\n- forloop -\u003e ForLoop\n- partial -\u003e Partial\n- nesting -\u003e Nesting\n- breakable_block -\u003e BreakableSpace\n- comment -\u003e Comment (or skip)\n- escaped_dollar -\u003e Literal(\"$\")\n\nReference: Phase 1, Tasks 4-5 from claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T15:48:33.191452-06:00","updated_at":"2025-11-24T16:56:27.881729-06:00","closed_at":"2025-11-24T16:56:27.881729-06:00","dependencies":[{"issue_id":"k-385","depends_on_id":"k-379","type":"parent-child","created_at":"2025-11-24T15:48:33.193133-06:00","created_by":"cscheid"},{"issue_id":"k-385","depends_on_id":"k-383","type":"blocks","created_at":"2025-11-24T15:48:33.194036-06:00","created_by":"cscheid"}]} -{"id":"k-386","title":"Integrate error generation with quarto-parse-errors","description":"Integrate the template parser with quarto-parse-errors for beautiful error messages.\n\nTasks:\n1. Create template error corpus in resources/error-corpus/\n - T-*.json files for template-specific errors\n - Common errors: unclosed delimiters, invalid variable names, malformed pipes\n2. Create build script to generate error table\n3. Use TreeSitterLogObserver during parsing\n4. Call produce_diagnostic_messages() on parse errors\n5. Return DiagnosticMessage errors with source locations\n\nThis follows the same pattern as qmd error generation but with template-specific error messages.\n\nReference: Phase 1, Task 6 from claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md","notes":"Implementation plan: claude-notes/plans/2025-01-25-k-386-template-error-corpus.md\n\nPhase 1 scope (this ticket):\n- Add Q-10-* error codes to error_catalog.json (Q-10-1 through Q-10-7)\n- Update DiagnosticCollector and EvalContext to support error codes\n- Update evaluation errors to use Q-10-2 (undefined var), Q-10-5 (unresolved partial), etc.\n- Generic Q-10-1 parse error with source location\n\nFuture work (separate tickets):\n- Full TreeSitterLogObserver integration\n- Error corpus JSON files for tree-sitter state mappings","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-24T15:48:42.779009-06:00","updated_at":"2025-11-25T17:02:12.497544-06:00","dependencies":[{"issue_id":"k-386","depends_on_id":"k-379","type":"parent-child","created_at":"2025-11-24T15:48:42.781375-06:00","created_by":"cscheid"},{"issue_id":"k-386","depends_on_id":"k-385","type":"blocks","created_at":"2025-11-24T15:48:42.782771-06:00","created_by":"cscheid"}]} -{"id":"k-387","title":"Implement basic template evaluator","description":"Implement the basic template evaluation engine in src/evaluator.rs.\n\nInitial scope (no pipes, no partials):\n- Literal nodes -\u003e output as-is\n- Variable interpolation -\u003e resolve from context, render value\n- Conditionals -\u003e evaluate truthiness, render appropriate branch\n- For loops -\u003e iterate over arrays/maps, render body for each\n- Nesting -\u003e track indentation, apply to multi-line content\n- Breakable spaces -\u003e mark spaces as breakable (for Doc output)\n\nKey functions:\n- evaluate(template: \u0026[TemplateNode], context: \u0026TemplateContext) -\u003e Result\u003cString\u003e\n- resolve_variable(var: \u0026VariableRef, context: \u0026TemplateContext) -\u003e TemplateValue\n- render_value(value: \u0026TemplateValue) -\u003e String\n\nFor loop semantics:\n- Array: iterate over elements, bind to variable name and 'it'\n- Map: single iteration with map as context\n- Other: single iteration with value\n\nReference: Phase 1, Task 7 from claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md","notes":"Implementation plan: claude-notes/plans/pandoc-template-port/2025-11-24-evaluator-implementation-plan.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T15:48:54.292312-06:00","updated_at":"2025-11-25T09:38:14.035683-06:00","closed_at":"2025-11-25T09:38:14.035683-06:00","dependencies":[{"issue_id":"k-387","depends_on_id":"k-379","type":"parent-child","created_at":"2025-11-24T15:48:54.293598-06:00","created_by":"cscheid"},{"issue_id":"k-387","depends_on_id":"k-385","type":"blocks","created_at":"2025-11-24T15:48:54.294379-06:00","created_by":"cscheid"},{"issue_id":"k-387","depends_on_id":"k-384","type":"blocks","created_at":"2025-11-24T15:48:54.295134-06:00","created_by":"cscheid"}]} -{"id":"k-388","title":"Write parser and evaluator tests","description":"Write comprehensive tests for the template parser and evaluator.\n\nParser tests:\n- Test each syntax element parses correctly\n- Test error messages for malformed templates\n- Test edge cases (empty templates, nested structures)\n- Use test templates from crates/tree-sitter-doctemplate/test-templates/\n\nEvaluator tests (using simple contexts, NO Pandoc):\n- Variable interpolation (simple, nested paths)\n- Truthiness evaluation for conditionals\n- For loop iteration (arrays, maps, single values)\n- Separator handling in loops\n- Nesting/indentation behavior\n- Breakable space handling\n\nIntegration tests:\n- Parse and evaluate complete templates\n- Compare output against expected results\n- Test the test templates with pandoc and verify matching output\n\nReference: Phase 1, Tasks 8-9 from claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T15:49:03.952777-06:00","updated_at":"2025-11-25T13:41:49.9422-06:00","closed_at":"2025-11-25T13:41:49.9422-06:00","dependencies":[{"issue_id":"k-388","depends_on_id":"k-379","type":"parent-child","created_at":"2025-11-24T15:49:03.954236-06:00","created_by":"cscheid"},{"issue_id":"k-388","depends_on_id":"k-387","type":"blocks","created_at":"2025-11-24T15:49:03.954985-06:00","created_by":"cscheid"}]} -{"id":"k-389","title":"Implement variable interpolation in evaluator","description":"Implement variable resolution and rendering in the template evaluator.\n\nTasks:\n1. Resolve variable path from context (e.g., 'employee.salary')\n2. Handle the 'it' anaphoric keyword for loop iteration\n3. Render values to strings according to Pandoc rules:\n - String: as-is\n - Bool true: 'true', Bool false: ''\n - List: concatenate rendered elements\n - Map: 'true'\n - Null: ''\n4. Handle literal separator syntax $var[, ]$ for array iteration\n\nNote: Pipes are out of scope for this issue - will be added in a separate issue.","notes":"See implementation plan: claude-notes/plans/pandoc-template-port/2025-11-24-evaluator-implementation-plan.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T17:15:18.832-06:00","updated_at":"2025-11-25T09:26:36.889681-06:00","closed_at":"2025-11-25T09:26:36.889681-06:00","dependencies":[{"issue_id":"k-389","depends_on_id":"k-387","type":"discovered-from","created_at":"2025-11-24T17:15:18.835131-06:00","created_by":"cscheid"}]} -{"id":"k-39","title":"Create compatibility module with conversion helpers","description":"Create src/pandoc/source_map_compat.rs with helper functions: node_to_source_info(node, file_id) and node_to_source_info_with_context(node, ctx). These provide a bridge from tree-sitter Node to quarto-source-map::SourceInfo.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T19:28:29.433992-05:00","updated_at":"2025-10-18T19:31:09.54738-05:00","closed_at":"2025-10-18T19:31:09.54738-05:00","dependencies":[{"issue_id":"k-39","depends_on_id":"k-27","type":"parent-child","created_at":"2025-10-18T19:28:29.435925-05:00","created_by":"cscheid"}]} -{"id":"k-390","title":"Implement conditional evaluation in evaluator","description":"Implement conditional evaluation ($if(var)$...$else$...$endif$) in the template evaluator.\n\nTasks:\n1. Evaluate truthiness of condition variable using existing is_truthy() method\n2. Render the appropriate branch (then or else)\n3. Support elseif chains by iterating through branches\n4. Handle nested conditionals correctly\n\nTruthiness rules (already implemented in TemplateValue::is_truthy):\n- Any non-empty map is truthy\n- Any array containing at least one truthy value is truthy\n- Any non-empty string is truthy (even 'false')\n- Boolean true is truthy\n- Everything else is falsy","notes":"See implementation plan: claude-notes/plans/pandoc-template-port/2025-11-24-evaluator-implementation-plan.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T17:15:27.488553-06:00","updated_at":"2025-11-25T09:26:38.203878-06:00","closed_at":"2025-11-25T09:26:38.203878-06:00","dependencies":[{"issue_id":"k-390","depends_on_id":"k-387","type":"discovered-from","created_at":"2025-11-24T17:15:27.49055-06:00","created_by":"cscheid"}]} -{"id":"k-391","title":"Implement for loop evaluation in evaluator","description":"Implement for loop evaluation ($for(var)$...$sep$...$endfor$) in the template evaluator.\n\nTasks:\n1. Resolve the iteration variable from context\n2. Handle different iteration modes:\n - Array: iterate over elements, bind to variable name AND 'it'\n - Map: single iteration with map as context\n - Other: single iteration with value\n3. Create child context for each iteration with proper variable bindings\n4. Render loop body for each iteration\n5. Insert separator between iterations (not after last)\n6. Handle nested loops correctly via context scoping\n\nPer Pandoc semantics:\n- Inside loop, can use either $variable$ or $it$ to refer to current element\n- For nested access: $variable.field$ or $it.field$","notes":"See implementation plan: claude-notes/plans/pandoc-template-port/2025-11-24-evaluator-implementation-plan.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T17:15:37.411702-06:00","updated_at":"2025-11-25T09:26:39.100972-06:00","closed_at":"2025-11-25T09:26:39.100972-06:00","dependencies":[{"issue_id":"k-391","depends_on_id":"k-387","type":"discovered-from","created_at":"2025-11-24T17:15:37.41387-06:00","created_by":"cscheid"}]} -{"id":"k-392","title":"Implement nesting/indentation in evaluator","description":"Implement nesting directive ($^$) for multi-line indentation in the template evaluator.\n\nThe nesting directive ensures subsequent lines are indented to line up with the first line.\n\nExample:\n $item.number$ $^$$item.description$\nproduces:\n 00123 A fine bottle of 18-year old\n Oban whiskey.\n\nTasks:\n1. Track current column position during rendering\n2. When encountering $^$, record current column as indentation level\n3. For content after $^$, indent subsequent lines to this level\n4. Handle nested nesting directives\n\nDesign consideration: The Haskell implementation uses Doc type with DL.nest for this. Our initial implementation can use a simpler approach by:\n- Tracking indentation level as state\n- Post-processing multi-line strings to add indentation\n\nNote: Full fidelity with Pandoc's Doc-based approach may require future refactoring.","notes":"See implementation plan: claude-notes/plans/pandoc-template-port/2025-11-24-evaluator-implementation-plan.md","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-24T17:15:49.733066-06:00","updated_at":"2025-12-02T10:17:19.603977-06:00","dependencies":[{"issue_id":"k-392","depends_on_id":"k-387","type":"discovered-from","created_at":"2025-11-24T17:15:49.734461-06:00","created_by":"cscheid"},{"issue_id":"k-392","depends_on_id":"k-395","type":"parent-child","created_at":"2025-11-25T09:38:08.528633-06:00","created_by":"cscheid"}]} -{"id":"k-393","title":"Implement breakable spaces in evaluator","description":"Implement breakable space blocks ($~$...$~$) in the template evaluator.\n\nPer Pandoc documentation:\n'When rendering to a Doc, a distinction can be made between breakable and unbreakable spaces. Normally, spaces in the template itself are not breakable, but they can be made breakable in part of the template by using the ~ keyword.'\n\n'The ~ keyword has no effect when rendering to Text or String.'\n\nTasks:\n1. For String output (current approach): Simply render content as-is (spaces are not breakable)\n2. If/when we implement Doc output: Mark spaces as breakable using DL.space equivalent\n\nDesign note: This feature is only meaningful when templates produce Doc output that can be reflowed. For simple String rendering, this is a no-op that just passes through content.\n\nPriority: Lower than other evaluator tasks since it's effectively a no-op for String output.","notes":"See implementation plan: claude-notes/plans/pandoc-template-port/2025-11-24-evaluator-implementation-plan.md","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-24T17:16:00.824294-06:00","updated_at":"2025-11-25T09:26:40.878582-06:00","closed_at":"2025-11-25T09:26:40.878582-06:00","dependencies":[{"issue_id":"k-393","depends_on_id":"k-387","type":"discovered-from","created_at":"2025-11-24T17:16:00.825669-06:00","created_by":"cscheid"}]} -{"id":"k-394","title":"Implement template partials","description":"Implement partial (subtemplate) loading and evaluation for the template system.\n\nPartials are subtemplates stored in different files that can be included via:\n- Bare partial: $boilerplate()$\n- Applied to variable: $date:fancy()$\n- With separator: $articles:bibentry()[; ]$\n- With pipes: $employee:name()/uppercase$\n\nKey implementation requirements:\n1. PartialResolver trait for abstracting file loading\n2. Compile-time partial resolution (following Pandoc/doctemplates)\n3. Path resolution (inherit template extension, same directory)\n4. Recursion protection (max depth 50, return '(loop)')\n5. Final newline stripping from partials\n6. Array iteration for applied partials\n\nReference: jgm/doctemplates (Haskell implementation)","notes":"Implementation plan: claude-notes/plans/pandoc-template-port/2025-11-25-partials-implementation-plan.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T09:33:38.810866-06:00","updated_at":"2025-11-25T10:38:24.233547-06:00","closed_at":"2025-11-25T10:38:24.233547-06:00","dependencies":[{"issue_id":"k-394","depends_on_id":"k-387","type":"blocks","created_at":"2025-11-25T09:33:38.813389-06:00","created_by":"cscheid"},{"issue_id":"k-394","depends_on_id":"k-379","type":"parent-child","created_at":"2025-11-25T09:33:53.15054-06:00","created_by":"cscheid"},{"issue_id":"k-394","depends_on_id":"k-396","type":"blocks","created_at":"2025-11-25T09:51:23.443688-06:00","created_by":"cscheid"}]} -{"id":"k-395","title":"Advanced template evaluator features","description":"Implement advanced template evaluator features that go beyond the basic evaluator.\n\nThis includes features that require more sophisticated handling:\n- Nesting/indentation tracking (Doc-based approach)\n- Pipes (value transformations)\n- Other advanced features as identified\n\nThese are lower priority than the core evaluator and partials.","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-25T09:38:02.166977-06:00","updated_at":"2025-12-02T10:17:37.633828-06:00"} -{"id":"k-396","title":"Add diagnostic context to template evaluator","description":"Thread an EvalContext through the template evaluator to support:\n\n1. **Warnings**: Non-fatal issues (e.g., undefined variables)\n2. **Multiple diagnostics**: Accumulate multiple errors/warnings before failing\n3. **Rich source locations**: File/line/column for IDE integration\n4. **Structured messages**: Tidyverse-style errors (problem, details, hints)\n\nKey changes:\n- Create EvalContext struct (variables + DiagnosticCollector + state)\n- Update all evaluate_* functions to take \u0026mut EvalContext\n- Add render_with_diagnostics() API\n- Use Q-9-* error codes for template subsystem\n\nThis should be completed before implementing partials (k-394) since partials need good error reporting for:\n- Partial not found (Q-9-001)\n- Partial parse errors (Q-9-002)\n- Recursion limit exceeded (Q-9-003)\n\nPattern reference: quarto-markdown-pandoc DiagnosticCollector","notes":"Implementation plan: claude-notes/plans/pandoc-template-port/2025-11-25-evaluator-diagnostics-plan.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T09:51:10.250069-06:00","updated_at":"2025-11-25T10:03:30.50845-06:00","closed_at":"2025-11-25T10:03:30.50845-06:00","dependencies":[{"issue_id":"k-396","depends_on_id":"k-379","type":"parent-child","created_at":"2025-11-25T09:51:21.119553-06:00","created_by":"cscheid"}]} -{"id":"k-397","title":"Integrate HTML templates into pico-quarto-render","description":"Extend pico-quarto-render to produce complete HTML documents using quarto-doctemplate and embedded templates. Plan: claude-notes/plans/2025-11-25-pico-quarto-render-template-integration.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-25T11:22:11.123347-06:00","updated_at":"2025-11-25T13:11:51.200536-06:00","closed_at":"2025-11-25T13:11:51.200536-06:00"} -{"id":"k-398","title":"Add quarto-doctemplate and include_dir dependencies to pico-quarto-render","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T11:22:21.086089-06:00","updated_at":"2025-11-25T13:11:51.074435-06:00","closed_at":"2025-11-25T13:11:51.074435-06:00","dependencies":[{"issue_id":"k-398","depends_on_id":"k-397","type":"blocks","created_at":"2025-11-25T11:22:21.088089-06:00","created_by":"cscheid"}]} -{"id":"k-399","title":"Implement EmbeddedResolver for loading templates from include_dir","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T11:22:22.615943-06:00","updated_at":"2025-11-25T13:11:51.094042-06:00","closed_at":"2025-11-25T13:11:51.094042-06:00","dependencies":[{"issue_id":"k-399","depends_on_id":"k-397","type":"blocks","created_at":"2025-11-25T11:22:22.61754-06:00","created_by":"cscheid"}]} -{"id":"k-3ge6","title":"Improve coverage: quarto-core/src/format.rs","description":"Session baseline: 73.45% line coverage. File at 58.65%. Focus on FormatIdentifier and Format methods.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T10:34:52.978749-06:00","updated_at":"2026-01-02T10:37:59.220906-06:00","closed_at":"2026-01-02T10:37:59.220906-06:00","dependencies":[{"issue_id":"k-3ge6","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T10:34:52.98006-06:00","created_by":"daemon"}]} -{"id":"k-3n95","title":"Investigate feasibility of 'kyoto' as project codename","description":"The Rust port of Quarto needs a distinct name to avoid confusion with Pandoc, especially since the port will still use Pandoc in some codepaths. Consider 'kyoto' and 'pampa' as codenames and investigate their feasibility from trademark, namespace, and discoverability perspectives.\n\nPlan document: claude-notes/plans/2025-12-06-project-naming.md","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-06T13:25:25.267234-06:00","updated_at":"2025-12-06T14:11:18.440069-06:00","closed_at":"2025-12-06T14:11:18.440069-06:00"} -{"id":"k-4","title":"Phase C: Switch to DiagnosticCollector","description":"Replace TextErrorCollector and JsonErrorCollector with DiagnosticCollector in readers.\n\nFiles to modify:\n- crates/quarto-markdown-pandoc/src/readers/qmd.rs\n\nMust verify all tests pass with no regressions.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T14:41:45.466234-05:00","updated_at":"2025-10-18T16:20:01.983787-05:00","closed_at":"2025-10-18T16:20:01.983787-05:00","dependencies":[{"issue_id":"k-4","depends_on_id":"k-1","type":"parent-child","created_at":"2025-10-18T14:41:45.467612-05:00","created_by":"cscheid"},{"issue_id":"k-4","depends_on_id":"k-3","type":"blocks","created_at":"2025-10-18T14:41:53.579362-05:00","created_by":"cscheid"}]} -{"id":"k-40","title":"Add source_info_qsm fields alongside existing source_info","description":"Pick 2-3 representative AST structs (e.g., HorizontalRule, Str). Add 'source_info_qsm: Option\u003cquarto_source_map::SourceInfo\u003e' field alongside existing source_info. Populate both during parsing. Verify tests pass. This allows gradual migration.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T19:28:36.642124-05:00","updated_at":"2025-10-18T19:38:50.085409-05:00","closed_at":"2025-10-18T19:38:50.085409-05:00","dependencies":[{"issue_id":"k-40","depends_on_id":"k-27","type":"parent-child","created_at":"2025-10-18T19:28:36.643819-05:00","created_by":"cscheid"},{"issue_id":"k-40","depends_on_id":"k-39","type":"blocks","created_at":"2025-10-18T19:28:36.644708-05:00","created_by":"cscheid"}]} -{"id":"k-400","title":"Expose write_inlines and write_blocks as public API in html.rs","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T11:22:23.959077-06:00","updated_at":"2025-11-25T13:11:51.113212-06:00","closed_at":"2025-11-25T13:11:51.113212-06:00","dependencies":[{"issue_id":"k-400","depends_on_id":"k-397","type":"blocks","created_at":"2025-11-25T11:22:23.96067-06:00","created_by":"cscheid"}]} -{"id":"k-401","title":"Implement MetaValueWithSourceInfo to TemplateValue conversion with HTML and plain-text paths","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T11:22:25.969462-06:00","updated_at":"2025-11-25T13:11:51.130469-06:00","closed_at":"2025-11-25T13:11:51.130469-06:00","dependencies":[{"issue_id":"k-401","depends_on_id":"k-397","type":"blocks","created_at":"2025-11-25T11:22:25.9708-06:00","created_by":"cscheid"}]} -{"id":"k-402","title":"Implement build_template_context with derived values","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T11:22:27.077722-06:00","updated_at":"2025-11-25T13:11:51.147737-06:00","closed_at":"2025-11-25T13:11:51.147737-06:00","dependencies":[{"issue_id":"k-402","depends_on_id":"k-397","type":"blocks","created_at":"2025-11-25T11:22:27.078966-06:00","created_by":"cscheid"}]} -{"id":"k-403","title":"Update pico-quarto-render main to use template rendering","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T11:22:28.323671-06:00","updated_at":"2025-11-25T13:11:51.165301-06:00","closed_at":"2025-11-25T13:11:51.165301-06:00","dependencies":[{"issue_id":"k-403","depends_on_id":"k-397","type":"blocks","created_at":"2025-11-25T11:22:28.324936-06:00","created_by":"cscheid"}]} -{"id":"k-404","title":"Add tests for pico-quarto-render template output","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-25T11:22:30.145875-06:00","updated_at":"2025-11-25T13:15:37.665909-06:00","closed_at":"2025-11-25T13:15:37.665909-06:00","dependencies":[{"issue_id":"k-404","depends_on_id":"k-397","type":"blocks","created_at":"2025-11-25T11:22:30.147564-06:00","created_by":"cscheid"}]} -{"id":"k-405","title":"Add plain-text writer module to quarto-markdown-pandoc","description":"Create writers/plaintext.rs that renders Pandoc AST (Inlines, Blocks) to pure plain text without HTML escaping. This is needed for deriving template values like pagetitle, author-meta, date-meta from MetaInlines. Unlike write_inlines_as_text in html.rs, this should NOT escape HTML entities. Plan: claude-notes/analysis/2025-11-25-plain-text-writer-design.md","design":"## RawInline/RawBlock\n- Echo contents if format is 'plaintext', otherwise drop with warning\n\n## PlainTextWriterContext\n- Thread error diagnostics through all write functions\n- Convenience functions return (String, Vec\u003cDiagnosticMessage\u003e)\n\n## Inlines - Strip structure, keep content:\n- Str, Space, SoftBreak, LineBreak: output directly\n- Emph, Strong, Underline, Strikeout, Superscript, Subscript, SmallCaps, Span: recurse (no markers)\n- Quoted: use actual quote characters\n- Code: mimic markdown (backticks)\n- Math: output raw TeX\n- Link, Image: recurse into content only (no \\![], [])\n- Cite: recurse into content\n- Insert, Delete, Highlight, EditComment: recurse\n- Note: skip (no warning)\n- RawInline: echo if 'plaintext', else drop with warning\n- Shortcode, NoteReference, Attr: drop with warning\n\n## Blocks - Mimic markdown writer:\n- Plain, Paragraph, Header: write inlines\n- CodeBlock: fenced with backticks\n- BlockQuote: \u003e prefix\n- LineBlock: | prefix\n- OrderedList: 1. 2. 3.\n- BulletList: - prefix\n- HorizontalRule: ---\n- Div, Figure: write contents only\n- RawBlock: echo if 'plaintext', else drop with warning\n\n## Blocks - Drop with warning:\n- DefinitionList, Table: complex structure\n- BlockMetadata, NoteDefinitionPara, NoteDefinitionFencedBlock, CaptionBlock: Quarto extensions","notes":"Design decisions:\n1. RawInline/RawBlock: echo contents if format is 'plaintext', otherwise drop with warning\n2. Add PlainTextWriterContext for threading error diagnostics\n3. Issue diagnostic warnings on dropped nodes:\n - RawInline/RawBlock with mismatched formats (not 'plaintext')\n - Unsupported Quarto extensions: Shortcode, NoteReference, Attr (inlines), BlockMetadata, NoteDefinitionPara, NoteDefinitionFencedBlock, CaptionBlock (blocks)\n4. No HTML escaping (unlike write_inlines_as_text in html.rs)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T11:47:43.028154-06:00","updated_at":"2025-11-25T12:08:35.769022-06:00","closed_at":"2025-11-25T12:08:35.769022-06:00","dependencies":[{"issue_id":"k-405","depends_on_id":"k-397","type":"blocks","created_at":"2025-11-25T11:47:48.137303-06:00","created_by":"cscheid"}]} -{"id":"k-406","title":"Implement template-based rendering in pico-quarto-render","description":"Implement template rendering pipeline: prepare_template_metadata() to derive pagetitle from title, meta_to_template_value() with format-specific writers, render_with_template() to produce final output. See plan: claude-notes/plans/2025-11-25-pico-quarto-render-template-rendering.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-25T12:24:48.921665-06:00","updated_at":"2025-11-25T13:11:51.183021-06:00","closed_at":"2025-11-25T13:11:51.183021-06:00","dependencies":[{"issue_id":"k-406","depends_on_id":"k-397","type":"blocks","created_at":"2025-11-25T12:24:48.924707-06:00","created_by":"cscheid"}]} -{"id":"k-407","title":"Extensible filters for quarto-markdown-pandoc","description":"Implement extensible filter infrastructure allowing third-party filters to transform the Pandoc AST. This epic covers:\n\n1. JSON filters - External processes that read/write JSON AST (Pandoc-compatible protocol)\n2. Lua filters - Embedded Lua interpreter with direct AST access (mlua-based)\n\nThis provides compatibility with Pandoc's filter ecosystem while enabling performant Lua filters.\n\nDesign plans:\n- JSON filters: claude-notes/plans/2025-11-26-json-filters-design.md\n- Lua filters: claude-notes/plans/2025-11-26-lua-filters-design.md","status":"open","priority":2,"issue_type":"epic","created_at":"2025-11-26T09:21:24.129138-06:00","updated_at":"2025-11-26T09:21:24.129138-06:00"} -{"id":"k-408","title":"JSON filter support for quarto-markdown-pandoc","description":"Implement JSON filter support following Pandoc's protocol:\n\n**Protocol:**\n- Stdin: Pandoc AST as JSON (using existing JSON writer)\n- Stdout: Modified Pandoc AST as JSON (using existing JSON reader)\n- Args: [target_format, ...]\n- Environment: PANDOC_VERSION, PANDOC_READER_OPTIONS\n\n**Implementation Tasks:**\n1. Add --filter CLI argument to accept filter paths\n2. Create filter execution infrastructure (spawn subprocess, pipe JSON)\n3. Implement interpreter detection for .py, .hs, .pl, .rb, .php, .js, .r files\n4. Add filter discovery (direct path, data dir, PATH)\n5. Support multiple filters with sequential composition\n6. Error handling (filter not found, non-zero exit, JSON parse errors)\n\n**Files to modify:**\n- crates/quarto-markdown-pandoc/src/main.rs (CLI args)\n- crates/quarto-markdown-pandoc/src/filters/ (new module)\n\n**Design plan:** claude-notes/plans/2025-11-26-json-filters-design.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-26T09:21:36.574582-06:00","updated_at":"2025-12-02T08:11:40.923141-06:00","closed_at":"2025-12-02T08:11:40.923141-06:00","dependencies":[{"issue_id":"k-408","depends_on_id":"k-407","type":"parent-child","created_at":"2025-11-26T09:21:36.575916-06:00","created_by":"cscheid"}]} -{"id":"k-409","title":"Lua filter support for quarto-markdown-pandoc","description":"Implement embedded Lua filter support using mlua:\n\n**Architecture:**\n- Use mlua crate for Rust-Lua integration\n- Expose Pandoc AST types as Lua UserData\n- Support both 'typewise' and 'topdown' traversal modes\n- Provide pandoc.* namespace for element constructors\n\n**Implementation Tasks:**\n1. Add mlua dependency to Cargo.toml\n2. Create Lua marshaling layer (Rust AST \u003c-\u003e Lua)\n - Pushers: Block, Inline, Meta types -\u003e Lua tables/userdata\n - Peekers: Lua values -\u003e Rust AST types\n3. Implement element constructors (Str, Para, Header, etc.)\n4. Create filter execution engine\n - Load filter script\n - Detect filter structure (explicit return vs global functions)\n - Apply traversal (typewise or topdown)\n5. Add --lua-filter CLI argument\n6. Implement return value semantics (nil=unchanged, element=replace, list=splice)\n7. Expose global variables (FORMAT, PANDOC_VERSION, etc.)\n\n**Key Design Decisions:**\n- Start with minimal pandoc.* namespace (constructors only)\n- Defer pandoc.utils, pandoc.text, etc. to later phases\n- Use UserData for complex types vs tables for simple ones\n\n**Files to create/modify:**\n- crates/quarto-markdown-pandoc/Cargo.toml (add mlua)\n- crates/quarto-markdown-pandoc/src/lua/ (new module)\n- crates/quarto-markdown-pandoc/src/main.rs (CLI)\n\n**Design plan:** claude-notes/plans/2025-11-26-lua-filters-design.md","notes":"Analysis and plan documents:\n- mlua implementation analysis: claude-notes/plans/2025-12-02-mlua-analysis.md\n- Filter diagnostics analysis: claude-notes/plans/2025-12-02-filter-diagnostics-analysis.md\n- FilterContext refactoring: claude-notes/plans/2025-12-02-filter-context-refactoring.md\n- Original design: claude-notes/plans/2025-11-26-lua-filters-design.md\n- Lua globals reference: claude-notes/lua-globals-report.md\n\nImplementation phases (all required):\n- k-469: Phase 1 - Core types and infrastructure\n- k-470: Phase 2 - Complete element coverage\n- k-471: Phase 3 - Methods and traversal (includes walk())\n- k-472: Phase 4 - Diagnostics and utilities (includes provenance tracking)\n\nKey decisions (2025-12-02):\n- Pandoc uses userdata (not tables) for AST elements\n- Feature flag: `lua-filter` (optional, for WASM compatibility)\n- No `send` feature initially (can add later if needed)\n- Attr must have special access patterns (not simplified)","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-26T09:21:51.214593-06:00","updated_at":"2025-12-02T13:35:48.602062-06:00","dependencies":[{"issue_id":"k-409","depends_on_id":"k-407","type":"parent-child","created_at":"2025-11-26T09:21:51.216178-06:00","created_by":"cscheid"}]} -{"id":"k-41","title":"Update one complete parsing module as proof of concept","description":"Choose a simple module (e.g., thematic_break.rs). Use new node_to_source_info_with_context helpers. Populate source_info_qsm field. Verify tests pass and location info is preserved. This validates the migration approach before wider rollout.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T19:28:43.290726-05:00","updated_at":"2025-10-18T19:39:10.753194-05:00","closed_at":"2025-10-18T19:39:10.753194-05:00","dependencies":[{"issue_id":"k-41","depends_on_id":"k-27","type":"parent-child","created_at":"2025-10-18T19:28:43.292361-05:00","created_by":"cscheid"},{"issue_id":"k-41","depends_on_id":"k-40","type":"blocks","created_at":"2025-10-18T19:28:43.293269-05:00","created_by":"cscheid"}]} -{"id":"k-410","title":"Rust port of citeproc with source-tracked CSL parsing","description":"Port the citeproc Haskell library to Rust, with a key enhancement: CSL style files should be parsed with source location tracking (similar to quarto-yaml's approach for YAML).\n\n**Goals:**\n1. Rust implementation of CSL 1.0.2 citation processing\n2. Source-tracked CSL parsing using quick-xml's event API\n3. Integration with quarto-markdown-pandoc's Pandoc AST\n4. Good error messages pointing to exact CSL locations\n\n**Key Components:**\n- CSL XML parser with SourceInfo annotations (like quarto-yaml)\n- Core citation processing algorithm (Eval module equivalent)\n- Integration with quarto-source-map for position tracking\n- Output to Pandoc Inlines (CiteprocOutput trait equivalent)\n\n**Design Report:** claude-notes/plans/2025-11-26-citeproc-rust-port-design.md\n\n**References:**\n- Haskell citeproc: external-sources/citeproc/\n- quick-xml: external-sources/quick-xml/\n- quarto-yaml patterns: crates/quarto-yaml/","status":"open","priority":4,"issue_type":"epic","created_at":"2025-11-26T09:54:26.380552-06:00","updated_at":"2025-12-01T18:39:55.842344-06:00"} -{"id":"k-411","title":"quarto-xml: Generic XML parser with source tracking","description":"Create quarto-xml crate that provides source-tracked XML parsing, analogous to quarto-yaml.\n\n**Scope:**\n- Thin wrapper around quick-xml\n- Produces XmlWithSourceInfo, XmlElement, XmlAttribute types\n- Tracks element positions (start, end, full span)\n- Tracks attribute positions (name, value)\n- Handles text content and mixed content with positions\n- General-purpose: can parse any XML (CSL, JATS, DocBook, etc.)\n\n**Key Types:**\n- XmlWithSourceInfo (analogous to YamlWithSourceInfo)\n- XmlElement (name, attributes, children, source_info)\n- XmlAttribute (name, value, with positions for both)\n- XmlChildren (Elements, Text, Mixed, Empty)\n\n**Design:** claude-notes/plans/2025-11-26-citeproc-rust-port-design.md (see 'quarto-xml' section)\n\n**Dependencies:**\n- quick-xml\n- quarto-source-map","design":"- claude-notes/plans/2025-11-26-citeproc-rust-port-design.md (architecture overview)\n- claude-notes/research/2025-11-27-quarto-source-map-xml-compatibility.md (compatibility analysis, confirms no quarto-source-map changes needed)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-27T10:33:54.78334-06:00","updated_at":"2025-11-27T11:04:55.611804-06:00","closed_at":"2025-11-27T11:04:55.611804-06:00","dependencies":[{"issue_id":"k-411","depends_on_id":"k-410","type":"parent-child","created_at":"2025-11-27T10:33:54.787683-06:00","created_by":"cscheid"}]} -{"id":"k-412","title":"quarto-csl: CSL parsing with semantic types","description":"Create quarto-csl crate that parses CSL (Citation Style Language) files into semantic Rust types.\n\n**Scope:**\n- Takes XmlWithSourceInfo from quarto-xml as input\n- Produces semantic CSL types: Style, Element, Macro, Locale, etc.\n- Preserves source location information for error reporting\n- Validates CSL structure (macro references, circular dependencies)\n\n**Key Types:**\n- Style (version, options, macros, citation layout, bibliography layout)\n- Element (text, names, date, number, label, group, choose)\n- Macro (name with source info, elements)\n- Formatting (font-style, text-case, prefix, suffix, etc.)\n- Locale (terms, date formats)\n\n**Validation:**\n- Undefined macro detection with suggestions\n- Circular macro dependency detection\n- Invalid variable/term names\n\n**Design:** claude-notes/plans/2025-11-26-citeproc-rust-port-design.md (see 'quarto-csl' section)\n\n**Dependencies:**\n- quarto-xml (for XmlWithSourceInfo input)\n- quarto-source-map\n- quarto-error-reporting (for diagnostics)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-27T10:34:05.752803-06:00","updated_at":"2025-11-27T13:21:10.731725-06:00","closed_at":"2025-11-27T13:21:10.731725-06:00","dependencies":[{"issue_id":"k-412","depends_on_id":"k-410","type":"parent-child","created_at":"2025-11-27T10:34:05.754483-06:00","created_by":"cscheid"},{"issue_id":"k-412","depends_on_id":"k-411","type":"blocks","created_at":"2025-11-27T10:34:05.755497-06:00","created_by":"cscheid"}]} -{"id":"k-413","title":"quarto-xml: Crate scaffolding and core types","description":"Create the quarto-xml crate structure with:\n- Cargo.toml with quick-xml and quarto-source-map dependencies\n- Core type definitions (XmlWithSourceInfo, XmlElement, XmlAttribute, XmlChildren)\n- Module structure (lib.rs, types.rs, parser.rs, error.rs)\n\nThis is foundational work before implementing the parser.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T10:56:31.264678-06:00","updated_at":"2025-11-27T11:01:45.534141-06:00","closed_at":"2025-11-27T11:01:45.534141-06:00","dependencies":[{"issue_id":"k-413","depends_on_id":"k-411","type":"parent-child","created_at":"2025-11-27T10:56:31.266336-06:00","created_by":"cscheid"}]} -{"id":"k-414","title":"quarto-xml: Basic element parsing with position tracking","description":"Implement the core parser:\n- Stack-based XML parsing using quick-xml events\n- Track element start positions (from error_position())\n- Compute element end positions (from buffer_position())\n- Build XmlElement tree with source_info for each element\n\nFocus on elements first, attributes and text content handled separately.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T10:56:43.229663-06:00","updated_at":"2025-11-27T11:02:06.043105-06:00","closed_at":"2025-11-27T11:02:06.043105-06:00","dependencies":[{"issue_id":"k-414","depends_on_id":"k-411","type":"parent-child","created_at":"2025-11-27T10:56:43.231125-06:00","created_by":"cscheid"},{"issue_id":"k-414","depends_on_id":"k-413","type":"blocks","created_at":"2025-11-27T10:56:43.232058-06:00","created_by":"cscheid"}]} -{"id":"k-415","title":"quarto-xml: Attribute position tracking","description":"Add attribute position tracking:\n- Parse attributes from start/empty elements\n- Compute absolute positions from tag start + relative offset\n- Track both attribute name and value positions\n- Handle namespace prefixes correctly","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T10:56:44.351084-06:00","updated_at":"2025-11-27T11:04:15.346252-06:00","closed_at":"2025-11-27T11:04:15.346252-06:00","dependencies":[{"issue_id":"k-415","depends_on_id":"k-411","type":"parent-child","created_at":"2025-11-27T10:56:44.352528-06:00","created_by":"cscheid"},{"issue_id":"k-415","depends_on_id":"k-413","type":"blocks","created_at":"2025-11-27T10:56:44.353301-06:00","created_by":"cscheid"}]} -{"id":"k-416","title":"quarto-xml: Text and mixed content handling","description":"Handle text content:\n- Track text content positions\n- Support mixed content (text + elements)\n- Handle CDATA sections\n- Normalize whitespace-only text (configurable)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T10:56:45.349193-06:00","updated_at":"2025-11-27T11:02:20.701548-06:00","closed_at":"2025-11-27T11:02:20.701548-06:00","dependencies":[{"issue_id":"k-416","depends_on_id":"k-411","type":"parent-child","created_at":"2025-11-27T10:56:45.350601-06:00","created_by":"cscheid"},{"issue_id":"k-416","depends_on_id":"k-413","type":"blocks","created_at":"2025-11-27T10:56:45.3514-06:00","created_by":"cscheid"}]} -{"id":"k-417","title":"quarto-xml: Test suite","description":"Comprehensive tests for quarto-xml:\n- Simple element parsing\n- Nested elements\n- Attributes with positions\n- Text content\n- Mixed content\n- Empty elements\n- CSL-specific patterns (macros, choose, names)\n- Error cases (malformed XML)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-27T10:56:46.670336-06:00","updated_at":"2025-11-27T11:04:37.326057-06:00","closed_at":"2025-11-27T11:04:37.326057-06:00","dependencies":[{"issue_id":"k-417","depends_on_id":"k-411","type":"parent-child","created_at":"2025-11-27T10:56:46.671626-06:00","created_by":"cscheid"},{"issue_id":"k-417","depends_on_id":"k-413","type":"blocks","created_at":"2025-11-27T10:56:46.672886-06:00","created_by":"cscheid"}]} -{"id":"k-418","title":"quarto-xml: Add README.md","description":"Create a minimalistic README.md describing:\n- Purpose of the crate (source-tracked XML parsing)\n- Core types (XmlWithSourceInfo, XmlElement, XmlAttribute)\n- Basic usage example\n- Relationship to quarto-yaml pattern","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-27T11:31:01.691666-06:00","updated_at":"2025-11-27T11:31:41.294011-06:00","closed_at":"2025-11-27T11:31:41.294011-06:00","dependencies":[{"issue_id":"k-418","depends_on_id":"k-411","type":"discovered-from","created_at":"2025-11-27T11:31:01.694515-06:00","created_by":"cscheid"}]} -{"id":"k-419","title":"quarto-xml: Add Q-9-* error catalog entries","description":"Add XML processing errors to quarto-error-reporting/error_catalog.json:\n- Use subsystem number 9 (XML processing) per README.md\n- Add entries for existing error types: XmlSyntax, UnexpectedEof, MismatchedEndTag, InvalidStructure, EmptyDocument, MultipleRoots\n- Follow the existing catalog format and conventions","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T11:31:02.707909-06:00","updated_at":"2025-11-27T11:33:26.358626-06:00","closed_at":"2025-11-27T11:33:26.358626-06:00","dependencies":[{"issue_id":"k-419","depends_on_id":"k-411","type":"discovered-from","created_at":"2025-11-27T11:31:02.709795-06:00","created_by":"cscheid"}]} -{"id":"k-42","title":"Investigate ASTContext serialization for JSON readers/writers","description":"Currently ASTContext.with_filename() stores filename in both 'filenames' Vec and 'source_context', requiring a clone. This duplication exists during the migration period. Investigate how to serialize ASTContext properly in JSON readers/writers so we can eventually remove one of these storage locations and eliminate the clone.","notes":"IMPORTANT: This is related to broader SourceInfo serialization concerns. When we serialize SourceInfo structures with Rc\u003cSourceInfo\u003e parent chains, the serialization duplicates the entire parent chain for each nested element (serde doesn't deduplicate Rc references). This creates significant JSON size blowup with deeply nested structures.\n\nAfter completing k-49 and k-50 (which will let us observe the serialization blowup in practice), we should investigate:\n1. Whether ASTContext serialization has similar issues\n2. If we need a custom serialization strategy for SourceInfo to avoid duplication\n3. Whether we can use some form of reference/ID system in the JSON format\n\nSee claude-notes/rc-serialization-caveat-analysis.md for background.","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-19T08:22:18.415067-05:00","updated_at":"2025-11-23T15:31:08.197492-06:00","dependencies":[{"issue_id":"k-42","depends_on_id":"k-27","type":"related","created_at":"2025-10-19T08:22:18.418-05:00","created_by":"cscheid"},{"issue_id":"k-42","depends_on_id":"k-49","type":"blocks","created_at":"2025-10-19T10:36:57.52073-05:00","created_by":"cscheid"},{"issue_id":"k-42","depends_on_id":"k-50","type":"blocks","created_at":"2025-10-19T10:37:34.10416-05:00","created_by":"cscheid"}]} -{"id":"k-420","title":"quarto-xml: Integrate DiagnosticMessage with XmlParseContext","description":"Refactor quarto-xml to use DiagnosticMessage from quarto-error-reporting:\n- Create XmlParseContext struct to collect diagnostics during parsing\n- Thread mut XmlParseContext through parsing calls (like QMD writer pattern in quarto-markdown-pandoc/src/writers/qmd.rs)\n- Return diagnostics alongside results (valid parse can still have warnings/lints)\n- Convert existing Error types to produce DiagnosticMessage objects with Q-9-* codes\n\nThis enables future warnings and lints, not just errors.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T11:31:03.922449-06:00","updated_at":"2025-11-27T11:35:50.881377-06:00","closed_at":"2025-11-27T11:35:50.881377-06:00","dependencies":[{"issue_id":"k-420","depends_on_id":"k-411","type":"discovered-from","created_at":"2025-11-27T11:31:03.924049-06:00","created_by":"cscheid"},{"issue_id":"k-420","depends_on_id":"k-419","type":"blocks","created_at":"2025-11-27T11:31:03.92484-06:00","created_by":"cscheid"}]} -{"id":"k-421","title":"quarto-xml: Add error behavior tests","description":"Add tests verifying error behavior:\n- Test that specific error types are returned for malformed XML\n- Verify error messages contain useful information\n- Test DiagnosticMessage codes after integration\n- Don't need full snapshot testing (errors are rarer than markdown parse errors)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-27T11:31:05.499516-06:00","updated_at":"2025-11-27T11:36:41.06983-06:00","closed_at":"2025-11-27T11:36:41.06983-06:00","dependencies":[{"issue_id":"k-421","depends_on_id":"k-411","type":"discovered-from","created_at":"2025-11-27T11:31:05.501298-06:00","created_by":"cscheid"},{"issue_id":"k-421","depends_on_id":"k-420","type":"blocks","created_at":"2025-11-27T11:31:05.502103-06:00","created_by":"cscheid"}]} -{"id":"k-422","title":"quarto-citeproc: Citation processing engine","description":"Create quarto-citeproc crate that processes citations using CSL styles.\n\n**Scope:**\n- Takes Style from quarto-csl, References (CSL-JSON), and Citations\n- Produces formatted Pandoc Inlines for citations and bibliography\n- Handles locale/term lookup with fallback chain\n- Implements CSL evaluation algorithm\n\n**Key Types:**\n- Reference (bibliographic data from CSL-JSON)\n- Citation, CitationItem (citation requests)\n- EvalContext (evaluation state)\n\n**Core Features (Phase 3):**\n- Basic text/variable rendering\n- Group elements with delimiters\n- Formatting application (font-style, text-case, prefix/suffix)\n- Simple names rendering\n- Basic date rendering\n- Locale term lookup\n\n**Design:** claude-notes/plans/2025-11-26-citeproc-rust-port-design.md (see Phase 3+)\n\n**Dependencies:**\n- quarto-csl (for Style, Element types)\n- quarto-source-map\n- serde/serde_json (for CSL-JSON parsing)\n\n**Resources:**\n- 60 locale files in locales/\n- 858 CSL conformance tests in test-data/csl-suite/","status":"in_progress","priority":4,"issue_type":"task","created_at":"2025-11-27T13:42:35.14407-06:00","updated_at":"2025-12-01T18:39:26.789258-06:00","dependencies":[{"issue_id":"k-422","depends_on_id":"k-412","type":"blocks","created_at":"2025-11-27T13:42:35.146721-06:00","created_by":"cscheid"}]} -{"id":"k-423","title":"Refactor Output to tagged AST architecture","description":"Introduce intermediate Output enum with Tag support for disambiguation, suppress-author, year suffixes, and hyperlinking. See plan: claude-notes/plans/2025-11-27-citeproc-output-architecture-refactor.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T15:02:34.928484-06:00","updated_at":"2025-11-27T15:09:46.829119-06:00","closed_at":"2025-11-27T15:09:46.829119-06:00","dependencies":[{"issue_id":"k-423","depends_on_id":"k-422","type":"parent-child","created_at":"2025-11-27T15:02:34.931279-06:00","created_by":"cscheid"}]} -{"id":"k-424","title":"Name formatting edge cases (et-al-use-last, delimiter-precedes-last)","description":"Implement missing name formatting features to unlock 20-30 tests. See plan: claude-notes/plans/2025-11-27-csl-conformance-roadmap.md#phase-1","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T15:23:07.844132-06:00","updated_at":"2025-11-27T15:42:22.993502-06:00","closed_at":"2025-11-27T15:42:22.993502-06:00","dependencies":[{"issue_id":"k-424","depends_on_id":"k-422","type":"parent-child","created_at":"2025-11-27T15:23:07.847137-06:00","created_by":"cscheid"}]} -{"id":"k-425","title":"Bibliography sorting","description":"Implement bibliography sorting with sort keys, multi-level sorting, and collation. Foundational for 62+ tests. See plan: claude-notes/plans/2025-11-27-csl-conformance-roadmap.md#phase-2","status":"in_progress","priority":4,"issue_type":"task","created_at":"2025-11-27T15:23:13.229157-06:00","updated_at":"2025-12-01T18:38:49.665867-06:00","dependencies":[{"issue_id":"k-425","depends_on_id":"k-422","type":"parent-child","created_at":"2025-11-27T15:23:13.25017-06:00","created_by":"cscheid"},{"issue_id":"k-425","depends_on_id":"k-424","type":"blocks","created_at":"2025-11-27T15:23:13.251362-06:00","created_by":"cscheid"}]} -{"id":"k-426","title":"Citation collapsing","description":"Implement citation collapsing (year, year-suffix, citation-number). Uses Output AST tags. 21 tests. See plan: claude-notes/plans/2025-11-27-csl-conformance-roadmap.md#phase-3","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-27T15:23:19.77254-06:00","updated_at":"2025-12-01T18:39:05.064799-06:00","dependencies":[{"issue_id":"k-426","depends_on_id":"k-422","type":"parent-child","created_at":"2025-11-27T15:23:19.774888-06:00","created_by":"cscheid"},{"issue_id":"k-426","depends_on_id":"k-425","type":"blocks","created_at":"2025-11-27T15:23:19.776014-06:00","created_by":"cscheid"}]} -{"id":"k-427","title":"Full disambiguation algorithm","description":"Implement complete disambiguation: add-givenname, add-year-suffix, givenname-disambiguation-rule. 67 tests. See plan: claude-notes/plans/2025-11-27-csl-conformance-roadmap.md#phase-4","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-27T15:23:24.56052-06:00","updated_at":"2025-12-01T18:38:56.733561-06:00","dependencies":[{"issue_id":"k-427","depends_on_id":"k-422","type":"parent-child","created_at":"2025-11-27T15:23:24.562162-06:00","created_by":"cscheid"},{"issue_id":"k-427","depends_on_id":"k-426","type":"blocks","created_at":"2025-11-27T15:23:24.563128-06:00","created_by":"cscheid"}]} -{"id":"k-428","title":"Phase 1 remaining: name formatting edge cases","description":"Optional/deferred name formatting features: HTML entity escaping, complex initialize=false variants, name-part elements, apostrophe handling. See plan: claude-notes/plans/2025-11-27-phase1-remaining-name-features.md","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-27T16:05:32.498847-06:00","updated_at":"2025-12-01T18:38:43.145568-06:00","dependencies":[{"issue_id":"k-428","depends_on_id":"k-422","type":"discovered-from","created_at":"2025-11-27T16:05:32.501717-06:00","created_by":"cscheid"}]} -{"id":"k-429","title":"Extract Pandoc AST types to quarto-pandoc-types crate","description":"Create quarto-pandoc-types crate with full Pandoc AST, enabling quarto-citeproc to produce Pandoc Inlines output. See plan: claude-notes/plans/2025-11-27-quarto-pandoc-types-extraction.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T18:54:10.464197-06:00","updated_at":"2025-11-27T19:08:34.290502-06:00","closed_at":"2025-11-27T19:08:34.290502-06:00","dependencies":[{"issue_id":"k-429","depends_on_id":"k-422","type":"discovered-from","created_at":"2025-11-27T18:54:10.466769-06:00","created_by":"cscheid"}]} -{"id":"k-43","title":"Performance: Optimize SourceMapping to use Rc/Arc instead of Box","description":"SourceMapping currently uses Box\u003cSourceInfo\u003e for parent references, causing expensive deep clones every time make_source_info() is called during YAML parsing (hundreds of times per document). Consider changing to Rc\u003cSourceInfo\u003e or Arc\u003cSourceInfo\u003e to make cloning cheap (reference counting). Need to study: serialization implications, thread-safety requirements, and performance benchmarks.","notes":"RECOMMENDATION: Use Rc\u003cSourceInfo\u003e instead of Box\u003cSourceInfo\u003e.\n\nAnalysis in claude-notes/sourcemapping-rc-arc-analysis.md\n\nKey findings:\n- Serde supports Rc with 'rc' feature flag\n- Serialization doesn't preserve sharing (acceptable)\n- Rc preferred over Arc (no threading, faster)\n- Expected 10-50x speedup for nested documents\n- Easy migration to Arc if needed later\n\nImplementation:\n1. Add serde rc feature to Cargo.toml\n2. Box\u003cSourceInfo\u003e → Rc\u003cSourceInfo\u003e\n3. Box::new → Rc::new\n4. Verify serialization tests pass","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T08:22:29.60798-05:00","updated_at":"2025-10-19T08:37:10.883135-05:00","closed_at":"2025-10-19T08:37:10.883135-05:00","dependencies":[{"issue_id":"k-43","depends_on_id":"k-27","type":"related","created_at":"2025-10-19T08:22:29.609678-05:00","created_by":"cscheid"}]} -{"id":"k-430","title":"Fix prefix/suffix ordering for layout formatting","description":"CSL spec puts prefix/suffix INSIDE formatting for layout elements. Currently we apply formatting first, then add prefix/suffix - should be reversed. See claude-notes/plans/2025-11-27-csl-failing-test-analysis.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-27T19:36:18.517666-06:00","updated_at":"2025-11-27T19:41:14.539423-06:00","closed_at":"2025-11-27T19:41:14.539423-06:00","dependencies":[{"issue_id":"k-430","depends_on_id":"k-422","type":"discovered-from","created_at":"2025-11-27T19:36:18.519031-06:00","created_by":"cscheid"}]} -{"id":"k-431","title":"Preserve HTML markup in CSL-JSON text fields","description":"CSL-JSON allows HTML markup in text fields like title. We escape it instead of preserving. Example: '\u003ci\u003eTitle\u003c/i\u003e' becomes '\u0026lt;i\u0026gt;Title\u0026lt;/i\u0026gt;'. See claude-notes/plans/2025-11-27-csl-failing-test-analysis.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-27T19:36:24.387607-06:00","updated_at":"2025-11-27T19:48:43.34973-06:00","closed_at":"2025-11-27T19:48:43.34973-06:00","dependencies":[{"issue_id":"k-431","depends_on_id":"k-422","type":"discovered-from","created_at":"2025-11-27T19:36:24.389102-06:00","created_by":"cscheid"}]} -{"id":"k-432","title":"Implement flip-flop formatting","description":"When italic is applied to content already containing \u003ci\u003e, nested italics should flip to normal using \u003cspan style='font-style:normal;'\u003e. Affects 19 flipflop_* tests. See claude-notes/plans/2025-11-27-csl-failing-test-analysis.md","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-11-27T19:36:30.656639-06:00","updated_at":"2025-11-27T20:09:50.056754-06:00","closed_at":"2025-11-27T20:09:50.056754-06:00","dependencies":[{"issue_id":"k-432","depends_on_id":"k-422","type":"discovered-from","created_at":"2025-11-27T19:36:30.657962-06:00","created_by":"cscheid"}]} -{"id":"k-433","title":"Text case edge cases (quotes, stop words)","description":"Text case transformations have issues: content inside quotes being lowercased, quote chars escaped as \u0026quot;, stop words not handled. See claude-notes/plans/2025-11-27-csl-failing-test-analysis.md","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-11-27T19:36:36.000213-06:00","updated_at":"2025-11-27T19:59:06.682741-06:00","closed_at":"2025-11-27T19:59:06.682741-06:00","dependencies":[{"issue_id":"k-433","depends_on_id":"k-422","type":"discovered-from","created_at":"2025-11-27T19:36:36.001502-06:00","created_by":"cscheid"}]} -{"id":"k-434","title":"Date era formatting (BC/AD for negative years)","description":"Negative years should display with era suffix: '100BC' not '-100'. See claude-notes/plans/2025-11-27-csl-failing-test-analysis.md","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-11-27T19:36:41.485027-06:00","updated_at":"2025-11-27T20:27:32.265412-06:00","closed_at":"2025-11-27T20:27:32.265412-06:00","dependencies":[{"issue_id":"k-434","depends_on_id":"k-422","type":"discovered-from","created_at":"2025-11-27T19:36:41.486273-06:00","created_by":"cscheid"}]} -{"id":"k-435","title":"Title case stop words not implemented","description":"Title case transformation should lowercase stop words (to, and, for, the, a, an, etc.) except at the start of a sentence. Currently all words are capitalized. Example: 'from \"distance\" to \"friction\"' should become 'From \"Distance\" to \"Friction\"' but we produce 'From \"Distance\" To \"Friction\"'. See textcase_InQuotes test.","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-11-27T20:00:30.12965-06:00","updated_at":"2025-11-29T14:03:36.943769-06:00","closed_at":"2025-11-29T14:03:36.943769-06:00","dependencies":[{"issue_id":"k-435","depends_on_id":"k-433","type":"discovered-from","created_at":"2025-11-27T20:00:30.131481-06:00","created_by":"cscheid"}]} -{"id":"k-436","title":"Title case should preserve content inside quotes","description":"Title case transformation should not modify text inside quotation marks. Currently quoted content is being lowercased then capitalized like other words. Example: 'from \"distance\"' with title case should preserve the quoted word's original case or capitalize it as a unit, not lowercase it. See textcase_InQuotes test.","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-11-27T20:00:30.947039-06:00","updated_at":"2025-11-29T14:03:41.974135-06:00","closed_at":"2025-11-29T14:03:41.974135-06:00","dependencies":[{"issue_id":"k-436","depends_on_id":"k-433","type":"discovered-from","created_at":"2025-11-27T20:00:30.948975-06:00","created_by":"cscheid"}]} -{"id":"k-437","title":"Implement CSL disambiguation","description":"Implement disambiguation for CSL citations. Plan: claude-notes/plans/2025-11-28-disambiguation-study.md","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-28T09:59:20.720541-06:00","updated_at":"2025-11-28T12:07:43.402073-06:00","closed_at":"2025-11-28T12:07:43.402073-06:00"} -{"id":"k-438","title":"Phase 1: Disambiguation infrastructure","description":"Parse disambiguation attributes, add DisambiguationData to Reference, implement year-suffix variable","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-28T09:59:25.417403-06:00","updated_at":"2025-11-28T10:03:39.592859-06:00","closed_at":"2025-11-28T10:03:39.592859-06:00","dependencies":[{"issue_id":"k-438","depends_on_id":"k-437","type":"parent-child","created_at":"2025-11-28T09:59:25.418718-06:00","created_by":"cscheid"}]} -{"id":"k-439","title":"Phase 2: Ambiguity detection","description":"Implement DisambData structure and find_ambiguities function","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-28T09:59:35.739829-06:00","updated_at":"2025-11-28T10:09:07.167129-06:00","closed_at":"2025-11-28T10:09:07.167129-06:00","dependencies":[{"issue_id":"k-439","depends_on_id":"k-437","type":"parent-child","created_at":"2025-11-28T09:59:35.741253-06:00","created_by":"cscheid"},{"issue_id":"k-439","depends_on_id":"k-438","type":"blocks","created_at":"2025-11-28T09:59:35.742043-06:00","created_by":"cscheid"}]} -{"id":"k-44","title":"Investigate and optimize SourceInfo JSON serialization size","description":"SourceInfo serialization duplicates parent chains in JSON. For a document with 100 YAML nodes sharing a parent, JSON contains ~100 full copies of the parent chain.\n\nProblem: When shipping SourceInfo across WASM/TypeScript boundaries, large documents may produce bloated JSON.\n\nInvestigation needed:\n1. Benchmark actual serialization sizes on real documents\n2. Measure impact of gzip/brotli compression\n3. Consider custom serialization with ID-based references\n4. Evaluate flattening parent chains to original positions\n\nSee claude-notes/rc-serialization-caveat-analysis.md for detailed analysis.\n\nNote: This is separate from the Rc optimization (k-43). Rc improves memory during parsing. This issue is about JSON size for process boundaries.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T08:36:59.796906-05:00","updated_at":"2025-10-20T15:09:12.027921-05:00","closed_at":"2025-10-20T15:09:12.027921-05:00","dependencies":[{"issue_id":"k-44","depends_on_id":"k-43","type":"related","created_at":"2025-10-19T08:36:59.799363-05:00","created_by":"cscheid"},{"issue_id":"k-44","depends_on_id":"k-34","type":"related","created_at":"2025-10-19T08:36:59.800183-05:00","created_by":"cscheid"}]} -{"id":"k-440","title":"Phase 3: Year suffix assignment","description":"Implement addYearSuffixes following bibliography sort order","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-28T09:59:35.760239-06:00","updated_at":"2025-11-28T10:09:07.187101-06:00","closed_at":"2025-11-28T10:09:07.187101-06:00","dependencies":[{"issue_id":"k-440","depends_on_id":"k-437","type":"parent-child","created_at":"2025-11-28T09:59:35.761511-06:00","created_by":"cscheid"},{"issue_id":"k-440","depends_on_id":"k-438","type":"blocks","created_at":"2025-11-28T09:59:35.762623-06:00","created_by":"cscheid"}]} -{"id":"k-441","title":"Phase 4: Name disambiguation","description":"Implement tryAddNames, tryAddGivenNames, apply name hints in rendering","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-28T09:59:35.780279-06:00","updated_at":"2025-11-28T10:15:26.02283-06:00","closed_at":"2025-11-28T10:15:26.02283-06:00","dependencies":[{"issue_id":"k-441","depends_on_id":"k-437","type":"parent-child","created_at":"2025-11-28T09:59:35.781448-06:00","created_by":"cscheid"},{"issue_id":"k-441","depends_on_id":"k-438","type":"blocks","created_at":"2025-11-28T09:59:35.782378-06:00","created_by":"cscheid"}]} -{"id":"k-442","title":"Phase 5: Disambiguation condition","description":"Implement tryDisambiguateCondition, fix ConditionType::Disambiguate","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-28T09:59:35.799581-06:00","updated_at":"2025-11-28T11:56:18.167906-06:00","closed_at":"2025-11-28T11:56:18.167906-06:00","dependencies":[{"issue_id":"k-442","depends_on_id":"k-437","type":"parent-child","created_at":"2025-11-28T09:59:35.800805-06:00","created_by":"cscheid"},{"issue_id":"k-442","depends_on_id":"k-438","type":"blocks","created_at":"2025-11-28T09:59:35.801551-06:00","created_by":"cscheid"}]} -{"id":"k-443","title":"Phase 6: Integration","description":"Two-pass rendering, bibliography coordination","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-28T09:59:35.819937-06:00","updated_at":"2025-11-28T12:07:32.66201-06:00","closed_at":"2025-11-28T12:07:32.66201-06:00","dependencies":[{"issue_id":"k-443","depends_on_id":"k-437","type":"parent-child","created_at":"2025-11-28T09:59:35.821255-06:00","created_by":"cscheid"},{"issue_id":"k-443","depends_on_id":"k-438","type":"blocks","created_at":"2025-11-28T09:59:35.822146-06:00","created_by":"cscheid"}]} -{"id":"k-444","title":"Multi-pass rendering architecture for quarto-citeproc","description":"Refactor quarto-citeproc to use a multi-pass rendering architecture similar to Pandoc's citeproc. This enables proper delimiter handling, substitute inheritance, and multi-pass disambiguation.\n\nKey changes:\n1. Add delimiter to Formatting struct (apply at render time, not evaluation)\n2. Implement CslRenderer trait for format-agnostic rendering\n3. Add substitute context inheritance in EvalContext\n4. Refactor disambiguation to use iterative re-rendering\n\nExpected impact: Unlock 80-150 additional CSL tests.\n\nSee detailed design: claude-notes/plans/2025-11-28-multi-pass-rendering-architecture.md","status":"in_progress","priority":4,"issue_type":"feature","created_at":"2025-11-28T11:16:56.366848-06:00","updated_at":"2025-12-01T18:38:32.516951-06:00"} -{"id":"k-445","title":"Refactor EvalContext for unified variable lookup","description":"Add locator/label fields to EvalContext and create unified get_variable() method. This centralizes variable resolution and prepares for citation item support. See claude-notes/plans/2025-11-27-csl-conformance-roadmap.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-28T14:09:46.466267-06:00","updated_at":"2025-11-28T14:12:59.745492-06:00","closed_at":"2025-11-28T14:12:59.745492-06:00"} -{"id":"k-446","title":"Implement citation item variable support (locator, label)","description":"Support citation item variables: locator, label. Required for ~50+ tests including label plural detection, position tracking. Depends on k-445 (EvalContext refactoring).","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-28T14:09:52.846487-06:00","updated_at":"2025-11-28T14:15:43.161183-06:00","closed_at":"2025-11-28T14:15:43.161183-06:00","dependencies":[{"issue_id":"k-446","depends_on_id":"k-445","type":"blocks","created_at":"2025-11-28T14:09:52.848435-06:00","created_by":"cscheid"}]} -{"id":"k-447","title":"Implement citation position tracking (ibid, subsequent, near-note)","description":"Track citation history to detect position conditions: ibid (same as previous), ibid-with-locator, subsequent, near-note. Required for note-style citations. Unlocks ~26 position tests plus many bugreports. Architecture: add citation history to Processor, track previous citation ID and note number.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-28T14:21:53.586937-06:00","updated_at":"2025-11-28T14:31:25.900914-06:00","closed_at":"2025-11-28T14:31:25.900914-06:00"} -{"id":"k-448","title":"Implement correct fixPunct behavior matching Pandoc citeproc","description":"Current fix_punct_inlines is applied as global post-process which is incorrect. Need to apply at sibling boundaries during rendering, matching Pandoc's approach. See claude-notes/plans/2025-11-28-fixpunct-correct-implementation.md","status":"in_progress","priority":4,"issue_type":"task","created_at":"2025-11-28T16:11:52.534598-06:00","updated_at":"2025-12-01T18:38:22.468703-06:00"} -{"id":"k-449","title":"Implement CSL disambiguation re-rendering loop","description":"Core disambiguation algorithm needs iterative re-rendering after applying fixes. See claude-notes/plans/2025-11-28-disambiguation-fixes.md for full analysis. Phase 1: Re-rendering loop. Phase 2: Add-names logic. Phase 3: Year suffix edge cases. Phase 4: Citation-label.","status":"in_progress","priority":4,"issue_type":"feature","created_at":"2025-11-28T18:14:59.713645-06:00","updated_at":"2025-12-01T18:38:15.598805-06:00"} -{"id":"k-45","title":"Phase 4: Design and implement MetaWithSourceInfo structure","description":"Replace Meta (LinkedHashMap\u003cString, MetaValue\u003e) with MetaWithSourceInfo that preserves source location tracking from YamlWithSourceInfo through the YAML→Meta transformation. This enables proper error reporting and validates serialization approach before Phase 3 migration.\n\nKey insight: Pandoc's Meta is not YAML - it's an interpreted structure where strings are parsed as Markdown. We need source tracking at every level: keys, values, and nested structures.\n\nSee claude-notes/phase4-metawithsourceinfo-design.md for detailed design.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-19T09:07:12.810111-05:00","updated_at":"2025-10-20T15:04:31.593778-05:00","closed_at":"2025-10-20T15:04:31.593778-05:00","dependencies":[{"issue_id":"k-45","depends_on_id":"k-27","type":"parent-child","created_at":"2025-10-19T09:07:12.812754-05:00","created_by":"cscheid"}]} -{"id":"k-450","title":"quarto-citeproc: Name handling architecture fixes","description":"Fix architectural issues in name handling that prevent ~56 CSL conformance tests from passing.\n\n**Plan:** claude-notes/plans/2025-11-28-name-handling-architecture.md\n\n**Key Issues:**\n1. Name formatting returns String instead of Output (blocks all other fixes)\n2. Missing `\u003cname-part\u003e` element support for per-part formatting\n3. Missing `comma_suffix` and `static_ordering` fields on Name struct\n4. Missing Byzantine (non-Western) name detection\n5. Missing `demote-non-dropping-particle` style option\n\n**Implementation Order:**\n1. Refactor format_names/format_single_name to return Output\n2. Add name-part formatting to CSL parser\n3. Add missing Name fields\n4. Add Byzantine name detection\n5. Add demote-non-dropping-particle support\n\n**Impact:** ~56 failing tests in name_* category","notes":"All 5 phases implemented:\n- Phase 1: format_single_name returns Output (complete)\n- Phase 2: name-part formatting works (complete)\n- Phase 3: comma_suffix and static_ordering fields added (complete)\n- Phase 4: is_byzantine() method implemented (complete)\n- Phase 5: demote_non_dropping_particle support (complete)\n\nRemaining issues are edge case bugs, not architectural. 42 unknown name tests remain (47 fail when run). Key bugs identified:\n1. Dropping particle not wrapped in separate formatting element\n2. initialize=false period handling strips trailing periods\n3. initialize=false space normalization not working\n\nThese bugs should be tracked as separate focused issues.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-28T19:29:23.312079-06:00","updated_at":"2025-11-29T14:08:00.894711-06:00","closed_at":"2025-11-29T14:08:00.894711-06:00","dependencies":[{"issue_id":"k-450","depends_on_id":"k-422","type":"parent-child","created_at":"2025-11-28T19:29:23.314676-06:00","created_by":"cscheid"}]} -{"id":"k-451","title":"Dropping particle not wrapped in separate formatting element","description":"When dropping particles appear after the given name in inverted order, they should be wrapped in their own formatting element.\n\nExpected: `\u003ci\u003eGivenname\u003c/i\u003e \u003ci\u003eal\u003c/i\u003e`\nActual: `\u003ci\u003eGivenname al\u003c/i\u003e`\n\nThis affects name_ParticlesDemoteNonDroppingNever and similar tests. The Output AST structure is correct but formatting application needs refinement.\n\nDiscovered from: k-450","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-29T11:49:36.96274-06:00","updated_at":"2025-11-29T13:39:53.245554-06:00","closed_at":"2025-11-29T13:39:53.245554-06:00","dependencies":[{"issue_id":"k-451","depends_on_id":"k-450","type":"discovered-from","created_at":"2025-11-29T11:49:36.964627-06:00","created_by":"cscheid"}]} -{"id":"k-452","title":"initialize=false strips trailing periods from initials","description":"When initialize=\"false\" is set, existing periods in given names should be preserved but our implementation strips trailing periods.\n\nExpected: `M.E` → `M.E.` (adds period per initialize-with)\nActual: `M.E` → `M.E` (no trailing period)\n\nAlso affects space normalization:\nExpected: `M E` → `M.E.`\nActual: `M E` → `M E`\n\nAffects name_InitialsInitializeFalsePeriod and similar tests.\n\nDiscovered from: k-450","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-29T11:49:43.886941-06:00","updated_at":"2025-11-29T12:46:32.542137-06:00","closed_at":"2025-11-29T12:46:32.542137-06:00","dependencies":[{"issue_id":"k-452","depends_on_id":"k-450","type":"discovered-from","created_at":"2025-11-29T11:49:43.888389-06:00","created_by":"cscheid"}]} -{"id":"k-453","title":"Hyphenated given names produce extra initials","description":"When a given name is hyphenated (e.g., Guo-Ping), our implementation produces initials for each part (G-P) but some tests expect only the first initial (G).\n\nExpected: `Guo-Ping Chen` → `G Chen`\nActual: `Guo-Ping Chen` → `G-P Chen`\n\nAffects name_LowercaseSurnameSuffix and similar tests.\n\nDiscovered from: k-450","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-29T11:49:49.513744-06:00","updated_at":"2025-11-29T12:46:31.396474-06:00","closed_at":"2025-11-29T12:46:31.396474-06:00","dependencies":[{"issue_id":"k-453","depends_on_id":"k-450","type":"discovered-from","created_at":"2025-11-29T11:49:49.515949-06:00","created_by":"cscheid"}]} -{"id":"k-454","title":"Implement citation-label variable generation","description":"The `citation-label` variable is a special auto-generated variable used in Harvard-style citations. It produces labels like 'Doe65', 'RoNo78a' from author names + year.\n\n**Impact:** 5 test files use this feature, causing 4 tests to produce empty output (critical for MVP).\n\n**Tests affected:**\n- disambiguate_CitationLabelDefault\n- disambiguate_Trigraph\n- disambiguate_CitationLabelInData\n- magic_CitationLabelInCitation\n- magic_CitationLabelInBibliography\n\n**Reference:** Pandoc citeproc implementation in external-sources/citeproc/","notes":"Plan: claude-notes/plans/2025-11-29-citation-label-implementation.md\n\nImplementation approach: Compute on demand (Option A)\n- Add generate_citation_label() to Reference\n- Modify get_variable() to handle citation-label specially\n- Add year suffix integration in evaluate_text()\n\nKey algorithm:\n- 1 author: first 4 chars of family name\n- 2-3 authors: first 2 chars each\n- 4+ authors: first 1 char each (up to 4)\n- Plus 2-digit year\n\nEdge cases handled:\n- Particle stripping (von Dipheria -\u003e Dipheria -\u003e D)\n- Data override (use citation-label from CSL-JSON if present)\n- Year suffix appended during rendering","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-29T12:05:29.974234-06:00","updated_at":"2025-11-29T12:18:00.913473-06:00","closed_at":"2025-11-29T12:18:00.913473-06:00"} -{"id":"k-455","title":"Em-dash incorrectly forces title case capitalization","description":"In title case, em-dash and en-dash should be word breaks but NOT force capitalization of the next word. Currently treating them like sentence-ending punctuation. Test: textcase_titlewithemdash","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-11-29T14:03:57.410819-06:00","updated_at":"2025-11-29T14:12:02.663648-06:00","closed_at":"2025-11-29T14:12:02.663648-06:00","dependencies":[{"issue_id":"k-455","depends_on_id":"k-436","type":"discovered-from","created_at":"2025-11-29T14:03:57.412882-06:00","created_by":"cscheid"}]} -{"id":"k-456","title":"Curly apostrophe breaks words in title case","description":"Curly apostrophe (U+2019) incorrectly breaks words. 'Shafi'i' becomes 'Shafi'I' instead of 'Shafi'i'. The apostrophe should be treated as part of the word. Test: textcase_nospacebeforeapostrophe","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-11-29T14:04:03.620477-06:00","updated_at":"2025-11-29T14:12:03.427389-06:00","closed_at":"2025-11-29T14:12:03.427389-06:00","dependencies":[{"issue_id":"k-456","depends_on_id":"k-436","type":"discovered-from","created_at":"2025-11-29T14:04:03.622368-06:00","created_by":"cscheid"}]} -{"id":"k-457","title":"Fix page range en-dash formatting","description":"Page ranges should use en-dash (–) not hyphen (-). Affects 4 bugreports tests: contextualpluralwithmainitemfields, ieeepunctuation, numberinmacrowithverticalalign, parenthesis. See claude-notes/plans/2025-11-29-bugreports-analysis.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-29T15:01:34.223648-06:00","updated_at":"2025-11-29T15:11:31.817796-06:00","closed_at":"2025-11-29T15:11:31.817796-06:00","dependencies":[{"issue_id":"k-457","depends_on_id":"k-422","type":"parent-child","created_at":"2025-11-29T15:01:48.908306-06:00","created_by":"cscheid"}]} -{"id":"k-458","title":"Fix punctuation-in-quote handling","description":"Punctuation should move inside quotes when punctuation-in-quote is enabled. Affects 8 bugreports tests. See claude-notes/plans/2025-11-29-bugreports-analysis.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-29T15:01:38.740865-06:00","updated_at":"2025-11-29T15:27:52.875388-06:00","closed_at":"2025-11-29T15:27:52.875388-06:00","dependencies":[{"issue_id":"k-458","depends_on_id":"k-422","type":"parent-child","created_at":"2025-11-29T15:01:48.928659-06:00","created_by":"cscheid"}]} -{"id":"k-459","title":"Fix year-suffix disambiguation","description":"Year suffixes (a, b, c) not being assigned when disambiguating works by same author in same year. Affects 5 bugreports tests. See claude-notes/plans/2025-11-29-bugreports-analysis.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-29T15:01:43.32947-06:00","updated_at":"2025-11-29T17:22:58.185735-06:00","closed_at":"2025-11-29T17:22:58.185735-06:00","dependencies":[{"issue_id":"k-459","depends_on_id":"k-422","type":"parent-child","created_at":"2025-11-29T15:01:48.94731-06:00","created_by":"cscheid"}]} -{"id":"k-46","title":"Define MetaValueWithSourceInfo enum and supporting types","description":"Create new types in pandoc/meta.rs:\n- MetaValueWithSourceInfo enum (replacing MetaValue)\n- Each variant stores value + SourceInfo\n- MetaMap stores (key, key_source, value) tuples\n- Preserve all existing variant types (String, Bool, Inlines, Blocks, List, Map)\n\nAdd Serialize/Deserialize derives.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T09:07:35.507557-05:00","updated_at":"2025-10-19T09:13:21.64233-05:00","closed_at":"2025-10-19T09:13:21.64233-05:00","dependencies":[{"issue_id":"k-46","depends_on_id":"k-45","type":"parent-child","created_at":"2025-10-19T09:07:35.509301-05:00","created_by":"cscheid"}]} -{"id":"k-460","title":"Session handoff notes for year-suffix disambiguation work","description":"See claude-notes/plans/2025-11-29-session-handoff-notes.md for context on completed work (k-457, k-458) and preparation for k-459 (year-suffix disambiguation). Contains technical notes, affected tests, recommended approach, and useful commands.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-29T16:40:38.931936-06:00","updated_at":"2025-11-29T18:24:58.065969-06:00","closed_at":"2025-11-29T18:24:58.065969-06:00","dependencies":[{"issue_id":"k-460","depends_on_id":"k-459","type":"related","created_at":"2025-11-29T16:40:38.934448-06:00","created_by":"cscheid"}]} -{"id":"k-461","title":"Design subsequent-author-substitute for bibliography","description":"Design and implement subsequent-author-substitute feature for CSL bibliography rendering.\n\n**Current State:**\n- Tests failing: name_SubsequentAuthorSubstituteSingleField, name_SubsequentAuthorSubstituteMultipleNames\n- Feature replaces repeated author names with substitute string (typically '———')\n- Requires tracking state across bibliography entries\n\n**CSL Specification:**\n- subsequent-author-substitute attribute on bibliography element\n- subsequent-author-substitute-rule (complete-all, complete-each, partial-first, partial-each)\n- Only applies to bibliography, not citations\n\n**Required Investigation:**\n1. Read Pandoc's implementation in external-sources/citeproc/src/Citeproc/Eval.hs\n2. Understand how author identity is determined for substitution\n3. Design state management for cross-entry tracking\n4. Consider integration with existing bibliography rendering\n\n**Design Output:**\nCreate plan in claude-notes/plans/YYYY-MM-DD-subsequent-author-substitute-design.md\n\n**Parent:** k-410 (citeproc epic)","notes":"Design plan: claude-notes/plans/2025-12-01-subsequent-author-substitute-design.md","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-29T18:53:20.582841-06:00","updated_at":"2025-12-01T18:39:48.849997-06:00","dependencies":[{"issue_id":"k-461","depends_on_id":"k-410","type":"discovered-from","created_at":"2025-11-29T18:53:20.584884-06:00","created_by":"cscheid"}]} -{"id":"k-462","title":"Design citation collapsing feature","description":"Design and implement citation collapsing features for CSL citation rendering.\n\n**Current State:**\n- Tests failing: name_CiteGroupDelimiterWithYearSuffixCollapse, name_CiteGroupDelimiterWithYearSuffixCollapse3, name_CollapseRoleLabels\n- Multiple collapse modes: year, year-suffix, year-suffix-ranged, citation-number\n- Requires post-processing of rendered citations\n\n**CSL Specification:**\n- collapse attribute on citation element\n- cite-group-delimiter for separator between collapsed cites\n- Interacts with year-suffix disambiguation\n\n**Required Investigation:**\n1. Read Pandoc's implementation of collapse in external-sources/citeproc/src/Citeproc/Eval.hs\n2. Understand how citation groups are identified for collapse\n3. Design the post-processing phase for collapse\n4. Consider year-suffix-ranged mode (1998a-c)\n\n**Design Output:**\nCreate plan in claude-notes/plans/YYYY-MM-DD-citation-collapsing-design.md\n\n**Parent:** k-410 (citeproc epic)","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-29T18:53:29.078041-06:00","updated_at":"2025-12-01T18:39:39.256509-06:00","dependencies":[{"issue_id":"k-462","depends_on_id":"k-410","type":"discovered-from","created_at":"2025-11-29T18:53:29.080026-06:00","created_by":"cscheid"}]} -{"id":"k-463","title":"Investigate and fix substitute mechanism","description":"Investigate the substitute mechanism implementation - multiple tests fail due to substitute behavior.\n\n**Failing Tests (5+):**\n- name_LabelFormatBug - label not rendering with substitute\n- name_SubstituteInheritLabel - label inheritance in substitute\n- name_QuashOrdinaryVariableRenderedViaSubstitute - variable suppression\n- name_SubstituteOnNamesSpanGroupSpanFail - group span interaction\n- name_SubstitutePartialEach - partial substitution\n\n**Symptoms:**\n- Labels not rendered when substitute activates\n- Label formatting not inherited properly\n- Variable suppression not working correctly\n\n**Required Investigation:**\n1. Read Pandoc's substitute implementation in external-sources/citeproc/src/Citeproc/Eval.hs\n2. Compare our substitute handling in evaluate_names()\n3. Understand label inheritance rules in substitute context\n4. Identify gaps in current implementation\n\n**Priority:** High - this blocks multiple tests and is a core CSL feature\n\n**Parent:** k-410 (citeproc epic)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-29T18:53:39.692983-06:00","updated_at":"2025-11-30T09:28:19.259304-06:00","closed_at":"2025-11-30T09:28:19.259304-06:00","dependencies":[{"issue_id":"k-463","depends_on_id":"k-410","type":"discovered-from","created_at":"2025-11-29T18:53:39.694391-06:00","created_by":"cscheid"}]} -{"id":"k-464","title":"Enhance particle extraction for punctuation-connected particles","description":"Enhance the extract_particles() function in reference.rs to handle particles connected by punctuation (apostrophes, hyphens, en-dashes).\n\n**Plan document:** claude-notes/plans/2025-11-30-particle-extraction-enhancement.md\n\n**Failing tests to unblock:**\n- name_ParsedDroppingParticleWithApostrophe\n- name_ParsedNonDroppingParticleWithApostrophe \n- name_HyphenatedNonDroppingParticle1\n- name_HyphenatedNonDroppingParticle2\n\n**Current behavior:** Only space-separated particles are extracted\n**Required:** Extract punctuation-connected particles like \"d'\" from \"d'Aubignac\" and \"al-\" from \"al-One\"\n\n**Reference:** Haskell citeproc Types.hs:1241-1281 (extractParticles function)\n\n**Parent:** k-410 (citeproc epic)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-30T11:12:31.104088-06:00","updated_at":"2025-11-30T11:30:20.907173-06:00","closed_at":"2025-11-30T11:30:20.907173-06:00","dependencies":[{"issue_id":"k-464","depends_on_id":"k-410","type":"parent-child","created_at":"2025-11-30T11:12:35.779048-06:00","created_by":"cscheid"}]} -{"id":"k-465","title":"CSL: Implement affixesInside flag for proper suffix placement","description":"Suffixes appear inside formatting instead of outside. Need to implement formatAffixesInside flag like Pandoc citeproc. Blocks flipflop_ItalicsWithOk, flipflop_ItalicsWithOkAndTextcase. See claude-notes/plans/2025-11-30-flipflop-remaining-blockers.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-30T12:26:59.762236-06:00","updated_at":"2025-11-30T13:05:57.671644-06:00","closed_at":"2025-11-30T13:05:57.671644-06:00","dependencies":[{"issue_id":"k-465","depends_on_id":"k-432","type":"discovered-from","created_at":"2025-11-30T12:27:29.824864-06:00","created_by":"cscheid"}]} -{"id":"k-466","title":"CSL: Parse HTML entities as markup in text values","description":"HTML entities in \u003ctext value=\"...\"/\u003e should be unescaped and interpreted as markup. Currently \u0026#60;b\u0026#62; is output literally instead of being parsed as \u003cb\u003e. Blocks flipflop_BoldfaceNodeLevelMarkup. See claude-notes/plans/2025-11-30-flipflop-remaining-blockers.md","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-11-30T12:27:09.57592-06:00","updated_at":"2025-11-30T12:37:17.862362-06:00","closed_at":"2025-11-30T12:37:17.862362-06:00","dependencies":[{"issue_id":"k-466","depends_on_id":"k-432","type":"discovered-from","created_at":"2025-11-30T12:27:29.847134-06:00","created_by":"cscheid"}]} -{"id":"k-467","title":"CSL: Smart quote and apostrophe handling in rich text","description":"Quote and apostrophe handling isn't working correctly inside markup tags. Need smart quote conversion, locale-aware quote styles, and apostrophe vs single quote distinction. Blocks flipflop_ApostropheInsideTag, flipflop_QuotesNodeLevelMarkup, flipflop_QuotesInFieldNotOnNode, flipflop_OrphanQuote, flipflop_SingleBeforeColon. See claude-notes/plans/2025-11-30-flipflop-remaining-blockers.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-30T12:27:20.024461-06:00","updated_at":"2025-11-30T12:50:15.848404-06:00","closed_at":"2025-11-30T12:50:15.848404-06:00","dependencies":[{"issue_id":"k-467","depends_on_id":"k-432","type":"discovered-from","created_at":"2025-11-30T12:27:29.865916-06:00","created_by":"cscheid"}]} -{"id":"k-468","title":"CSL: text-case transformation should not affect nodecor content","description":"In flipflop_ItalicsWithOkAndTextcase, content inside a nodecor span (font-variant:normal) is incorrectly affected by the outer text-case=capitalize-all transformation. Expected: 'v.' (lowercase), Actual: 'V.' (uppercase). The nodecor mechanism should protect content from text-case transformations.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-30T13:06:06.034219-06:00","updated_at":"2025-11-30T13:45:15.789582-06:00","closed_at":"2025-11-30T13:45:15.789582-06:00","dependencies":[{"issue_id":"k-468","depends_on_id":"k-465","type":"discovered-from","created_at":"2025-11-30T13:06:06.036519-06:00","created_by":"cscheid"}]} -{"id":"k-469","title":"Phase 1: Core Lua filter types and infrastructure","description":"Foundation for Lua filter support. See claude-notes/plans/2025-12-02-mlua-analysis.md\n\nTasks:\n- Add mlua optional dependency to Cargo.toml with `lua-filter` feature\n- Create `src/lua/mod.rs` module structure (behind `#[cfg(feature = \"lua-filter\")]`)\n- Implement `LuaInline` wrapper with basic fields\n- Implement `LuaBlock` wrapper with basic fields\n- Support common types: Str, Para, Header, Link, Emph, Strong\n- Implement constructors: `pandoc.Str()`, `pandoc.Para()`, etc.\n- Basic typewise traversal\n- Add `--lua-filter` CLI argument (behind feature flag)\n- Test with simple filter (uppercase Str elements)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-02T11:53:17.350115-06:00","updated_at":"2025-12-02T12:12:17.89629-06:00","closed_at":"2025-12-02T12:12:17.89629-06:00","dependencies":[{"issue_id":"k-469","depends_on_id":"k-409","type":"blocks","created_at":"2025-12-02T11:53:17.352066-06:00","created_by":"cscheid"}]} -{"id":"k-47","title":"Implement yaml_to_meta_with_source_info transformation","description":"Implement transformation function in pandoc/meta.rs:\n- Takes YamlWithSourceInfo → returns MetaValueWithSourceInfo\n- Parse YAML strings as Markdown (creating Substring SourceInfos)\n- Handle all YAML types (String, Bool, Hash, Array)\n- Recognize special YAML tags\n- Preserve source tracking through nested structures\n\nThis is the core logic that enriches YAML with Markdown parsing while maintaining source locations.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T09:07:37.662896-05:00","updated_at":"2025-10-19T09:17:44.723311-05:00","closed_at":"2025-10-19T09:17:44.723311-05:00","dependencies":[{"issue_id":"k-47","depends_on_id":"k-45","type":"parent-child","created_at":"2025-10-19T09:07:37.664209-05:00","created_by":"cscheid"},{"issue_id":"k-47","depends_on_id":"k-46","type":"blocks","created_at":"2025-10-19T09:07:37.664926-05:00","created_by":"cscheid"}]} -{"id":"k-470","title":"Phase 2: Complete Lua filter element coverage","description":"Complete element field coverage for Lua filters. See claude-notes/plans/2025-12-02-mlua-analysis.md\n\nTasks:\n- All inline element fields\n- All block element fields\n- Meta value handling\n- Attr (attributes) with special access patterns (userdata, not simplified tables)\n - `attr.identifier` - string\n - `attr.classes` - list of strings\n - `attr.attributes` - key-value pairs\n - Positional access: `attr[1]`, `attr[2]`, `attr[3]`\n - Constructor: `pandoc.Attr(id, classes, attrs)`\n- List splicing semantics","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-02T11:53:25.362528-06:00","updated_at":"2025-12-02T12:32:20.722738-06:00","closed_at":"2025-12-02T12:32:20.722738-06:00","dependencies":[{"issue_id":"k-470","depends_on_id":"k-469","type":"blocks","created_at":"2025-12-02T11:53:25.364013-06:00","created_by":"cscheid"}]} -{"id":"k-471","title":"Phase 3: Lua filter methods and traversal","description":"Methods and traversal modes for Lua filters. See claude-notes/plans/2025-12-02-mlua-analysis.md\n\nTasks:\n- `clone()` method on elements\n- `walk()` method (REQUIRED - too important for practical filters)\n - Must support AST traversal with Lua callback functions\n - Used extensively in real-world filters\n- `pairs()` iteration\n- Topdown traversal mode\n- Global variables (FORMAT, PANDOC_VERSION, etc.)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-02T11:53:31.360707-06:00","updated_at":"2025-12-02T12:56:21.923872-06:00","closed_at":"2025-12-02T12:56:21.923872-06:00","dependencies":[{"issue_id":"k-471","depends_on_id":"k-470","type":"blocks","created_at":"2025-12-02T11:53:31.362165-06:00","created_by":"cscheid"}]} -{"id":"k-472","title":"Phase 4: Lua filter diagnostics and utilities","description":"Diagnostics and utility functions for Lua filters. See claude-notes/plans/2025-12-02-mlua-analysis.md\n\nTasks:\n- Filter provenance tracking (REQUIRED for diagnostic messages)\n - Capture source file and line from Lua `debug.getinfo()`\n - Store in wrapper types as `SourceInfo::FilterProvenance`\n - Report in error messages when filter-created elements cause issues\n- `pandoc.utils.stringify()`\n- Additional `pandoc.utils.*` functions as needed\n- Performance optimization","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-02T11:53:37.972187-06:00","updated_at":"2025-12-02T15:05:14.135869-06:00","closed_at":"2025-12-02T15:05:14.135869-06:00","dependencies":[{"issue_id":"k-472","depends_on_id":"k-471","type":"blocks","created_at":"2025-12-02T11:53:37.973494-06:00","created_by":"cscheid"}]} -{"id":"k-473","title":"Lua API Port: Design and implement Pandoc Lua API for quarto-markdown-pandoc","description":"Design and implement the Pandoc Lua API for our Rust-based Lua filter subsystem. This includes element constructors, utility modules (pandoc.utils, pandoc.text, pandoc.path, pandoc.system, etc.), List type, and related infrastructure. See plan: claude-notes/plans/2025-12-02-lua-api-port-plan.md","status":"open","priority":1,"issue_type":"epic","created_at":"2025-12-02T16:14:30.67219-06:00","updated_at":"2025-12-02T16:14:30.67219-06:00","dependencies":[{"issue_id":"k-473","depends_on_id":"k-409","type":"related","created_at":"2025-12-02T16:14:37.851152-06:00","created_by":"cscheid"}]} -{"id":"k-474","title":"Lua API: Implement List/Blocks/Inlines metatable system","description":"Implement the pandoc.List type and specialized Blocks/Inlines metatables. Lists are regular Lua tables with metatables providing methods like clone(), extend(), filter(), find(), map(), etc. Inlines/Blocks extend List with walk() and serialization. See plan: claude-notes/plans/2025-12-02-lua-api-port-plan.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-02T16:33:28.276144-06:00","updated_at":"2025-12-02T16:53:10.573147-06:00","closed_at":"2025-12-02T16:53:10.573147-06:00","dependencies":[{"issue_id":"k-474","depends_on_id":"k-409","type":"blocks","created_at":"2025-12-02T16:33:28.279319-06:00","created_by":"cscheid"}]} -{"id":"k-475","title":"Lua API: Design and implement LuaRuntime abstraction layer","description":"Design dependency injection pattern for runtime operations (file I/O, network, environment) to support native, WASM/Emscripten, and sandboxed execution contexts. Trait-based design allows different implementations per target. See plan: claude-notes/plans/2025-12-02-lua-api-port-plan.md","notes":"Design document: claude-notes/plans/2025-12-03-lua-runtime-abstraction-layer.md\n\n## Key Design Decisions\n\nModeled after Deno's permission system (https://docs.deno.com/runtime/fundamentals/security/):\n\n### SecurityPolicy Structure (Deno-aligned)\n- `allow_read` / `deny_read` - File read paths (like --allow-read)\n- `allow_write` / `deny_write` - File write paths (like --allow-write)\n- `allow_net` / `deny_net` - Network hosts (like --allow-net)\n- `allow_run` / `deny_run` - Programs to execute (like --allow-run)\n- `allow_env` / `deny_env` - Environment variables (like --allow-env)\n- `allow_cwd` - CWD operations (grouped with env, like Deno's chdir)\n- `allow_sys` - System info APIs (like --allow-sys)\n\n### Resolved Design Questions\n1. **CWD handling**: Part of 'env' category; allow in native, deny in WASM, flag in sandboxed\n2. **Async network**: Design for blocking now, note async as future consideration\n3. **Module loading**: `require()` subject to file read permissions\n4. **Error messages**: Detailed, actionable messages (Deno pattern)\n\n### Key Patterns\n- Deny takes precedence over allow (Deno pattern)\n- Path wildcards supported (like `/home/user/*`)\n- Env var suffix wildcards (like `AWS_*`)\n- Replace Lua io/os modules with runtime-controlled versions\n\n### Industry Research\n- Deno: Mature model, full adoption of their patterns\n- Node.js: Permission model in v23.5+, simpler than Deno\n- Bun: No permission model yet (open issue #6617)","status":"open","priority":4,"issue_type":"feature","created_at":"2025-12-02T16:33:29.275099-06:00","updated_at":"2025-12-04T08:29:40.472449-06:00","dependencies":[{"issue_id":"k-475","depends_on_id":"k-409","type":"blocks","created_at":"2025-12-02T16:33:29.276524-06:00","created_by":"cscheid"}]} -{"id":"k-476","title":"Lua API: Integrate quarto-citeproc with pandoc.utils.citeproc","description":"Connect quarto-citeproc Processor to Lua API via pandoc.utils.citeproc(doc). Needs to extract references/CSL from metadata, process citations, replace Cite elements, and add bibliography. See plan: claude-notes/plans/2025-12-02-lua-api-port-plan.md","status":"open","priority":1,"issue_type":"feature","created_at":"2025-12-02T16:33:30.243699-06:00","updated_at":"2025-12-02T16:33:30.243699-06:00","dependencies":[{"issue_id":"k-476","depends_on_id":"k-409","type":"blocks","created_at":"2025-12-02T16:33:30.245801-06:00","created_by":"cscheid"},{"issue_id":"k-476","depends_on_id":"k-490","type":"related","created_at":"2025-12-03T16:57:20.749076-06:00","created_by":"cscheid"}]} -{"id":"k-477","title":"Investigate Lua filter traversal order (typewise multi-pass)","description":"Our current Lua filter implementation uses a single bottom-up pass, but Pandoc's typewise traversal does multiple passes:\n\n1. First pass: ALL inline elements (Str, Emph, etc. + Inline fallback)\n2. Then: Inlines list filter\n3. Second pass: ALL block elements (Para, Header, etc. + Block fallback)\n4. Then: Blocks list filter\n5. Finally: Meta, then Pandoc\n\n**Current behavior (filter.rs):**\n- For each block, we process its inline children, then the block itself\n- This is bottom-up within a single traversal\n\n**Pandoc behavior (documented):**\n- \"Lua filter functions are run in the order: Inlines → Blocks → Meta → Pandoc\"\n- This suggests multiple passes over the document\n\n**Tasks:**\n1. Study Pandoc's Haskell source to understand exact traversal semantics\n2. Write test cases comparing our output to Pandoc's for filters that depend on traversal order\n3. Determine if the difference matters in practice\n4. If needed, implement multi-pass traversal to match Pandoc\n\n**Key files:**\n- crates/quarto-markdown-pandoc/src/lua/filter.rs (apply_filter_to_block, apply_filter_to_inlines)\n- crates/quarto-markdown-pandoc/src/lua/types.rs (walk_blocks_with_filter, walk_inlines_with_filter)\n\n**Also verify:**\n- Generic Inline/Block fallback priority (type-specific should win)\n- Add tests for these behaviors","notes":"Plan document: claude-notes/plans/2025-12-02-lua-filter-traversal-fix.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-02T17:42:18.469344-06:00","updated_at":"2025-12-03T09:18:30.243945-06:00","closed_at":"2025-12-03T09:18:30.243945-06:00","dependencies":[{"issue_id":"k-477","depends_on_id":"k-409","type":"discovered-from","created_at":"2025-12-02T17:42:18.471315-06:00","created_by":"cscheid"}]} -{"id":"k-478","title":"Implement topdown traversal with stop signal for Lua filters","description":"Implement topdown traversal mode for Lua filters. When a filter sets traverse='topdown', the filter should process parents before children in a depth-first manner. Additionally, filters can return (element, false) to stop descent into children. This matches Pandoc's WalkTopdown behavior.","notes":"Plan: claude-notes/plans/2025-12-02-topdown-traversal.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-02T19:31:50.336579-06:00","updated_at":"2025-12-02T19:48:57.671782-06:00","closed_at":"2025-12-02T19:48:57.671782-06:00","dependencies":[{"issue_id":"k-478","depends_on_id":"k-477","type":"discovered-from","created_at":"2025-12-02T19:31:50.339484-06:00","created_by":"cscheid"}]} -{"id":"k-479","title":"Update elem:walk{} to use correct four-pass traversal","description":"The walk methods in types.rs (walk_inlines_with_filter, walk_blocks_with_filter) used by elem:walk{} should use the same four-pass traversal as document-level filtering. Currently they interleave passes incorrectly. They should also support topdown traversal with stop signal when traverse='topdown' is set.","notes":"Plan: claude-notes/plans/2025-12-02-elem-walk-fix.md\n\nDepends on: k-478 (topdown traversal implementation)","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-02T19:31:57.855494-06:00","updated_at":"2025-12-03T09:18:31.00601-06:00","closed_at":"2025-12-03T09:18:31.00601-06:00","dependencies":[{"issue_id":"k-479","depends_on_id":"k-477","type":"discovered-from","created_at":"2025-12-02T19:31:57.856856-06:00","created_by":"cscheid"},{"issue_id":"k-479","depends_on_id":"k-478","type":"blocks","created_at":"2025-12-02T19:35:21.163729-06:00","created_by":"cscheid"}]} -{"id":"k-48","title":"Update rawblock_to_meta to use quarto-yaml","description":"Replace yaml-rust2 usage with quarto_yaml in rawblock_to_meta():\n- Use quarto_yaml::parse_with_parent() instead of yaml-rust2 Parser\n- Create parent SourceInfo from RawBlock\n- Create Substring SourceInfo for YAML content within frontmatter\n- Call yaml_to_meta_with_source_info() to get MetaValueWithSourceInfo\n- Return the new type\n\nThis integrates quarto-yaml into the metadata parsing pipeline.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T09:07:39.959315-05:00","updated_at":"2025-10-19T09:24:09.733868-05:00","closed_at":"2025-10-19T09:24:09.733868-05:00","dependencies":[{"issue_id":"k-48","depends_on_id":"k-45","type":"parent-child","created_at":"2025-10-19T09:07:39.961417-05:00","created_by":"cscheid"},{"issue_id":"k-48","depends_on_id":"k-47","type":"blocks","created_at":"2025-10-19T09:07:39.962334-05:00","created_by":"cscheid"}]} -{"id":"k-480","title":"Implement quarto.warn() and quarto.error() Lua functions","description":"Implement Lua functions that allow filter authors to emit diagnostic messages (warnings and errors) during filter execution.\n\n**Summary:**\n- Add `quarto.warn(message [, element])` function\n- Add `quarto.error(message [, element])` function\n- Diagnostics are stored in a hidden Lua table during execution\n- After filter execution, diagnostics are extracted and returned to Rust\n- Source locations captured automatically from Lua stack or from AST element\n\n**Key Files to Create/Modify:**\n- Create: `src/lua/diagnostics.rs` - Core diagnostic functions\n- Modify: `src/lua/mod.rs` - Add module export\n- Modify: `src/lua/constructors.rs` - Register functions\n- Modify: `src/lua/filter.rs` - Update return types, extract diagnostics\n- Create: Test files for the new functionality\n\n**Design plan:** claude-notes/plans/2025-12-03-lua-filter-diagnostics-implementation.md\n\n**Related analysis:** claude-notes/plans/2025-12-02-filter-diagnostics-analysis.md","notes":"Updated plan to include Phase 4: LuaLS Documentation. See claude-notes/plans/2025-12-03-lua-filter-diagnostics-implementation.md for full details including LuaLS annotation format reference.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-03T09:27:21.250737-06:00","updated_at":"2025-12-03T09:53:30.532131-06:00","closed_at":"2025-12-03T09:53:30.532131-06:00","dependencies":[{"issue_id":"k-480","depends_on_id":"k-409","type":"discovered-from","created_at":"2025-12-03T09:27:21.253611-06:00","created_by":"cscheid"}]} -{"id":"k-481","title":"quarto.warn/error element location doesn't work for original document elements","description":"## Problem\n\nThe `quarto.warn(msg, elem)` and `quarto.error(msg, elem)` functions accept an optional AST element to attach source location information. However, this only works for elements **created by filters** (which have `FilterProvenance` source info), not elements **from the original document** (which have `SourceInfo::Original`).\n\nThis is a significant limitation because user-provided filters that want to act as linters cannot report warnings/errors about specific locations in the source document - they can only report the filter's own location.\n\n## Root Cause\n\nIn `src/lua/diagnostics.rs`, the `source_info_to_path_line` function (lines 208-218) only handles `FilterProvenance`:\n\n```rust\nfn source_info_to_path_line(source_info: \u0026SourceInfo) -\u003e Option\u003c(String, i64)\u003e {\n match source_info {\n SourceInfo::FilterProvenance { filter_path, line } =\u003e {\n Some((filter_path.clone(), *line as i64))\n }\n // For Original source info, we don't have easy access to the filename\n // without a SourceContext. For now, return None to fall back to stack.\n _ =\u003e None,\n }\n}\n```\n\nFor `SourceInfo::Original`, we need access to `SourceContext` to:\n1. Look up the `FileId` to get the filename\n2. Map byte offsets to line/column numbers\n\nThe `SourceContext` is available in `ASTContext` but is not currently passed to the Lua diagnostic functions.\n\n## How to Test\n\nCreate a test filter `linter.lua`:\n```lua\nfunction Str(elem)\n if elem.text:match('TODO') then\n quarto.warn('Found TODO in document', elem)\n end\n return elem\nend\n```\n\nCreate a test document `test.qmd`:\n```markdown\nThis has a TODO item.\n```\n\nRun:\n```bash\ncargo run -- -L linter.lua -i test.qmd -t native\n```\n\n**Expected**: Warning shows location in `test.qmd` (line 1, around column 12)\n**Actual**: Warning shows location in `linter.lua` (line 3, the quarto.warn call)\n\n## Potential Solutions\n\n1. **Pass ASTContext to Lua state**: Store `ASTContext` (or at least `SourceContext`) in the Lua registry so diagnostic functions can access it\n2. **Thread-local context**: Use a thread-local to store context during filter execution\n3. **Closure capture**: Capture context in the Lua function closures created in `register_quarto_namespace`\n\nOption 1 or 3 seems cleanest. The context would need to be set before filter execution and cleared after.\n\n## Related\n\n- Parent issue: k-480 (Implement quarto.warn/error Lua functions)\n- Plan: claude-notes/plans/2025-12-03-lua-filter-diagnostics-implementation.md\n- Discussion: Element location extraction was identified as incomplete during implementation review","notes":"Plan document: claude-notes/plans/2025-12-03-k481-source-location-resolution.md\n\nFINAL APPROACH: Store SourceInfo as Lua table (not userdata)\n\nWhy not userdata?\n- In Pandoc, userdata = AST nodes. Filters may use type(x)=='userdata' to identify elements.\n- Using userdata for non-AST data could cause Pandoc compatibility issues.\n\nWhy not thread-local IDs? \n- If diagnostic entries are serialized, IDs become meaningless.\n\nSolution: Serialize SourceInfo to plain Lua table, deserialize on extraction.\n\nLua table format:\n { t = 'Original', file_id = 0, start_offset = 42, end_offset = 55 }\n { t = 'Substring', parent = {...}, start_offset = 10, end_offset = 20 }\n { t = 'FilterProvenance', filter_path = '...', line = 42 }\n\nChanges needed in diagnostics.rs:\n1. Add source_info_to_lua_table() and source_info_from_lua_table()\n2. Update add_diagnostic() to store serialized SourceInfo\n3. Update extract_lua_diagnostics() to deserialize and pass to builder\n4. Remove obsolete resolution functions\n\nBenefits:\n- No SourceContext needed in Lua\n- Pure Lua tables (Pandoc-compatible)\n- Serialization-safe\n- Resolution stays in Rust","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-03T09:58:47.930405-06:00","updated_at":"2025-12-03T10:57:39.45095-06:00","closed_at":"2025-12-03T10:57:39.45095-06:00","dependencies":[{"issue_id":"k-481","depends_on_id":"k-480","type":"discovered-from","created_at":"2025-12-03T09:58:47.933174-06:00","created_by":"cscheid"}]} -{"id":"k-482","title":"LuaRuntime trait definition and module structure","description":"Create the runtime abstraction layer module structure and trait definition:\n- Create lua/runtime/ module with mod.rs, traits.rs\n- Define LuaRuntime trait with all methods from design doc\n- Define supporting types (RuntimeResult, RuntimeError, PathKind, PathMetadata, CommandOutput, XdgDirKind, TempDir)\n- Re-export from lua/runtime/mod.rs\n\nDesign doc: claude-notes/plans/2025-12-03-lua-runtime-abstraction-layer.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-03T13:15:56.414019-06:00","updated_at":"2025-12-03T13:25:57.044049-06:00","closed_at":"2025-12-03T13:25:57.044049-06:00","dependencies":[{"issue_id":"k-482","depends_on_id":"k-475","type":"blocks","created_at":"2025-12-03T13:15:56.419898-06:00","created_by":"cscheid"}]} -{"id":"k-483","title":"Implement NativeRuntime for Lua filters","description":"Implement NativeRuntime in lua/runtime/native.rs:\n- Use std::fs for file operations\n- Use std::process for command execution\n- Use std::env for environment access\n- Implement all LuaRuntime trait methods\n- Add comprehensive tests\n\nThis is the default runtime for native targets with full system access.\n\nDesign doc: claude-notes/plans/2025-12-03-lua-runtime-abstraction-layer.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-03T13:16:03.509818-06:00","updated_at":"2025-12-03T13:25:58.186288-06:00","closed_at":"2025-12-03T13:25:58.186288-06:00","dependencies":[{"issue_id":"k-483","depends_on_id":"k-482","type":"blocks","created_at":"2025-12-03T13:16:03.511352-06:00","created_by":"cscheid"}]} -{"id":"k-484","title":"Implement WasmRuntime for browser execution","description":"Implement WasmRuntime in lua/runtime/wasm.rs:\n- Use VirtualFileSystem for file operations (mediabag + in-memory)\n- Return NotSupported for process execution\n- Use fetch() API for network (blocking wrapper)\n- Return empty/None for environment access\n- Return NotSupported for CWD operations\n- Conditional compilation: #[cfg(target_arch = \"wasm32\")]\n\nThis runtime enables Lua filter execution in browser environments.\n\nDesign doc: claude-notes/plans/2025-12-03-lua-runtime-abstraction-layer.md","status":"open","priority":4,"issue_type":"task","created_at":"2025-12-03T13:16:10.892738-06:00","updated_at":"2025-12-04T08:29:23.938869-06:00","dependencies":[{"issue_id":"k-484","depends_on_id":"k-482","type":"blocks","created_at":"2025-12-03T13:16:10.894479-06:00","created_by":"cscheid"}]} -{"id":"k-485","title":"Implement SandboxedRuntime for untrusted filters","description":"Implement SandboxedRuntime in lua/runtime/sandbox.rs:\n- Decorator pattern wrapping any LuaRuntime\n- SecurityPolicy with Deno-style permission model:\n - allow_read/deny_read with PathPattern\n - allow_write/deny_write with PathPattern\n - allow_net/deny_net for network hosts\n - allow_run/deny_run for programs\n - allow_env/deny_env for environment variables\n - allow_cwd for CWD operations\n - allow_sys for system info\n- Deny takes precedence over allow\n- Detailed error messages (PermissionError)\n- PathPattern with wildcard support\n\nDesign doc: claude-notes/plans/2025-12-03-lua-runtime-abstraction-layer.md","status":"open","priority":4,"issue_type":"task","created_at":"2025-12-03T13:16:21.570538-06:00","updated_at":"2025-12-04T08:29:29.166127-06:00","dependencies":[{"issue_id":"k-485","depends_on_id":"k-482","type":"blocks","created_at":"2025-12-03T13:16:21.572017-06:00","created_by":"cscheid"}]} -{"id":"k-486","title":"Phase 1: List Infrastructure \u0026 Missing Constructors","description":"Complete the element type system:\n- Missing constructors: Cite, Table, TableHead, TableBody, TableFoot, Row, Cell, DefinitionList, LineBlock, Figure, Caption, ListAttributes, Citation\n- List metatable enhancements if needed\n\nPlan: claude-notes/plans/2025-12-02-lua-api-port-plan.md (Phase 1)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-03T13:48:18.855571-06:00","updated_at":"2025-12-03T14:04:08.541192-06:00","closed_at":"2025-12-03T14:04:08.541192-06:00","dependencies":[{"issue_id":"k-486","depends_on_id":"k-473","type":"blocks","created_at":"2025-12-03T13:48:18.858647-06:00","created_by":"cscheid"}]} -{"id":"k-487","title":"Phase 2: Core Utility Modules","description":"Essential utilities for most filters:\n- pandoc.utils expansion: blocks_to_inlines, equals, type, sha1, normalize_date\n- pandoc.text: lower, upper, len, sub (Unicode-aware)\n- pandoc.json: decode, encode\n\nPlan: claude-notes/plans/2025-12-02-lua-api-port-plan.md (Phase 2)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-03T13:48:33.315556-06:00","updated_at":"2025-12-03T16:19:54.038912-06:00","closed_at":"2025-12-03T16:19:54.038912-06:00","dependencies":[{"issue_id":"k-487","depends_on_id":"k-486","type":"blocks","created_at":"2025-12-03T13:48:33.317131-06:00","created_by":"cscheid"}]} -{"id":"k-488","title":"Phase 3: Runtime Abstraction \u0026 System Modules","description":"Cross-platform runtime support:\n- pandoc.path: all path manipulation functions via LuaRuntime\n- pandoc.system: file operations, process execution, environment via LuaRuntime\n- Integration with existing LuaRuntime infrastructure\n\nPlan: claude-notes/plans/2025-12-02-lua-api-port-plan.md (Phase 3)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-03T13:48:34.329264-06:00","updated_at":"2025-12-03T16:36:56.224766-06:00","closed_at":"2025-12-03T16:36:56.224766-06:00","dependencies":[{"issue_id":"k-488","depends_on_id":"k-487","type":"blocks","created_at":"2025-12-03T13:48:34.330574-06:00","created_by":"cscheid"}]} -{"id":"k-489","title":"Phase 4: MediaBag \u0026 Network","description":"Media and network handling:\n- pandoc.mediabag: all functions (delete, empty, fetch, fill, insert, items, list, lookup, make_data_uri, write)\n- WasmRuntime implementation (conditional)\n\nPlan: claude-notes/plans/2025-12-02-lua-api-port-plan.md (Phase 4)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-03T13:48:35.834169-06:00","updated_at":"2025-12-03T16:52:45.423477-06:00","closed_at":"2025-12-03T16:52:45.423477-06:00","dependencies":[{"issue_id":"k-489","depends_on_id":"k-488","type":"blocks","created_at":"2025-12-03T13:48:35.836097-06:00","created_by":"cscheid"}]} -{"id":"k-49","title":"Update PandocAST to use MetaWithSourceInfo","description":"Update Pandoc struct and related code:\n- Change Pandoc.meta from Meta to MetaWithSourceInfo\n- Update all code that constructs Pandoc instances\n- Update filters that traverse/modify metadata\n- Ensure backward compatibility where possible\n\nThis may touch multiple files (readers, writers, filters).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T09:07:42.175901-05:00","updated_at":"2025-10-19T11:04:06.866105-05:00","closed_at":"2025-10-19T11:04:06.866105-05:00","dependencies":[{"issue_id":"k-49","depends_on_id":"k-45","type":"parent-child","created_at":"2025-10-19T09:07:42.177385-05:00","created_by":"cscheid"},{"issue_id":"k-49","depends_on_id":"k-48","type":"blocks","created_at":"2025-10-19T09:07:42.178171-05:00","created_by":"cscheid"}]} -{"id":"k-490","title":"Phase 5: Citeproc Integration","description":"Citation processing:\n- pandoc.utils.citeproc: Full document processing\n- pandoc.utils.references: Extract references from doc\n- Integration with quarto-citeproc crate\n\nPlan: claude-notes/plans/2025-12-02-lua-api-port-plan.md (Phase 5)","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-03T13:48:36.751574-06:00","updated_at":"2025-12-03T13:48:36.751574-06:00","dependencies":[{"issue_id":"k-490","depends_on_id":"k-489","type":"blocks","created_at":"2025-12-03T13:48:36.753008-06:00","created_by":"cscheid"}]} -{"id":"k-491","title":"Phase 6: Reader/Writer","description":"Full API parity:\n- pandoc.read: Format parsing\n- pandoc.write: Format rendering\n- pandoc.template: Template processing\n- pandoc.layout: Custom writer support\n- pandoc.zip: Archive handling\n\nPlan: claude-notes/plans/2025-12-02-lua-api-port-plan.md (Phase 6)","notes":"Design plan: claude-notes/plans/2025-12-03-reader-writer-options-design.md\n\nKey decisions to discuss:\n1. Which reader/writer options to implement initially (recommend minimal set)\n2. How to handle format-specific options (store all, implement as needed)\n3. Whether extensions should affect parsing (recommend: no, for now)\n4. Which formats pandoc.read/write should support (qmd, json, html initially)","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-03T13:48:38.265989-06:00","updated_at":"2025-12-03T17:07:51.384615-06:00","dependencies":[{"issue_id":"k-491","depends_on_id":"k-490","type":"blocks","created_at":"2025-12-03T13:48:38.267432-06:00","created_by":"cscheid"}]} -{"id":"k-492","title":"Phase 7: Template, Layout \u0026 Zip","description":"Advanced utilities:\n- pandoc.template: Template processing\n- pandoc.layout: Custom writer support\n- pandoc.zip: Archive handling\n\nPlan: claude-notes/plans/2025-12-02-lua-api-port-plan.md","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-03T16:59:12.611465-06:00","updated_at":"2025-12-03T16:59:12.611465-06:00","dependencies":[{"issue_id":"k-492","depends_on_id":"k-491","type":"blocks","created_at":"2025-12-03T16:59:12.61283-06:00","created_by":"cscheid"}]} -{"id":"k-4csc","title":"Plan: Lua filter integration tests for types.rs coverage","description":"Plan document: claude-notes/plans/2026-01-02-lua-types-integration-tests.md\n\nSession baseline: 75.81% overall, lua/types.rs at 44.56%\n\nPlan covers 7 phases of integration tests targeting ~680 lines, estimated to improve types.rs coverage to ~78%.","status":"in_progress","priority":2,"issue_type":"task","created_at":"2026-01-02T14:26:38.023302-06:00","updated_at":"2026-01-02T14:33:29.866817-06:00","dependencies":[{"issue_id":"k-4csc","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T14:26:38.024435-06:00","created_by":"daemon"}]} -{"id":"k-4wex","title":"quarto-hub MVP: automerge-based collaborative infrastructure","description":"Create a new crate 'quarto-hub' that produces a binary called 'hub' with library exports. Implements automerge-based collaborative editing infrastructure with shared state web server, directory management with lockfiles, and file persistence.","status":"in_progress","priority":1,"issue_type":"feature","created_at":"2025-12-08T13:06:57.634484-06:00","updated_at":"2025-12-08T14:02:35.709646-06:00"} -{"id":"k-4xqi","title":"Phase 6: Non-Native Formats (Pandoc Integration)","description":"REVISED: Support formats requiring Pandoc. Pandoc invocation layer (emit JSON, call with --from json), Lua filter integration, PDF recipe with latexmk, DOCX/EPUB via Pandoc. Part of k-xlko.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-12-20T11:42:27.680303-06:00","updated_at":"2025-12-20T12:10:00.065583-06:00","dependencies":[{"issue_id":"k-4xqi","depends_on_id":"k-xlko","type":"parent-child","created_at":"2025-12-20T11:42:27.681132-06:00","created_by":"daemon"},{"issue_id":"k-4xqi","depends_on_id":"k-b1x1","type":"blocks","created_at":"2025-12-20T11:42:47.763404-06:00","created_by":"daemon"}]} -{"id":"k-5","title":"Replace ErrorCollector usage in src/readers/qmd.rs with DiagnosticCollector","description":"Update qmd.rs to use DiagnosticCollector instead of TextErrorCollector and JsonErrorCollector. The logic needs to change: instead of creating different collectors for JSON vs text, use single DiagnosticCollector and call to_json() or to_text() based on format.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:29:00.576583-05:00","updated_at":"2025-10-18T15:29:40.921902-05:00","closed_at":"2025-10-18T15:29:40.921902-05:00"} -{"id":"k-50","title":"Add deeply nested YAML serialization roundtrip test","description":"Create test to observe serialization behavior:\n1. Create .qmd with deeply nested YAML (5+ levels)\n2. Parse to PandocAST with MetaWithSourceInfo\n3. Serialize to JSON\n4. Measure JSON size and analyze duplication\n5. Deserialize back to PandocAST\n6. Verify SourceInfo functionality (offsets, file resolution)\n7. Document findings\n\nThis validates the approach and observes the serialization blowup problem in real usage.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T09:07:44.439461-05:00","updated_at":"2025-10-19T13:35:07.223867-05:00","closed_at":"2025-10-19T13:35:07.223867-05:00","dependencies":[{"issue_id":"k-50","depends_on_id":"k-45","type":"parent-child","created_at":"2025-10-19T09:07:44.441135-05:00","created_by":"cscheid"},{"issue_id":"k-50","depends_on_id":"k-49","type":"blocks","created_at":"2025-10-19T09:07:44.442159-05:00","created_by":"cscheid"},{"issue_id":"k-50","depends_on_id":"k-51","type":"blocks","created_at":"2025-10-19T09:25:07.847592-05:00","created_by":"cscheid"}]} -{"id":"k-51","title":"Add Serialize/Deserialize to Inline and Block types","description":"Add #[derive(Serialize, Deserialize)] to:\\n- Inline enum in pandoc/inline.rs\\n- Block enum in pandoc/block.rs\\n- All their nested struct types\\n\\nThis is needed for:\\n- k-50 (serialization roundtrip test)\\n- Full JSON serialization of MetaValueWithSourceInfo\\n\\nThis is part of Phase 3 work (systematic migration).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T09:13:31.211553-05:00","updated_at":"2025-10-19T09:30:13.120375-05:00","closed_at":"2025-10-19T09:30:13.120375-05:00"} -{"id":"k-52","title":"Add consuming methods to YamlWithSourceInfo","description":"Add methods to YamlWithSourceInfo that consume self and return owned values:\n- into_array() -\u003e Option\u003c(Vec\u003cYamlWithSourceInfo\u003e, SourceInfo)\u003e\n- into_hash() -\u003e Option\u003c(Vec\u003cYamlHashEntry\u003e, SourceInfo)\u003e\n\nThis eliminates unnecessary clones when transforming YamlWithSourceInfo to other types.\n\nFile: crates/quarto-yaml/src/yaml_with_source_info.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T10:26:19.988076-05:00","updated_at":"2025-10-19T10:27:03.395761-05:00","closed_at":"2025-10-19T10:27:03.395761-05:00"} -{"id":"k-53","title":"Refactor yaml_to_meta_with_source_info to take ownership","description":"Change yaml_to_meta_with_source_info to take YamlWithSourceInfo by value instead of reference:\n- Change signature: yaml: YamlWithSourceInfo (not \u0026YamlWithSourceInfo)\n- Use destructuring and pattern matching on owned values\n- Use into_array() and into_hash() consuming methods\n- Eliminate all unnecessary clone() calls\n- Update caller in rawblock_to_meta_with_source_info to pass by value\n\nFile: crates/quarto-markdown-pandoc/src/pandoc/meta.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T10:26:27.817775-05:00","updated_at":"2025-10-19T10:28:28.405622-05:00","closed_at":"2025-10-19T10:28:28.405622-05:00","dependencies":[{"issue_id":"k-53","depends_on_id":"k-52","type":"blocks","created_at":"2025-10-19T10:26:27.819307-05:00","created_by":"cscheid"}]} -{"id":"k-54","title":"Unify 'l' and 's' source tracking keys in JSON format","description":"Currently JSON output uses 'l' for old SourceInfo (Blocks/Inlines) and 's' for new quarto_source_map::SourceInfo (Metadata). These should be unified once we fix the serialization storage problems. Both serve the same purpose - tracking source location.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-19T11:02:07.609948-05:00","updated_at":"2025-10-20T15:32:57.307896-05:00","closed_at":"2025-10-20T15:32:57.307896-05:00","dependencies":[{"issue_id":"k-54","depends_on_id":"k-49","type":"discovered-from","created_at":"2025-10-19T11:04:09.092582-05:00","created_by":"cscheid"},{"issue_id":"k-54","depends_on_id":"k-35","type":"blocks","created_at":"2025-10-20T15:17:25.830558-05:00","created_by":"cscheid"}]} -{"id":"k-55","title":"Fix incorrect source tracking in JSON 's' metadata fields","description":"The 's' field in JSON metadata output shows all-zero ranges (offset:0, row:0, col:0) instead of actual source locations. Test case: tests/snapshots/json/002.qmd where title:'metadata1' should point to line 2, offset 7-16, but shows 0-0. Root cause investigation needed: check if quarto-yaml is producing correct SourceInfo, or if yaml_to_meta_with_source_info is losing it.","notes":"ROOT CAUSE FOUND:\nIn qmd.rs lines 190-242, the metadata flow loses source info:\n1. rawblock_to_meta_with_source_info() gets correct SourceInfo from quarto-yaml ✓\n2. Line 190: .to_meta() converts to old Meta type, LOSING all source info ✗ \n3. parse_metadata_strings() parses markdown (works on old Meta type)\n4. Lines 212/240: meta_from_legacy() converts back using SourceInfo::default() ✗\n\nFIX PLAN:\nCreate parse_metadata_strings_with_source_info() that:\n- Takes MetaValueWithSourceInfo instead of MetaValue\n- Preserves SourceInfo when parsing strings as markdown\n- When parsing 'title: metadata1' as markdown, creates Substring SourceInfo for the inline content\n- Returns MetaValueWithSourceInfo\n\nThis requires updating the markdown parsing to accept a parent SourceInfo parameter.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-19T11:03:16.819879-05:00","updated_at":"2025-10-19T11:11:33.69779-05:00","closed_at":"2025-10-19T11:11:33.69779-05:00","dependencies":[{"issue_id":"k-55","depends_on_id":"k-49","type":"discovered-from","created_at":"2025-10-19T11:04:07.992406-05:00","created_by":"cscheid"}]} -{"id":"k-56","title":"quarto-yaml: Fix key_span tracking to use Substring instead of Original","description":"quarto-yaml currently returns key_span as an Original SourceInfo with offset 0, when it should return a Substring SourceInfo pointing to the actual location of the key in the file.\n\nTest: test_metadata_source_tracking_002_qmd now fails with:\n assertion failed: Key 'title' should start at file offset 4\n left: 0\n right: 4\n\nThe key 'title' in 002.qmd should have offset 4 (start of frontmatter content), not 0.\n\nThis affects metadata key source tracking in PandocAST.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-19T11:52:12.408812-05:00","updated_at":"2025-10-19T12:53:13.554596-05:00","closed_at":"2025-10-19T12:53:13.554596-05:00"} -{"id":"k-57","title":"Implement SourceInfo pool serialization (writer)","description":"Implement the writer side of pool-based SourceInfo serialization.\n\nTasks:\n- Create SerializableSourceInfo and SerializableSourceMapping types\n- Implement SourceInfoSerializer with intern() method\n- Update all write_* functions to use serializer\n- Update write_pandoc to build pool and add to astContext\n\nFiles: crates/quarto-markdown-pandoc/src/writers/json.rs\n\nSee: claude-notes/plans/2025-10-19-sourceinfo-pool-serialization.md Phase 1","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T14:08:00.06362-05:00","updated_at":"2025-10-19T14:15:45.496951-05:00","closed_at":"2025-10-19T14:15:45.496951-05:00","dependencies":[{"issue_id":"k-57","depends_on_id":"k-44","type":"blocks","created_at":"2025-10-19T14:08:00.067491-05:00","created_by":"cscheid"}]} -{"id":"k-58","title":"Implement SourceInfo pool deserialization (reader)","description":"Implement the reader side of pool-based SourceInfo deserialization.\n\nTasks:\n- Create SourceInfoDeserializer that builds pool from JSON\n- Implement from_json_ref() to resolve $ref IDs\n- Update all read_* functions to use deserializer\n- Update read_pandoc to extract pool and create deserializer\n\nFiles: crates/quarto-markdown-pandoc/src/readers/json.rs\n\nSee: claude-notes/plans/2025-10-19-sourceinfo-pool-serialization.md Phase 2","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T14:08:05.886463-05:00","updated_at":"2025-11-21T15:18:15.20908-06:00","closed_at":"2025-11-21T15:18:15.20908-06:00","dependencies":[{"issue_id":"k-58","depends_on_id":"k-57","type":"blocks","created_at":"2025-10-19T14:08:05.888235-05:00","created_by":"cscheid"}]} -{"id":"k-59","title":"Add error handling for SourceInfo pool serialization","description":"Add error types and handling for pool-based serialization.\n\nTasks:\n- Add InvalidSourceInfoRef error variant\n- Add ExpectedSourceInfoRef error variant\n- Add MalformedSourceInfoPool error variant\n- Add CircularSourceInfoReference error variant\n\nFiles: crates/quarto-markdown-pandoc/src/readers/json.rs\n\nSee: claude-notes/plans/2025-10-19-sourceinfo-pool-serialization.md Phase 3","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T14:08:11.499185-05:00","updated_at":"2025-11-21T16:50:54.809108-06:00","closed_at":"2025-11-21T16:50:54.809108-06:00","dependencies":[{"issue_id":"k-59","depends_on_id":"k-58","type":"blocks","created_at":"2025-10-19T14:08:11.501067-05:00","created_by":"cscheid"}]} -{"id":"k-5a26","title":"Phase 3: Materialization and error handling","description":"Implement MaterializeOptions, materialize(), depth-limited materialization. Implement merge_with_diagnostics() for layer validation. Q-1-27 for nesting too deep. Tests for depth limits and error collection. Plan: claude-notes/plans/2025-12-07-config-merging-design.md Phase 3","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T14:03:50.953029-06:00","updated_at":"2025-12-07T14:25:57.601925-06:00","closed_at":"2025-12-07T14:25:57.601925-06:00","dependencies":[{"issue_id":"k-5a26","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2025-12-07T14:03:50.954904-06:00","created_by":"cscheid"}]} -{"id":"k-5hu5","title":"Fix cargo clippy warnings","description":"Pre-existing clippy warnings to clean up: collapsed if statements, write! with newlines, Option.and_then patterns","status":"open","priority":3,"issue_type":"chore","created_at":"2025-12-31T17:25:12.290518-06:00","updated_at":"2025-12-31T17:25:12.290518-06:00"} -{"id":"k-5u7d","title":"Phase 3: Library API for template rendering","description":"Expose clean public API: render_with_bundle (always available), render_with_template_file (feature-gated behind template-fs), and render_with_resolver (generic over PartialResolver).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T11:44:23.422676-06:00","updated_at":"2025-12-05T11:54:10.567791-06:00","closed_at":"2025-12-05T11:54:10.567791-06:00","dependencies":[{"issue_id":"k-5u7d","depends_on_id":"k-y2f3","type":"blocks","created_at":"2025-12-05T11:44:23.424608-06:00","created_by":"cscheid"},{"issue_id":"k-5u7d","depends_on_id":"k-u1iy","type":"blocks","created_at":"2025-12-05T11:44:58.733163-06:00","created_by":"cscheid"}]} -{"id":"k-5ywq","title":"Unify filter CLI: single --filter option with citeproc support","description":"Replace separate --json-filter and --lua-filter options with a single -F/--filter option that supports ordering across filter types. Add citeproc as a built-in filter.\n\nPlan: claude-notes/plans/2025-12-05-unified-filter-cli.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-05T15:44:16.194801-06:00","updated_at":"2025-12-05T16:12:23.959817-06:00","closed_at":"2025-12-05T16:12:23.959817-06:00"} -{"id":"k-5zv5","title":"Template diagnostics have incorrect file_id attribution","description":"Template warnings (e.g., undefined variable warnings from built-in HTML template) are incorrectly attributed to the .qmd file instead of the template file. The root cause is that quarto-doctemplate creates its own independent SourceContext during parsing, assigning file_id 0 to the template file. When these diagnostics are reported, the main program interprets file_id 0 using its own SourceContext where file_id 0 is the .qmd file.\n\nPlan document: claude-notes/plans/2025-12-06-template-file-id-bug.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-06T10:52:05.264739-06:00","updated_at":"2025-12-06T11:31:05.489645-06:00","closed_at":"2025-12-06T11:31:05.489645-06:00"} -{"id":"k-6","title":"Update treesitter_to_pandoc signature to use DiagnosticCollector","description":"Change function signature from generic ErrorCollector trait to concrete DiagnosticCollector type in src/pandoc/treesitter.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:29:01.548909-05:00","updated_at":"2025-10-18T15:30:15.033025-05:00","closed_at":"2025-10-18T15:30:15.033025-05:00","dependencies":[{"issue_id":"k-6","depends_on_id":"k-2","type":"blocks","created_at":"2025-10-18T13:52:20.681784-05:00","created_by":"import"},{"issue_id":"k-6","depends_on_id":"k-3","type":"blocks","created_at":"2025-10-18T13:52:20.682485-05:00","created_by":"import"},{"issue_id":"k-6","depends_on_id":"k-4","type":"blocks","created_at":"2025-10-18T13:52:20.683211-05:00","created_by":"import"},{"issue_id":"k-6","depends_on_id":"k-12","type":"blocks","created_at":"2025-10-18T13:52:28.278712-05:00","created_by":"import"}]} -{"id":"k-60","title":"Test and validate SourceInfo pool serialization","description":"Add comprehensive tests for pool-based serialization.\n\nTasks:\n- Add unit tests for SourceInfoSerializer (6 tests)\n- Add unit tests for SourceInfoDeserializer (4 tests)\n- Verify existing roundtrip tests pass\n- Update metadata source tracking test\n- Update nested YAML serialization tests with pool verification\n- Update all JSON snapshots\n\nFiles: \n- crates/quarto-markdown-pandoc/src/writers/json.rs (tests)\n- crates/quarto-markdown-pandoc/src/readers/json.rs (tests)\n- crates/quarto-markdown-pandoc/tests/test_json_roundtrip.rs\n- crates/quarto-markdown-pandoc/tests/test_metadata_source_tracking.rs\n- crates/quarto-markdown-pandoc/tests/test_nested_yaml_serialization.rs\n- crates/quarto-markdown-pandoc/tests/snapshots/json/*.snapshot\n\nSee: claude-notes/plans/2025-10-19-sourceinfo-pool-serialization.md Phase 4","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T14:08:19.728117-05:00","updated_at":"2025-11-21T16:58:27.168763-06:00","closed_at":"2025-11-21T16:58:27.168763-06:00","dependencies":[{"issue_id":"k-60","depends_on_id":"k-59","type":"blocks","created_at":"2025-10-19T14:08:19.729857-05:00","created_by":"cscheid"}]} -{"id":"k-61","title":"Document SourceInfo pool serialization implementation","description":"Add documentation for the pool-based serialization approach.\n\nTasks:\n- Add comprehensive code comments to SourceInfoSerializer\n- Add comprehensive code comments to SourceInfoDeserializer\n- Update design doc with implementation notes and learnings\n- Document the JSON format in both writer and reader\n\nFiles:\n- crates/quarto-markdown-pandoc/src/writers/json.rs\n- crates/quarto-markdown-pandoc/src/readers/json.rs\n- claude-notes/sourceinfo-serialization-optimization-design.md\n\nSee: claude-notes/plans/2025-10-19-sourceinfo-pool-serialization.md Phase 5","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-19T14:08:26.866955-05:00","updated_at":"2025-11-21T17:30:14.960862-06:00","closed_at":"2025-11-21T17:30:14.960862-06:00","dependencies":[{"issue_id":"k-61","depends_on_id":"k-60","type":"blocks","created_at":"2025-10-19T14:08:26.868862-05:00","created_by":"cscheid"}]} -{"id":"k-62","title":"YAML tag information lost in new API with source tracking","description":"The old rawblock_to_meta API preserves YAML tag information (\\!path, \\!glob, \\!str) and wraps tagged strings in Spans with class 'yaml-tagged-string'. The new rawblock_to_meta_with_source_info API loses this information because quarto-yaml doesn't track tags. This prevents removal of the legacy API and causes test_yaml_tagged_strings to fail when migrated to new API.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-20T09:19:18.04194-05:00","updated_at":"2025-10-20T09:35:15.084731-05:00","closed_at":"2025-10-20T09:35:15.084731-05:00"} -{"id":"k-63","title":"Phase 3: Complete systematic migration of all AST types to use quarto-source-map","description":"Complete the systematic migration from pandoc::location::SourceInfo to quarto_source_map::SourceInfo across all AST types.\n\nCurrent state:\n- Infrastructure completed (Phase 1, 2)\n- A few structs have source_info_qsm fields (Str, HorizontalRule from proof-of-concept)\n- Most AST types still use old pandoc::location::SourceInfo\n\nTasks:\n1. Audit all AST struct definitions to find which have source_info fields\n2. Add source_info_qsm: Option\u003cquarto_source_map::SourceInfo\u003e to all remaining structs\n3. Update all parsing code to populate both fields during transition\n4. Add Span struct to have source_info_qsm field (discovered during k-62)\n5. Once all populated, rename source_info_qsm -\u003e source_info and remove old fields\n6. Remove pandoc::location module entirely\n7. Update all imports and type references\n8. Run full test suite\n\nSee: claude-notes/quarto-source-map-integration-plan.md Phase 3","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T09:59:34.894007-05:00","updated_at":"2025-10-20T13:08:15.349955-05:00","closed_at":"2025-10-20T13:08:15.349955-05:00","dependencies":[{"issue_id":"k-63","depends_on_id":"k-27","type":"parent-child","created_at":"2025-10-20T09:59:34.897817-05:00","created_by":"cscheid"}]} -{"id":"k-64","title":"Audit all AST structs and create migration checklist","description":"Identify all structs that need source_info_qsm field added. Create comprehensive list of:\n- All Inline types in inline.rs that need migration\n- All Block types in block.rs that need migration\n- Any other types with source_info fields\n\nDocument current state: 2/42 structs have source_info_qsm (Str, HorizontalRule)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T10:03:40.111289-05:00","updated_at":"2025-10-20T10:15:58.737432-05:00","closed_at":"2025-10-20T10:15:58.737432-05:00","dependencies":[{"issue_id":"k-64","depends_on_id":"k-63","type":"parent-child","created_at":"2025-10-20T10:03:40.11311-05:00","created_by":"cscheid"}]} -{"id":"k-65","title":"Add source_info_qsm to all Inline types in inline.rs","description":"Add 'pub source_info_qsm: Option\u003cquarto_source_map::SourceInfo\u003e' field to all Inline types that don't have it yet.\n\nInline types to update (based on grep results):\n- Emph, Underline, Strong, Strikeout, Superscript, Subscript\n- SmallCaps, Quoted, Cite, Code, Space, SoftBreak, LineBreak\n- Math, RawInline, Link, Image, Note, Span, Shortcode\n- (Str already has it)\n\nEnsure all types have the field added with Option\u003c\u003e wrapper.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T10:03:48.030737-05:00","updated_at":"2025-10-20T10:33:20.994543-05:00","closed_at":"2025-10-20T10:33:20.994543-05:00","dependencies":[{"issue_id":"k-65","depends_on_id":"k-64","type":"blocks","created_at":"2025-10-20T10:03:48.03243-05:00","created_by":"cscheid"},{"issue_id":"k-65","depends_on_id":"k-63","type":"parent-child","created_at":"2025-10-20T10:03:48.033415-05:00","created_by":"cscheid"}]} -{"id":"k-66","title":"Add source_info_qsm to all Block types in block.rs","description":"Add 'pub source_info_qsm: Option\u003cquarto_source_map::SourceInfo\u003e' field to all Block types that don't have it yet.\n\nBlock types to update (based on grep results):\n- Plain, Para, LineBlock, CodeBlock, RawBlock, BlockQuote\n- OrderedList, BulletList, DefinitionList, Header, Div, Table\n- Figure, Caption, TableHead, TableBody, TableFoot, Row, Cell\n- (HorizontalRule already has it)\n\nEnsure all types have the field added with Option\u003c\u003e wrapper.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T10:03:55.330281-05:00","updated_at":"2025-10-20T10:33:21.009695-05:00","closed_at":"2025-10-20T10:33:21.009695-05:00","dependencies":[{"issue_id":"k-66","depends_on_id":"k-64","type":"blocks","created_at":"2025-10-20T10:03:55.33295-05:00","created_by":"cscheid"},{"issue_id":"k-66","depends_on_id":"k-63","type":"parent-child","created_at":"2025-10-20T10:03:55.334221-05:00","created_by":"cscheid"}]} -{"id":"k-67","title":"Update all parsing code to populate both source_info fields","description":"Update all parsing code across all modules to populate both source_info and source_info_qsm fields.\n\nFor each struct construction:\n- Keep existing source_info using pandoc::location::SourceInfo\n- Add source_info_qsm using node_to_source_info_with_context() from source_map_compat.rs\n\nThis ensures gradual migration without breaking existing code.\n\nFiles to update: All readers/treesitter/*.rs parsing modules","notes":"Current: 141 missing field errors. Sub-tasks created: k-72 through k-77. See phase3-sourceinfo-migration-guide.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T10:04:03.558959-05:00","updated_at":"2025-10-20T11:21:55.811406-05:00","closed_at":"2025-10-20T11:21:55.811406-05:00","dependencies":[{"issue_id":"k-67","depends_on_id":"k-65","type":"blocks","created_at":"2025-10-20T10:04:03.560757-05:00","created_by":"cscheid"},{"issue_id":"k-67","depends_on_id":"k-66","type":"blocks","created_at":"2025-10-20T10:04:03.561851-05:00","created_by":"cscheid"},{"issue_id":"k-67","depends_on_id":"k-63","type":"parent-child","created_at":"2025-10-20T10:04:03.564626-05:00","created_by":"cscheid"}]} -{"id":"k-68","title":"Test that all source locations are preserved","description":"Verify that source location tracking works correctly after migration.\n\nTests:\n- Run existing test suite (all should pass)\n- Verify source_info_qsm fields are populated correctly\n- Spot check a few parsing modules to ensure locations match\n- Test inline location tracking\n- Test block location tracking\n\nThis validates the dual-field approach before switchover.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T10:04:10.636767-05:00","updated_at":"2025-10-20T11:26:25.717196-05:00","closed_at":"2025-10-20T11:26:25.717196-05:00","dependencies":[{"issue_id":"k-68","depends_on_id":"k-67","type":"blocks","created_at":"2025-10-20T10:04:10.638345-05:00","created_by":"cscheid"},{"issue_id":"k-68","depends_on_id":"k-63","type":"parent-child","created_at":"2025-10-20T10:04:10.639298-05:00","created_by":"cscheid"}]} -{"id":"k-684e","title":"Jupyter engine: Production readiness","description":"Bring Jupyter engine from MVP to production readiness. MVP is complete with kernelspec discovery, kernel lifecycle, execute/reply, output conversion, AST transform, daemon persistence, and inline expressions. Remaining work includes: chunk options, language setup code, timeout/interrupt, error recovery, figure improvements, pipeline integration. See plan: claude-notes/plans/2026-01-07-jupyter-engine-remaining-work.md","status":"open","priority":2,"issue_type":"feature","created_at":"2026-01-07T19:26:49.679024272Z","updated_at":"2026-01-07T19:26:49.679024272Z"} -{"id":"k-69","title":"Replace source_info with source_info_qsm throughout","description":"Final switchover from old to new SourceInfo type.\n\nTasks:\n- Remove 'pub source_info: SourceInfo' (pandoc::location) from all structs\n- Rename 'pub source_info_qsm' to 'pub source_info' everywhere\n- Update all field access from .source_info_qsm to .source_info\n- Update serialization derives if needed\n- This is the breaking change that completes the migration","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T10:04:18.15738-05:00","updated_at":"2025-10-20T12:52:21.024388-05:00","closed_at":"2025-10-20T12:52:21.024388-05:00","dependencies":[{"issue_id":"k-69","depends_on_id":"k-68","type":"blocks","created_at":"2025-10-20T10:04:18.158891-05:00","created_by":"cscheid"},{"issue_id":"k-69","depends_on_id":"k-63","type":"parent-child","created_at":"2025-10-20T10:04:18.159759-05:00","created_by":"cscheid"}]} -{"id":"k-6cza","title":"Add 'import' subcommand to quarto-hub binary","description":"Add an 'import' subcommand to the hub binary that allows users to clone a collaborative Quarto project from a sync server. Given an index document ID and sync server URL, this command should:\n\n1. Create the target directory (if needed)\n2. Set up the .quarto/hub/ infrastructure\n3. Connect to the sync server\n4. Fetch the index document\n5. Fetch all file documents referenced in the index\n6. Write file contents to disk\n7. Configure hub.json with the index ID and peer URL\n8. Initialize sync state\n\n**Design decisions (approved)**:\n- No partial imports: fail entirely if any document fails\n- No timeout: wait indefinitely with interactive progress feedback\n- Separate commands: users run 'hub import' then 'hub serve'\n\nSee plan: claude-notes/plans/2025-01-05-hub-import-subcommand.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-01-05T17:23:15.193952-06:00","updated_at":"2026-01-05T17:34:49.291138-06:00","closed_at":"2026-01-05T17:34:49.291138-06:00"} -{"id":"k-6daf","title":"Good source location tracking of document after engine outputs","description":"After engine execution (Jupyter, knitr, etc), the pipeline has two PandocAST structs: the pre-engine AST with source locations pointing to the original qmd, and the post-engine AST with locations pointing to intermediate engine output files. We need a tree-diffing algorithm to reconcile these ASTs, transferring original source locations to unchanged elements while keeping new locations for elements that changed (code execution outputs).\n\nPlan: claude-notes/plans/2025-12-15-engine-output-source-location-reconciliation.md\nRelated: claude-notes/plans/2025-12-15-source-info-for-structured-formats.md","status":"open","priority":1,"issue_type":"feature","created_at":"2025-12-15T15:53:21.187508-06:00","updated_at":"2025-12-15T15:54:35.598252-06:00"} -{"id":"k-6qau","title":"Phase 1: Foundation MVP - Single document HTML rendering","description":"REVISED: Render single .qmd to HTML without calling Pandoc. Uses pampa for parsing and quarto-doctemplate for HTML output. Includes: ProjectContext detection, DependencyCollector skeleton, basic file copying. Deliverable: 'cargo run -- render simple.qmd' produces basic HTML. Part of k-xlko.","status":"in_progress","priority":1,"issue_type":"feature","created_at":"2025-12-20T11:42:21.79358-06:00","updated_at":"2025-12-21T10:30:54.707146-06:00","dependencies":[{"issue_id":"k-6qau","depends_on_id":"k-xlko","type":"parent-child","created_at":"2025-12-20T11:42:21.794398-06:00","created_by":"daemon"}]} -{"id":"k-6wjz","title":"Improve coverage for quarto-yaml-validation/validator.rs","description":"Session baseline: 69.62% line coverage, validator.rs: 42.18%. Working on improving coverage.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-31T10:02:09.631523-06:00","updated_at":"2025-12-31T11:57:18.729364-06:00","closed_at":"2025-12-31T11:57:18.729364-06:00","dependencies":[{"issue_id":"k-6wjz","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2025-12-31T10:02:09.632368-06:00","created_by":"daemon"}]} -{"id":"k-6zaq","title":"Rename LuaRuntime to SystemRuntime and unify runtime abstraction","description":"Rename the LuaRuntime trait to SystemRuntime and move it to a shared location so it can be used by both pampa (for Lua filters) and quarto-core (for filesystem abstraction). This eliminates the need for a separate QuartoRuntime trait.\n\nPlan: claude-notes/plans/2025-12-22-system-runtime-unification.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-22T17:20:10.017439-06:00","updated_at":"2025-12-22T18:52:26.13751-06:00","closed_at":"2025-12-22T18:52:26.13751-06:00","dependencies":[{"issue_id":"k-6zaq","depends_on_id":"k-nkhl","type":"discovered-from","created_at":"2025-12-22T17:20:10.019-06:00","created_by":"daemon"}]} -{"id":"k-7","title":"Update postprocess function to use DiagnosticCollector","description":"Change postprocess function signature from generic ErrorCollector trait to concrete DiagnosticCollector type in src/pandoc/treesitter_utils/postprocess.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:29:02.832735-05:00","updated_at":"2025-10-18T15:30:37.920982-05:00","closed_at":"2025-10-18T15:30:37.920982-05:00","dependencies":[{"issue_id":"k-7","depends_on_id":"k-12","type":"blocks","created_at":"2025-10-18T13:52:28.279485-05:00","created_by":"import"}]} -{"id":"k-70","title":"Remove pandoc::location module","description":"Delete the old pandoc::location module after migration is complete.\n\nTasks:\n- Remove src/pandoc/location.rs file\n- Remove 'pub mod location;' from src/pandoc/mod.rs\n- Remove any remaining imports of pandoc::location types\n- Remove source_map_compat.rs (temporary bridge module)\n- Verify no references remain to old Location, Range, SourceInfo types\n- Run cargo check to ensure clean compilation","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T10:04:26.83249-05:00","updated_at":"2025-10-20T13:25:36.442096-05:00","closed_at":"2025-10-20T13:25:36.442096-05:00","dependencies":[{"issue_id":"k-70","depends_on_id":"k-69","type":"blocks","created_at":"2025-10-20T10:04:26.83385-05:00","created_by":"cscheid"},{"issue_id":"k-70","depends_on_id":"k-63","type":"parent-child","created_at":"2025-10-20T10:04:26.83474-05:00","created_by":"cscheid"}]} -{"id":"k-71","title":"Run full test suite after migration complete","description":"Final validation that migration is complete and correct.\n\nTasks:\n- cargo test --package quarto-markdown-pandoc (all tests must pass)\n- cargo test --workspace (verify no breakage in other crates)\n- Verify all source location tracking still works\n- Check that error messages show correct locations\n- Document any remaining work or known issues\n\nSuccess criteria: All tests pass, no compilation errors, source tracking functional.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T10:04:34.574239-05:00","updated_at":"2025-10-20T15:01:18.681793-05:00","closed_at":"2025-10-20T15:01:18.681793-05:00","dependencies":[{"issue_id":"k-71","depends_on_id":"k-70","type":"blocks","created_at":"2025-10-20T10:04:34.5762-05:00","created_by":"cscheid"},{"issue_id":"k-71","depends_on_id":"k-63","type":"parent-child","created_at":"2025-10-20T10:04:34.577373-05:00","created_by":"cscheid"}]} -{"id":"k-72","title":"Step 2.1: Fix filters.rs struct constructions","description":"Add source_info_qsm: None to all struct initializers in filters.rs.\n\nCommon patterns:\n- Inline::Note(pandoc::Note { content, source_info: self.source_info })\n- Inline::Cite(pandoc::Cite { citations, content, source_info: self.source_info })\n- Block::BlockMetadata(MetaBlock { meta, source_info })\n\nEstimated: 20-30 struct constructions","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T10:37:46.20235-05:00","updated_at":"2025-10-20T10:43:44.018029-05:00","closed_at":"2025-10-20T10:43:44.018029-05:00","dependencies":[{"issue_id":"k-72","depends_on_id":"k-65","type":"blocks","created_at":"2025-10-20T10:37:46.204457-05:00","created_by":"cscheid"},{"issue_id":"k-72","depends_on_id":"k-66","type":"blocks","created_at":"2025-10-20T10:37:46.205364-05:00","created_by":"cscheid"},{"issue_id":"k-72","depends_on_id":"k-67","type":"parent-child","created_at":"2025-10-20T10:37:46.206184-05:00","created_by":"cscheid"}]} -{"id":"k-73","title":"Step 2.2: Fix pandoc/treesitter.rs struct constructions","description":"Add source_info_qsm: None to all Str, Space, LineBreak, SoftBreak, RawInline constructions in pandoc/treesitter.rs.\n\nPattern: Inline::Str(Str { text, source_info: node_source_info(node) })\n\nEstimated: 10-15 struct constructions","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T10:37:53.022731-05:00","updated_at":"2025-10-20T10:45:41.347372-05:00","closed_at":"2025-10-20T10:45:41.347372-05:00","dependencies":[{"issue_id":"k-73","depends_on_id":"k-72","type":"blocks","created_at":"2025-10-20T10:37:53.02538-05:00","created_by":"cscheid"},{"issue_id":"k-73","depends_on_id":"k-67","type":"parent-child","created_at":"2025-10-20T10:37:53.026918-05:00","created_by":"cscheid"}]} -{"id":"k-74","title":"Step 2.3: Fix treesitter_utils/ parsing files (Priority 1)","description":"Add source_info_qsm: None to struct constructions in core parsing files.\n\nFiles to fix (in order):\n1. atx_heading.rs - Header\n2. setext_heading.rs - Header\n3. code_span.rs - Code\n4. fenced_code_block.rs - CodeBlock\n5. indented_code_block.rs - CodeBlock\n6. block_quote.rs - BlockQuote\n7. quoted_span.rs - Quoted\n8. inline_link.rs - Link\n9. image.rs - Image, Link\n10. citation.rs - Cite\n\nEstimated: 30-40 struct constructions total","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T10:38:01.113205-05:00","updated_at":"2025-10-20T11:21:57.3632-05:00","closed_at":"2025-10-20T11:21:57.3632-05:00","dependencies":[{"issue_id":"k-74","depends_on_id":"k-72","type":"blocks","created_at":"2025-10-20T10:38:01.114944-05:00","created_by":"cscheid"},{"issue_id":"k-74","depends_on_id":"k-67","type":"parent-child","created_at":"2025-10-20T10:38:01.116059-05:00","created_by":"cscheid"}]} -{"id":"k-75","title":"Step 2.4: Fix treesitter_utils/ remaining files (Priority 2)","description":"Add source_info_qsm: None to struct constructions in remaining treesitter_utils files.\n\nFiles:\n- note_definition_para.rs - NoteDefinitionPara\n- note_definition_fenced_block.rs - NoteDefinitionFencedBlock\n- fenced_div_block.rs - Div\n- editorial_marks.rs - Insert, Delete, Highlight, EditComment\n- latex_span.rs - Math, RawInline\n- caption.rs - CaptionBlock\n- pipe_table.rs - Table\n- document.rs - various\n\nEstimated: 30-40 constructions","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T10:38:09.595489-05:00","updated_at":"2025-10-20T11:21:58.983699-05:00","closed_at":"2025-10-20T11:21:58.983699-05:00","dependencies":[{"issue_id":"k-75","depends_on_id":"k-74","type":"blocks","created_at":"2025-10-20T10:38:09.597372-05:00","created_by":"cscheid"},{"issue_id":"k-75","depends_on_id":"k-67","type":"parent-child","created_at":"2025-10-20T10:38:09.598308-05:00","created_by":"cscheid"}]} -{"id":"k-76","title":"Step 2.5: Fix pandoc/meta.rs and other pandoc/ files","description":"Add source_info_qsm: None to struct constructions in meta.rs and other pandoc core files.\n\nFiles:\n- pandoc/meta.rs - MetaBlock constructions\n- pandoc/inline.rs - helper functions (make_span_inline, make_cite_inline, etc)\n- pandoc/block.rs - helper functions (make_block_leftover, etc)\n- pandoc/shortcode.rs - if any\n\nEstimated: 20-30 constructions","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T10:38:18.965689-05:00","updated_at":"2025-10-20T11:22:00.516003-05:00","closed_at":"2025-10-20T11:22:00.516003-05:00","dependencies":[{"issue_id":"k-76","depends_on_id":"k-73","type":"blocks","created_at":"2025-10-20T10:38:18.96731-05:00","created_by":"cscheid"},{"issue_id":"k-76","depends_on_id":"k-67","type":"parent-child","created_at":"2025-10-20T10:38:18.968257-05:00","created_by":"cscheid"}]} -{"id":"k-77","title":"Step 2.6: Fix readers/ and writers/ files","description":"Add source_info_qsm: None to struct constructions in readers and writers.\n\nFiles:\n- readers/json.rs - Deserialization (many structs)\n- readers/qmd.rs - if any\n- writers/qmd.rs - if any\n- writers/json.rs - may already be correct (uses serialization)\n\nEstimated: 20-30 constructions\n\nAfter this, run: cargo check --package quarto-markdown-pandoc\nShould see 0 errors.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T10:38:26.830653-05:00","updated_at":"2025-10-20T11:22:02.17214-05:00","closed_at":"2025-10-20T11:22:02.17214-05:00","dependencies":[{"issue_id":"k-77","depends_on_id":"k-75","type":"blocks","created_at":"2025-10-20T10:38:26.832365-05:00","created_by":"cscheid"},{"issue_id":"k-77","depends_on_id":"k-76","type":"blocks","created_at":"2025-10-20T10:38:26.833269-05:00","created_by":"cscheid"},{"issue_id":"k-77","depends_on_id":"k-67","type":"parent-child","created_at":"2025-10-20T10:38:26.834079-05:00","created_by":"cscheid"}]} -{"id":"k-78","title":"Implement SourceLocation trait for new quarto_source_map::SourceInfo","description":"The old SourceLocation trait (filename_index(), range()) is incompatible with new quarto_source_map::SourceInfo structure. Need to either: 1) Update trait to work with new type, 2) Remove trait and update JSON writer, or 3) Create compat layer. Blocking k-69 completion.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-20T11:40:28.023905-05:00","updated_at":"2025-10-20T14:32:35.332457-05:00","closed_at":"2025-10-20T14:32:35.332457-05:00","dependencies":[{"issue_id":"k-78","depends_on_id":"k-69","type":"discovered-from","created_at":"2025-10-20T11:40:28.025571-05:00","created_by":"cscheid"}]} -{"id":"k-79","title":"k-69 Part 2: Update function signatures to use quarto_source_map::SourceInfo","description":"Update helper function signatures that currently take old location::SourceInfo parameter (e.g., make_span_inline, etc.). Convert between old/new types at boundaries where needed. Fix ~126 type mismatch errors.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-20T11:44:32.928647-05:00","updated_at":"2025-10-20T12:44:48.351038-05:00","closed_at":"2025-10-20T12:44:48.351038-05:00","dependencies":[{"issue_id":"k-79","depends_on_id":"k-69","type":"blocks","created_at":"2025-10-20T11:44:32.930264-05:00","created_by":"cscheid"}]} -{"id":"k-7bty","title":"Implement metadata-level reconciliation for YAML front matter","description":"Currently, AST reconciliation uses a simple rule: if metadata changes, the executed metadata wins entirely. A future enhancement would reconcile metadata at the mapping level, preserving source locations for unchanged fields while updating changed ones. This would involve: (1) For MetaMap: reconcile each key-value pair; (2) For MetaList: align items similar to block alignment; (3) For scalar values: exact match or replace. Related to structural hash reconciliation design.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-12-17T18:09:59.7026-06:00","updated_at":"2025-12-17T18:09:59.7026-06:00","dependencies":[{"issue_id":"k-7bty","depends_on_id":"k-xvte","type":"discovered-from","created_at":"2025-12-17T18:09:59.704099-06:00","created_by":"daemon"}]} -{"id":"k-7r7z","title":"Improve coverage: quarto-core/src/template.rs","description":"Session baseline: 73.73% line coverage. File at 60.04%. Focus on render functions, metadata conversion, inlines/blocks to text.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T11:06:44.093672-06:00","updated_at":"2026-01-02T11:15:32.791569-06:00","closed_at":"2026-01-02T11:15:32.791569-06:00","dependencies":[{"issue_id":"k-7r7z","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T11:06:44.095533-06:00","created_by":"daemon"}]} -{"id":"k-7srl","title":"Improve coverage: pampa/src/pandoc/shortcode.rs","description":"Session baseline: 72.69% line coverage. Target: beat baseline by adding tests for shortcode_to_span function branches.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T09:31:01.650013-06:00","updated_at":"2026-01-02T09:35:57.964195-06:00","closed_at":"2026-01-02T09:35:57.964195-06:00","dependencies":[{"issue_id":"k-7srl","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T09:31:01.652353-06:00","created_by":"daemon"}]} -{"id":"k-7y5r","title":"Improve coverage for quarto-pandoc-types/reconcile module","description":"Session baseline: 70.44% line coverage. hash.rs: 36.48%, types.rs: 32.00%, apply.rs: 48.27%, compute.rs: 60.79%.","status":"in_progress","priority":2,"issue_type":"task","created_at":"2025-12-31T10:02:10.572005-06:00","updated_at":"2025-12-31T12:04:56.711244-06:00","dependencies":[{"issue_id":"k-7y5r","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2025-12-31T10:02:10.572843-06:00","created_by":"daemon"}]} -{"id":"k-8","title":"Update test files to use DiagnosticCollector","description":"Update tests/test.rs and tests/test_inline_locations.rs to use DiagnosticCollector instead of TextErrorCollector","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:29:04.145707-05:00","updated_at":"2025-10-18T15:31:12.689417-05:00","closed_at":"2025-10-18T15:31:12.689417-05:00"} -{"id":"k-80","title":"k-69 Part 3: Update imports to use new SourceInfo type","description":"Replace 'use crate::pandoc::location::SourceInfo' imports with new type. Remove unused imports of old location types (node_source_info_with_context, etc.).","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-20T11:44:34.645643-05:00","updated_at":"2025-10-20T12:44:56.135319-05:00","closed_at":"2025-10-20T12:44:56.135319-05:00","dependencies":[{"issue_id":"k-80","depends_on_id":"k-69","type":"blocks","created_at":"2025-10-20T11:44:34.646847-05:00","created_by":"cscheid"}]} -{"id":"k-81","title":"k-69 Part 4: Verify compilation and tests","description":"Run cargo check (0 errors), run cargo test (all passing). Fix any remaining issues.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-20T11:44:36.260697-05:00","updated_at":"2025-10-20T12:51:06.884202-05:00","closed_at":"2025-10-20T12:51:06.884202-05:00","dependencies":[{"issue_id":"k-81","depends_on_id":"k-69","type":"blocks","created_at":"2025-10-20T11:44:36.262013-05:00","created_by":"cscheid"}]} -{"id":"k-82","title":"Implement combine() method for quarto_source_map::SourceInfo","description":"The merge_strs function in postprocess.rs needs a combine() method to merge source info when concatenating strings. Currently commented out at line 755-758. This method should combine two SourceInfo objects, similar to how location::SourceInfo::combine() worked.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-20T12:38:55.993474-05:00","updated_at":"2025-10-20T14:40:01.36889-05:00","closed_at":"2025-10-20T14:40:01.36889-05:00","dependencies":[{"issue_id":"k-82","depends_on_id":"k-69","type":"discovered-from","created_at":"2025-10-20T12:38:55.996144-05:00","created_by":"cscheid"}]} -{"id":"k-83","title":"k-70 Step 1: Remove SourceLocation trait and update JSON writer","description":"","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-20T13:09:16.465787-05:00","updated_at":"2025-10-20T13:13:23.311889-05:00","closed_at":"2025-10-20T13:13:23.311889-05:00","dependencies":[{"issue_id":"k-83","depends_on_id":"k-70","type":"blocks","created_at":"2025-10-20T13:09:16.468226-05:00","created_by":"cscheid"}]} -{"id":"k-84","title":"k-70 Step 2: Replace old Range/Location types with quarto_source_map types","description":"","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-20T13:09:21.933957-05:00","updated_at":"2025-10-20T13:21:48.289778-05:00","closed_at":"2025-10-20T13:21:48.289778-05:00","dependencies":[{"issue_id":"k-84","depends_on_id":"k-70","type":"blocks","created_at":"2025-10-20T13:09:21.935652-05:00","created_by":"cscheid"}]} -{"id":"k-85","title":"k-70 Step 3: Move helper functions and delete location module","description":"","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-20T13:09:28.863617-05:00","updated_at":"2025-10-20T13:25:31.169093-05:00","closed_at":"2025-10-20T13:25:31.169093-05:00","dependencies":[{"issue_id":"k-85","depends_on_id":"k-70","type":"blocks","created_at":"2025-10-20T13:09:28.865949-05:00","created_by":"cscheid"},{"issue_id":"k-85","depends_on_id":"k-83","type":"discovered-from","created_at":"2025-10-20T13:09:28.867368-05:00","created_by":"cscheid"},{"issue_id":"k-85","depends_on_id":"k-84","type":"discovered-from","created_at":"2025-10-20T13:09:28.868047-05:00","created_by":"cscheid"}]} -{"id":"k-86","title":"Fix FileId handling - both branches of context.filenames.is_empty() return FileId(0)","description":"During k-84 migration, introduced a bug where if statements check context.filenames.is_empty() but both branches return FileId(0). The else branch should use the actual filename index from context.\n\nAffected files:\n- src/pandoc/location.rs (node_source_info_with_context)\n- src/pandoc/treesitter.rs (multiple locations)\n- src/pandoc/treesitter_utils/editorial_marks.rs (multiple locations)\n\nThe pattern should be:\nif context.filenames.is_empty() {\n quarto_source_map::FileId(0)\n} else {\n quarto_source_map::FileId(context.current_filename_index or similar)\n}\n\nTasks:\n1. Study how filename indices are tracked in ASTContext\n2. Determine the correct way to get the current filename index\n3. Create test cases that verify filename information is preserved\n4. Fix all instances of this pattern\n5. Verify tests pass and filename information is correct","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-20T13:29:53.798883-05:00","updated_at":"2025-10-20T13:36:27.383592-05:00","closed_at":"2025-10-20T13:36:27.383592-05:00","dependencies":[{"issue_id":"k-86","depends_on_id":"k-84","type":"discovered-from","created_at":"2025-10-20T13:29:53.801661-05:00","created_by":"cscheid"}]} -{"id":"k-87","title":"Audit and fix SourceInfo::default() instances - ensure proper source tracking","description":"There are 43 instances of SourceInfo::default() across the codebase where we're not tracking source locations. Many of these could and should track actual source information from tree-sitter nodes or other sources.\n\nAffected files:\n- src/readers/json.rs\n- src/readers/qmd.rs \n- src/pandoc/treesitter.rs (3 instances)\n- src/pandoc/treesitter_utils/document.rs\n- src/pandoc/treesitter_utils/postprocess.rs\n- src/pandoc/block.rs\n- src/pandoc/inline.rs\n- src/pandoc/meta.rs\n\nTasks:\n1. Audit each SourceInfo::default() instance to determine:\n - Is source location information available from tree-sitter node?\n - Is this data derived from existing AST with source info?\n - Is this a legitimate case where no source info exists (e.g., synthetic nodes)?\n\n2. Categorize instances:\n - Can be fixed: node available, should track location\n - Should propagate: derived from existing AST, should copy/combine source info\n - Legitimate default: synthetic/generated content with no source\n\n3. Create systematic plan to fix trackable instances\n\n4. Fix instances file by file, verifying with tests\n\n5. Document remaining legitimate default() uses with comments explaining why\n\nExpected outcome:\n- Maximum source location tracking throughout AST\n- Better error messages and diagnostics\n- Clear documentation for cases where default() is appropriate","notes":"**2025-11-21 Comprehensive Documentation Audit Complete**\n\nTotal instances: 109 (up from original 43)\n\n**Breakdown:**\n- 55 instances in test files (legitimate)\n- 19 in json.rs (backward compatibility - documented)\n- 19 in meta.rs (legacy conversion + error recovery - documented)\n- 7 in yaml_with_source_info.rs (test code - legitimate)\n- 4 in validation schema (structure errors - documented)\n- 2 in validator.rs (test code - legitimate)\n- 2 in postprocess.rs (1 blocked by k-82, 1 synthetic - documented)\n- 1 in document.rs (legitimate - already documented)\n\n**Documentation Added:**\n1. json.rs: Added module-level comment about backward compatibility\n2. meta.rs: Added inline comments for error recovery spans and legacy conversion\n3. schema/merge.rs: Documented 3 schema structure errors\n4. schema/mod.rs: Documented 1 schema structure error\n\n**Status:**\n- All production code instances are either:\n - Already had documentation (1 instance)\n - Now have documentation (14 instances)\n - Blocked by other work - k-82 (1 instance)\n - Legitimate test code (64 instances)\n\n**Remaining Work:**\n- postprocess.rs:667 - Math+Attr wrapper (blocked by k-82 combine() implementation)\n- meta.rs:449 - yaml-tagged-string Span (TODO added to propagate source info)\n\nAll cargo check and cargo test pass.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T13:39:29.142757-05:00","updated_at":"2025-11-21T15:40:17.413701-06:00","closed_at":"2025-11-21T15:40:17.413701-06:00"} -{"id":"k-88","title":"Migrate NoteReference to use SourceInfo instead of Range","description":"NoteReference currently uses the old Range field instead of SourceInfo, which means postprocess.rs can't properly track source info when converting NoteReference -\u003e Span.\n\nCurrent state:\n- NoteReference struct has 'range: Range' field\n- Should have 'source_info: SourceInfo' field instead\n- postprocess.rs:389 has to use default() because no SourceInfo available\n\nFix needed:\n1. Update NoteReference struct to use SourceInfo\n2. Update note_reference.rs parser to set source_info from node\n3. Update postprocess.rs to use note_ref.source_info\n4. Add test to verify NoteReference source tracking\n\nThis is a larger structural migration discovered during k-87 audit.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-20T14:18:26.315377-05:00","updated_at":"2025-10-20T14:26:24.07964-05:00","closed_at":"2025-10-20T14:26:24.07964-05:00","dependencies":[{"issue_id":"k-88","depends_on_id":"k-87","type":"discovered-from","created_at":"2025-10-20T14:18:26.317299-05:00","created_by":"cscheid"}]} -{"id":"k-89","title":"Add UPDATE_SNAPSHOTS environment variable support for snapshot tests","description":"Currently snapshot tests in test.rs require manual updating by regenerating each .snapshot file individually. Add support for UPDATE_SNAPSHOTS=1 environment variable (like insta and other snapshot testing libraries) to automatically update all snapshot files when tests fail.\n\nImplementation:\n- Check for UPDATE_SNAPSHOTS env var in test_snapshots_for_format()\n- When set, write output to snapshot_path instead of comparing\n- Print message indicating snapshots were updated\n\nThis would make it much easier to update snapshots after intentional changes to output format.","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-10-20T14:40:19.374671-05:00","updated_at":"2025-10-20T14:44:18.877845-05:00","closed_at":"2025-10-20T14:44:18.877845-05:00"} -{"id":"k-9","title":"Remove old ErrorCollector trait and implementations","description":"Delete ErrorCollector trait, TextErrorCollector, JsonErrorCollector, and SourceInfo from src/utils/error_collector.rs. Keep the file if needed or remove from mod.rs.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T15:29:05.724675-05:00","updated_at":"2025-10-18T15:31:40.941416-05:00","closed_at":"2025-10-18T15:31:40.941416-05:00","dependencies":[{"issue_id":"k-9","depends_on_id":"k-8","type":"blocks","created_at":"2025-10-18T13:52:20.683931-05:00","created_by":"import"}]} -{"id":"k-90","title":"Implement tag-based YAML metadata markdown parsing behavior","description":"Change metadata string markdown parsing behavior based on YAML tags: !str/!path emit plain Str nodes, !md fails with error on parse failure, untagged values emit warnings on parse failure. See claude-notes/plans/2025-10-21-yaml-tag-markdown-warning.md for full plan.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-21T08:40:49.635916-05:00","updated_at":"2025-10-21T13:46:14.689557-05:00","closed_at":"2025-10-21T13:46:14.689557-05:00","dependencies":[{"issue_id":"k-90","depends_on_id":"k-8","type":"related","created_at":"2025-10-21T08:41:36.111694-05:00","created_by":"cscheid"}]} -{"id":"k-91","title":"Thread diagnostic collector through metadata parsing functions","description":"Add diagnostics parameter to yaml_to_meta_with_source_info, parse_metadata_strings_with_source_info, and their callers to enable warning/error emission during metadata parsing","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T08:40:56.989763-05:00","updated_at":"2025-10-21T08:45:34.41158-05:00","closed_at":"2025-10-21T08:45:34.41158-05:00","dependencies":[{"issue_id":"k-91","depends_on_id":"k-90","type":"discovered-from","created_at":"2025-10-21T08:40:56.99114-05:00","created_by":"cscheid"}]} -{"id":"k-92","title":"Implement !str and !path tag behavior (plain Str nodes)","description":"Modify yaml_to_meta_with_source_info to emit plain Str nodes for !str and !path tags without yaml-tagged-string wrapper","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T08:41:03.071741-05:00","updated_at":"2025-10-21T08:46:54.514894-05:00","closed_at":"2025-10-21T08:46:54.514894-05:00","dependencies":[{"issue_id":"k-92","depends_on_id":"k-90","type":"discovered-from","created_at":"2025-10-21T08:41:03.073287-05:00","created_by":"cscheid"}]} -{"id":"k-93","title":"Implement !md tag error on parse failure","description":"When !md tag is present and markdown parsing fails, emit error (not warning) with helpful message","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T08:41:09.383717-05:00","updated_at":"2025-10-21T08:48:43.584432-05:00","closed_at":"2025-10-21T08:48:43.584432-05:00","dependencies":[{"issue_id":"k-93","depends_on_id":"k-90","type":"discovered-from","created_at":"2025-10-21T08:41:09.385912-05:00","created_by":"cscheid"}]} -{"id":"k-94","title":"Emit warning for untagged metadata parse failures","description":"When metadata string fails to parse as markdown and has no tag, emit warning suggesting use of !str or !path tags","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T08:41:18.779796-05:00","updated_at":"2025-10-21T08:48:43.599576-05:00","closed_at":"2025-10-21T08:48:43.599576-05:00","dependencies":[{"issue_id":"k-94","depends_on_id":"k-90","type":"discovered-from","created_at":"2025-10-21T08:41:18.781586-05:00","created_by":"cscheid"}]} -{"id":"k-95","title":"Add tests for tag-based metadata parsing behavior","description":"Create tests for !str/!path plain Str nodes, !md error, and untagged warnings. Update existing tests as needed.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T08:41:27.024546-05:00","updated_at":"2025-10-21T13:46:17.688561-05:00","closed_at":"2025-10-21T13:46:17.688561-05:00","dependencies":[{"issue_id":"k-95","depends_on_id":"k-90","type":"discovered-from","created_at":"2025-10-21T08:41:27.026446-05:00","created_by":"cscheid"}]} -{"id":"k-96","title":"Consolidate qmd::read error reporting to DiagnosticMessage","description":"Refactor qmd::read to return Result\u003cParseResult, Vec\u003cDiagnosticMessage\u003e\u003e instead of Result\u003c(Pandoc, ASTContext), Vec\u003cString\u003e\u003e. Unify all error/warning types. See claude-notes/plans/2025-10-21-consolidate-to-diagnosticmessage.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-21T09:24:59.380974-05:00","updated_at":"2025-11-23T07:22:48.147789-06:00","closed_at":"2025-11-23T07:22:49.147789-06:00"} -{"id":"k-97","title":"Create produce_diagnostic_messages() function","description":"Add produce_diagnostic_messages() to qmd_error_messages.rs to convert tree-sitter parse errors to Vec\u003cDiagnosticMessage\u003e instead of Vec\u003cString\u003e","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T09:25:08.296798-05:00","updated_at":"2025-10-21T10:38:21.894018-05:00","closed_at":"2025-10-21T10:38:21.894018-05:00","dependencies":[{"issue_id":"k-97","depends_on_id":"k-96","type":"discovered-from","created_at":"2025-10-21T09:25:08.298159-05:00","created_by":"cscheid"}]} -{"id":"k-98","title":"Define ParseResult struct and update qmd::read signature","description":"Add ParseResult struct with pandoc, context, diagnostics. Update qmd::read to return Result\u003cParseResult, Vec\u003cDiagnosticMessage\u003e\u003e","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T09:25:16.000177-05:00","updated_at":"2025-10-21T10:29:13.893568-05:00","closed_at":"2025-10-21T10:29:13.893568-05:00","dependencies":[{"issue_id":"k-98","depends_on_id":"k-96","type":"discovered-from","created_at":"2025-10-21T09:25:16.001731-05:00","created_by":"cscheid"}]} -{"id":"k-99","title":"Convert all error returns in qmd::read to DiagnosticMessage","description":"Update tree-sitter errors, deep nesting errors, manual parse errors, AST conversion errors to all return DiagnosticMessage","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T09:25:23.062813-05:00","updated_at":"2025-10-21T10:29:21.878964-05:00","closed_at":"2025-10-21T10:29:21.878964-05:00","dependencies":[{"issue_id":"k-99","depends_on_id":"k-96","type":"discovered-from","created_at":"2025-10-21T09:25:23.065118-05:00","created_by":"cscheid"}]} -{"id":"k-9aj6","title":"Phase 3: AST Transformation Layer","description":"REVISED: Port critical Lua filters to Rust. Includes: Normalization transforms (Pandoc AST → Quarto extended AST), custom node parsing, figure/table handling, callout rendering, cross-reference system. Part of k-xlko.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-20T11:42:24.636072-06:00","updated_at":"2025-12-20T12:09:56.561644-06:00","dependencies":[{"issue_id":"k-9aj6","depends_on_id":"k-xlko","type":"parent-child","created_at":"2025-12-20T11:42:24.636931-06:00","created_by":"daemon"},{"issue_id":"k-9aj6","depends_on_id":"k-bk15","type":"blocks","created_at":"2025-12-20T11:42:47.546441-06:00","created_by":"daemon"}]} -{"id":"k-9jt4","title":"Improve coverage: schema/helpers.rs","description":"Session baseline: 74.35% line coverage. Target: beat baseline by adding tests to quarto-yaml-validation/src/schema/helpers.rs (currently 62.42% coverage).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T11:46:41.60604-06:00","updated_at":"2026-01-02T11:53:25.290075-06:00","closed_at":"2026-01-02T11:53:25.290075-06:00","dependencies":[{"issue_id":"k-9jt4","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T11:46:41.607217-06:00","created_by":"daemon"}]} -{"id":"k-9zwe","title":"Phase 1.2: Jupyter notebook conversion","description":"Phase 2: Execute request/reply - implement execute(), collect outputs from iopub","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-07T15:42:33.881706697Z","updated_at":"2026-01-07T19:24:55.234213344Z","closed_at":"2026-01-07T19:24:55.234213344Z","dependencies":[{"issue_id":"k-9zwe","depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-01-07T15:42:33.883222622Z","created_by":"cc"}]} -{"id":"k-a2nw","title":"quarto render should produce ariadne-style errors like pampa","description":"The quarto-core crate has its own QuartoError type that wraps strings, completely ignoring the rich DiagnosticMessage infrastructure from quarto-error-reporting.\n\n**Current state:**\n- `QuartoError::Parse(String)` - loses all structured error info\n- Diagnostics are converted to strings too early (in pipeline.rs)\n- SourceContext is discarded, so ariadne can't render source snippets\n- Tests can't check DiagnosticMessage structure\n\n**Expected behavior (what pampa does):**\n- Keep `Vec\u003cDiagnosticMessage\u003e` with full source locations\n- Only convert to string at CLI output time\n- Pass SourceContext for ariadne rendering\n\n**Required changes:**\n1. Refactor `QuartoError` to hold `Vec\u003cDiagnosticMessage\u003e` + source info\n2. Update `parse_qmd()` to return structured errors\n3. Update CLI to render diagnostics with SourceContext\n4. Write tests that check DiagnosticMessage structure directly\n\nPlan: claude-notes/plans/2025-12-28-quarto-core-error-infrastructure.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-28T15:23:49.171149-06:00","updated_at":"2025-12-28T15:59:15.646353-06:00","closed_at":"2025-12-28T15:59:15.646353-06:00","dependencies":[{"issue_id":"k-a2nw","depends_on_id":"k-i5nw","type":"blocks","created_at":"2025-12-28T15:23:49.172465-06:00","created_by":"daemon"}]} -{"id":"k-b1x1","title":"Phase 5: Engine Infrastructure","description":"REVISED (was Phase 5 HTML Postprocessing): Prepare for code execution. Define ExecutionEngine trait and registry, implement MarkdownEngine (passthrough), engine selection algorithm, freeze/thaw support, Jupyter engine placeholder. Part of k-xlko.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-20T11:42:26.563508-06:00","updated_at":"2025-12-20T12:09:58.811967-06:00","dependencies":[{"issue_id":"k-b1x1","depends_on_id":"k-xlko","type":"parent-child","created_at":"2025-12-20T11:42:26.564298-06:00","created_by":"daemon"},{"issue_id":"k-b1x1","depends_on_id":"k-yd14","type":"blocks","created_at":"2025-12-20T11:42:47.691387-06:00","created_by":"daemon"}]} -{"id":"k-bfp2","title":"Improve coverage: CSL/citeproc error modules","description":"Session baseline: 71.55% line coverage. Target: beat baseline. Testing error.rs modules in quarto-csl and quarto-citeproc crates (both at 0% coverage).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T11:33:43.799815-06:00","updated_at":"2026-01-01T11:41:53.887269-06:00","closed_at":"2026-01-01T11:41:53.887269-06:00","dependencies":[{"issue_id":"k-bfp2","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-01T11:33:43.801232-06:00","created_by":"daemon"}]} -{"id":"k-bk15","title":"Phase 2: Dependency System (CSS, JS, Resources)","description":"REVISED: Support CSS, JS, and resource dependencies. Includes: SASS compilation via dart-sass, dependency injection (copy to lib/, inject script/link tags), resource discovery for images/data files. Part of k-xlko.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-20T11:42:23.055014-06:00","updated_at":"2025-12-20T12:09:54.697347-06:00","dependencies":[{"issue_id":"k-bk15","depends_on_id":"k-xlko","type":"parent-child","created_at":"2025-12-20T11:42:23.055807-06:00","created_by":"daemon"},{"issue_id":"k-bk15","depends_on_id":"k-6qau","type":"blocks","created_at":"2025-12-20T11:42:47.476298-06:00","created_by":"daemon"}]} -{"id":"k-btfo","title":"Remove dead treesitter_utils modules","description":"8 dead code files found in pampa/src/pandoc/treesitter_utils/: code_span.rs, inline_link.rs, image.rs, indented_code_block.rs, latex_span.rs, quoted_span.rs, raw_attribute.rs, raw_specifier.rs, setext_heading.rs. See report: claude-notes/reports/2026-01-01-dead-code-treesitter-utils.md","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T12:07:09.024728-06:00","updated_at":"2026-01-01T12:12:22.787341-06:00","closed_at":"2026-01-01T12:12:22.787341-06:00"} -{"id":"k-c1sk","title":"Improve coverage: pampa/src/utils/text.rs","description":"Current baseline: 71.87% line coverage. Target: pampa/src/utils/text.rs at 0% coverage (32 lines).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T11:45:51.717066-06:00","updated_at":"2026-01-01T11:49:51.261619-06:00","closed_at":"2026-01-01T11:49:51.261619-06:00","dependencies":[{"issue_id":"k-c1sk","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-01T11:45:51.719073-06:00","created_by":"daemon"}]} -{"id":"k-c6uj","title":"Phase 1.1: Jupyter core infrastructure","description":"Phase 1: Kernel lifecycle - add deps, create module structure, implement kernelspec discovery, kernel start/stop","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-07T15:42:32.875326323Z","updated_at":"2026-01-07T18:15:30.555039724Z","closed_at":"2026-01-07T18:15:30.555039724Z","dependencies":[{"issue_id":"k-c6uj","depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-01-07T15:42:32.876818878Z","created_by":"cc"}]} -{"id":"k-ct7i","title":"Improve coverage: citeproc_filter.rs","description":"Session baseline: 74.78% line coverage. Target: beat baseline. citeproc_filter.rs currently at 2.65% coverage (1101 of 1131 lines uncovered).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T13:01:37.747325-06:00","updated_at":"2026-01-02T13:12:09.524301-06:00","closed_at":"2026-01-02T13:12:09.524301-06:00","dependencies":[{"issue_id":"k-ct7i","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T13:01:37.748648-06:00","created_by":"daemon"}]} -{"id":"k-d4r0","title":"quarto-yaml: Capture tags on compound types (arrays/maps)","description":"The quarto-yaml crate currently only captures YAML tags on scalar values, not on compound types (arrays and maps).\n\n**Current behavior:**\n```yaml\nitems: !prefer [a, b] # Tag is NOT captured on the array\nconfig: !prefer {key: value} # Tag is NOT captured on the map\n```\n\n**Impact:**\n- `!prefer` tags on arrays/maps are silently ignored\n- This prevents proper merge semantics for compound types in config merging\n- Documented in pampa test: test_prefer_on_inline_array, test_prefer_on_inline_map\n\n**Files:**\n- crates/quarto-yaml/src/parser.rs (tag capture logic)\n- crates/quarto-yaml/src/yaml_with_source_info.rs (YamlWithSourceInfo struct)\n\n**Test documenting current behavior:**\ncrates/quarto-yaml/src/parser.rs:1249 - 'The tag is currently only captured for scalars, not sequences'","status":"open","priority":2,"issue_type":"bug","created_at":"2025-12-29T12:53:14.549566-06:00","updated_at":"2025-12-29T12:53:14.549566-06:00","dependencies":[{"issue_id":"k-d4r0","depends_on_id":"k-2tu9","type":"discovered-from","created_at":"2025-12-29T12:53:14.551289-06:00","created_by":"daemon"}]} -{"id":"k-dnfd","title":"Expose unified render pipeline for quarto crate and WASM","description":"The wasm-quarto-hub-client currently bypasses the quarto-core transform pipeline (callouts, metadata normalization, etc.) by calling pampa directly. We need to expose a unified render function from the quarto crate that both the CLI and WASM client can use, ensuring feature parity.\n\nPlan: claude-notes/plans/2025-12-27-unified-render-pipeline.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-27T10:50:10.528283-06:00","updated_at":"2025-12-27T11:43:49.771037-06:00","closed_at":"2025-12-27T11:43:49.771037-06:00"} -{"id":"k-dp9r","title":"Improve coverage: unified_filter.rs","description":"Session baseline: 74.68% line coverage. Target: beat baseline by adding tests for error Display implementations in unified_filter.rs (currently at 40.65% coverage).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T12:34:05.717593-06:00","updated_at":"2026-01-02T12:38:51.272709-06:00","closed_at":"2026-01-02T12:38:51.272709-06:00","dependencies":[{"issue_id":"k-dp9r","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T12:34:05.719914-06:00","created_by":"daemon"}]} -{"id":"k-dqce","title":"Phase 4: CLI integration for templates","description":"Add CLI options (--template, --template-bundle, --body-format), embed built-in templates, add export-template subcommand, update main.rs routing.","status":"in_progress","priority":1,"issue_type":"task","created_at":"2025-12-05T11:44:28.727559-06:00","updated_at":"2025-12-05T11:54:27.284787-06:00","dependencies":[{"issue_id":"k-dqce","depends_on_id":"k-y2f3","type":"blocks","created_at":"2025-12-05T11:44:28.729222-06:00","created_by":"cscheid"},{"issue_id":"k-dqce","depends_on_id":"k-5u7d","type":"blocks","created_at":"2025-12-05T11:45:03.917294-06:00","created_by":"cscheid"}]} -{"id":"k-enqe","title":"Phase 1.4: JupyterEngine trait implementation","description":"Phase 4: AST integration - JupyterEngine as AstTransform, CodeBlock extraction and replacement","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-07T15:42:37.102402981Z","updated_at":"2026-01-07T19:25:00.147917236Z","closed_at":"2026-01-07T19:25:00.147917236Z","dependencies":[{"issue_id":"k-enqe","depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-01-07T15:42:37.103907029Z","created_by":"cc"}]} -{"id":"k-evpj","title":"Add presence features (cursors, selections) to quarto-hub","description":"Implement collaborative presence features showing other users' cursors and selections in real-time. Leverage Monaco's decoration/cursor APIs and Automerge's ephemeral messaging for presence state.\n\nPlan: claude-notes/plans/2025-12-28-presence-features.md","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2025-12-28T11:15:53.016124-06:00","updated_at":"2025-12-28T12:12:25.636523-06:00"} -{"id":"k-fgyv","title":"Design Python filter integration for quarto-markdown-pandoc","description":"Explore feasibility and design architecture for native Python filters that can run in-process, similar to Lua filters. Goals: (1) leverage existing Python interpreter or embed libpython, (2) build Python package with entry points to quarto-markdown-pandoc, (3) provide comparable dev experience to Lua filters with walk() methods and AST node constructors.\n\n**Plan document:** claude-notes/plans/2025-12-06-python-filter-integration.md","status":"open","priority":1,"issue_type":"feature","created_at":"2025-12-06T12:46:57.081157-06:00","updated_at":"2025-12-06T12:52:28.741554-06:00"} -{"id":"k-g9uc","title":"Property testing framework for CommonMark subset validation","description":"Design and implement a property testing framework using proptest to verify that generated Pandoc ASTs roundtrip correctly through qmd writer → qmd reader and comrak parser. This provides stronger coverage than hand-written differential tests by generating arbitrary valid inputs.","notes":"See claude-notes/plans/2025-12-16-property-testing-commonmark-subset.md for full design.\n\nAPPROACH: Feature set-based generators that progressively add complexity.\n\nFEATURE SET DESIGN:\n- Generator takes a set of enabled features (InlineFeatures, BlockFeatures)\n- When using a feature (e.g., Emph), recurse with that feature removed\n- Elegantly prevents Emph-inside-Emph and naturally limits nesting depth\n- Enables progressive complexity testing\n\nINLINE PROGRESSION (L0-L7):\nL0: Plain text (Str, Space, SoftBreak)\nL1: + Emph\nL2: + Strong\nL3: + Code\nL4: + Link\nL5: + Image\nL6: + Autolink\nL7: + LineBreak\n\nBLOCK PROGRESSION (B0-B6):\nB0: Paragraph only\nB1: + Header\nB2: + CodeBlock\nB3: + HorizontalRule\nB4: + BlockQuote (recursive)\nB5: + BulletList (recursive)\nB6: + OrderedList\n\nIMPLEMENTATION: 7 phases with checkpoints after each level\n- Each phase adds features and verifies tests pass before proceeding\n- Progressive approach helps isolate which features cause failures\n\nNORMALIZATION:\n- Strip heading IDs\n- Figure → Paragraph(Image)\n- Strip autolink uri class\n- Strip extra code block attributes","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-16T16:46:33.219368-06:00","updated_at":"2025-12-16T16:59:48.737986-06:00","dependencies":[{"issue_id":"k-g9uc","depends_on_id":"k-333","type":"parent-child","created_at":"2025-12-16T16:46:33.221733-06:00","created_by":"daemon"}]} -{"id":"k-giyy","title":"Investigate style differences between WASM and CLI rendering","description":"Implement artifact system for WASM rendering to match CLI styling.\n\n**Plan:** claude-notes/plans/2025-12-27-wasm-css-styling.md\n\n**Architecture:**\n1. Render pipeline stores CSS/resources as artifacts with paths under /.quarto/project-artifacts/\n2. WASM populates VFS with artifacts after render\n3. React post-processor replaces artifact links with data URIs on iframe load\n4. Same pattern handles .qmd link navigation\n\n**Status:** Plan approved, ready for implementation","status":"in_progress","priority":1,"issue_type":"task","created_at":"2025-12-27T12:09:24.254333-06:00","updated_at":"2025-12-27T12:32:51.150423-06:00"} -{"id":"k-gv05","title":"Fix nondeterministic sourceInfoPool IDs in JSON writer","description":"The yaml-tags snapshot test fails intermittently on Linux CI but passes on macOS. Root cause: pointer-based cache in SourceInfoSerializer returns stale IDs when memory addresses are reused. See plan: claude-notes/plans/2026-01-02-yaml-tags-nondeterminism-analysis.md","status":"open","priority":1,"issue_type":"bug","created_at":"2026-01-02T17:34:50.502156-06:00","updated_at":"2026-01-02T17:35:41.41512-06:00"} -{"id":"k-h66w","title":"Phase 2.2: Jupyter daemon integration","description":"Implement daemon client, kernel session reuse, daemon options","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-07T15:42:59.945361516Z","updated_at":"2026-01-07T19:25:02.064190971Z","closed_at":"2026-01-07T19:25:02.064190971Z","dependencies":[{"issue_id":"k-h66w","depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-01-07T15:42:59.94830732Z","created_by":"cc"}]} -{"id":"k-hb9f","title":"Remove dead code: treesitter_utils helper files","description":"Six treesitter_utils helper files are declared in mod.rs but never imported or used:\n\n1. attribute.rs (16 lines) - superseded by inline handling in treesitter.rs\n2. backslash_escape.rs (15 lines) - handled by process_backslash_escapes in text_helpers\n3. html_comment.rs (12 lines) - 'comment' case returns IntermediateUnknown\n4. key_value_specifier.rs (22 lines) - handled inline at line 928 in treesitter.rs\n5. link_title.rs (12 lines) - 'title' case handled inline at line 1013\n6. note_reference.rs (20 lines) - 'inline_note_reference' handled inline at line 784\n\nTotal: ~97 lines of dead code that inflate uncovered line counts.\nEvidence: grep -r 'module::' finds no imports for these modules.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-01-02T09:36:23.945641-06:00","updated_at":"2026-01-02T09:41:52.744353-06:00","closed_at":"2026-01-02T09:41:52.744353-06:00"} -{"id":"k-hqyf","title":"Add convenience accessors (identifier, classes, attributes) for inline elements with attr","description":"Inline elements with attr (Span, Code, Link, Image, Insert, Delete, Highlight, EditComment) are missing convenience getters/setters for identifier, classes, and attributes fields. Block elements (CodeBlock, Header, Div) have these, and LuaAttr has them, but inline elements don't. This breaks Pandoc Lua API compatibility.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-01-02T15:00:41.989146-06:00","updated_at":"2026-01-02T15:05:17.263951-06:00","closed_at":"2026-01-02T15:05:17.263951-06:00"} -{"id":"k-i5nw","title":"Monaco editor diagnostic squiggles from QMD parse errors","description":"Surface structured DiagnosticMessage errors from WASM rendering to Monaco editor as inline squiggles/markers, replacing the current plain text error display.\n\nPlan: claude-notes/plans/2025-12-28-monaco-diagnostics.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-28T15:17:48.343533-06:00","updated_at":"2025-12-28T17:05:27.665775-06:00","closed_at":"2025-12-28T17:05:27.665775-06:00"} -{"id":"k-ic1o","title":"Integrate ConfigValue into ProjectConfig and render pipeline","description":"Implement the configuration merging infrastructure needed for matched scrolling and future features.\n\nThis is a prerequisite for k-suww (matched scrolling).\n\nKey changes:\n1. Create quarto-config crate with ConfigValue and MergedConfig types (subset of design in 2025-12-07-config-merging-design.md)\n2. Replace ProjectConfig.raw: serde_json::Value with ConfigValue\n3. Update render_qmd_to_html to merge project config with document metadata\n4. Allow WASM renderer to inject config into ProjectContext\n\nThis enables:\n- Source location tracking controlled via project config (not document metadata injection)\n- Future format-specific settings controlled at project level\n- Clean separation between project defaults and document overrides\n\nPlan: claude-notes/plans/2025-12-29-config-integration-pipeline.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-29T10:25:44.563423-06:00","updated_at":"2025-12-29T22:08:59.618876-06:00","closed_at":"2025-12-29T22:08:59.618876-06:00","dependencies":[{"issue_id":"k-ic1o","depends_on_id":"k-suww","type":"blocks","created_at":"2025-12-29T10:25:44.565339-06:00","created_by":"daemon"}]} -{"id":"k-ifux","title":"Implement IndexedDB schema versioning and migration system","description":"Create a robust schema versioning system for the hub-client IndexedDB storage. Support both structural changes (new stores/indexes) via IndexedDB native upgrade and data transformations via application-level migrations. This is a prerequisite for adding user identity storage for presence features.\n\nParent issue: k-evpj (presence features)\nPlan: claude-notes/plans/2025-12-28-indexeddb-schema-versioning.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-28T11:37:57.936839-06:00","updated_at":"2025-12-28T12:01:12.646463-06:00","closed_at":"2025-12-28T12:01:12.646463-06:00","dependencies":[{"issue_id":"k-ifux","depends_on_id":"k-evpj","type":"related","created_at":"2025-12-28T11:37:57.937778-06:00","created_by":"daemon"}]} -{"id":"k-igxc","title":"Improve coverage: citeproc_filter.rs (continued)","description":"Session baseline: 75.16% line coverage. Target: beat baseline. citeproc_filter.rs currently at 42.23% coverage. Focus on extract_references, extract_names, extract_date, collect_citations, and insert_bibliography.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T13:58:55.445255-06:00","updated_at":"2026-01-02T14:06:51.694953-06:00","closed_at":"2026-01-02T14:06:51.694953-06:00","dependencies":[{"issue_id":"k-igxc","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T13:58:55.446518-06:00","created_by":"daemon"}]} -{"id":"k-igyi","title":"comrak-to-pandoc: Missing Space inline handling in conversion","description":"Property testing revealed that comrak-to-pandoc conversion produces different ASTs than pampa for input with whitespace before styled text. Comrak produces [Str(\"aA\"), Emph(...)] while pampa produces [Str(\"aA\"), Space, Emph(...)]. Need to investigate whether comrak's AST contains the space and we're losing it in conversion.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-16T17:16:40.1214-06:00","updated_at":"2025-12-16T17:27:03.039945-06:00","closed_at":"2025-12-16T17:27:03.039945-06:00","dependencies":[{"issue_id":"k-igyi","depends_on_id":"k-g9uc","type":"discovered-from","created_at":"2025-12-16T17:16:40.123882-06:00","created_by":"daemon"}]} -{"id":"k-j7by","title":"Improve coverage: quarto-yaml-validation/src/error.rs","description":"Session baseline: 71.24% line coverage. Target: beat baseline by testing error types in quarto-yaml-validation.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T11:05:24.734762-06:00","updated_at":"2026-01-01T11:12:44.264491-06:00","closed_at":"2026-01-01T11:12:44.264491-06:00","dependencies":[{"issue_id":"k-j7by","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-01T11:05:24.73602-06:00","created_by":"daemon"}]} -{"id":"k-jocn","title":"Phase 1.3: Jupyter subprocess execution","description":"Phase 3: Output conversion - Media → AST blocks (text, images, html)","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-07T15:42:35.586066838Z","updated_at":"2026-01-07T19:24:57.48498844Z","closed_at":"2026-01-07T19:24:57.48498844Z","dependencies":[{"issue_id":"k-jocn","depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-01-07T15:42:35.58776754Z","created_by":"cc"}]} -{"id":"k-js4l","title":"Remove dead code: code_span.rs","description":"code_span.rs is never imported or used. It was superseded by code_span_helpers.rs. Should be removed to clean up codebase.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-01-01T12:03:29.791259-06:00","updated_at":"2026-01-01T12:07:15.030512-06:00","closed_at":"2026-01-01T12:07:15.030512-06:00"} -{"id":"k-jut5","title":"Improve coverage: html_source.rs source map tests","description":"Session baseline: 76.36% line coverage. Final: 76.72%. Added 34 integration tests for build_source_map exercising various block and inline types.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-03T14:40:25.061265-06:00","updated_at":"2026-01-03T14:40:30.304193-06:00","closed_at":"2026-01-03T14:40:30.304193-06:00","dependencies":[{"issue_id":"k-jut5","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-03T14:40:25.062859-06:00","created_by":"daemon"}]} -{"id":"k-k803","title":"Improve coverage: metadata_normalize.rs","description":"Session baseline: 77.08% line coverage. Target file: quarto-core/src/transforms/metadata_normalize.rs at 51.77%. Goal: beat baseline.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-03T16:04:01.971759-06:00","updated_at":"2026-01-03T16:13:59.526466-06:00","closed_at":"2026-01-03T16:13:59.526466-06:00","dependencies":[{"issue_id":"k-k803","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-03T16:04:01.973728-06:00","created_by":"daemon"}]} -{"id":"k-kaaq","title":"Improve coverage: pandoc/location.rs","description":"Session baseline: 75.05% line coverage. Target: beat baseline. location.rs currently at 63.91% coverage (61 of 169 lines uncovered).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T13:26:43.887842-06:00","updated_at":"2026-01-02T13:31:48.152479-06:00","closed_at":"2026-01-02T13:31:48.152479-06:00","dependencies":[{"issue_id":"k-kaaq","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T13:26:43.888936-06:00","created_by":"daemon"}]} -{"id":"k-ke2m","title":"Filesystem synchronization design for quarto-hub","description":"Design the bidirectional synchronization between filesystem (.qmd files) and automerge documents.\n\n## Core Design: Unified Sync Algorithm\n\nA single fork-and-merge algorithm handles ALL sync scenarios (startup, shutdown, periodic, user-triggered):\n\n1. Fork doc at last sync checkpoint\n2. Apply filesystem content to fork via update_text (Myers diff)\n3. Merge fork back into main doc (CRDT merge)\n4. Write merged result to filesystem\n5. Update checkpoint\n\nThis naturally handles: no changes (no-op), automerge-only changes, filesystem-only changes, and true divergence (three-way merge).\n\n## Key Decisions\n- Automerge update_text handles diffing internally (grapheme-aware Myers)\n- Sync state stored locally in sync-state.json (not synced to peers)\n- Algorithm converges: after sync, fs and automerge match\n\n## Related Issues\n- k-r2t1 (filesystem serialization strategy)\n- k-yvfo (conflict resolution for divergence)\n\nDesign document: claude-notes/plans/2025-12-09-filesystem-sync-design.md","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-09T15:56:36.732287-06:00","updated_at":"2025-12-09T16:53:24.323101-06:00","dependencies":[{"issue_id":"k-ke2m","depends_on_id":"k-4wex","type":"discovered-from","created_at":"2025-12-09T15:56:36.733851-06:00","created_by":"cscheid"}]} -{"id":"k-kh5i","title":"Jupyter engine implementation","description":"Implement Jupyter execution engine as AstTransform using pure Rust via runtimelib/jupyter-protocol (no Python subprocess orchestration). Features: in-process daemon with tokio, ZeroMQ kernel communication, inline expression evaluation. See plan: claude-notes/plans/2026-01-07-jupyter-engine-implementation.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-01-07T15:42:15.691802744Z","updated_at":"2026-01-07T19:25:14.619299804Z","closed_at":"2026-01-07T19:25:14.619299804Z"} -{"id":"k-kswp","title":"Phase 4: quarto-yaml integration","description":"Extend quarto-yaml tag parsing to recognize !prefer and !concat. Ensure tags flow through to YamlWithSourceInfo.tag field. Integrate error handling with DiagnosticCollector. Plan: claude-notes/plans/2025-12-07-config-merging-design.md Phase 4","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T14:03:57.230535-06:00","updated_at":"2025-12-07T14:32:45.993075-06:00","closed_at":"2025-12-07T14:32:45.993075-06:00","dependencies":[{"issue_id":"k-kswp","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2025-12-07T14:03:57.232276-06:00","created_by":"cscheid"}]} -{"id":"k-lckc","title":"Use quarto-error-reporting crate uniformly for render pipeline errors and warnings","description":"The render pipeline (quarto-core, quarto render command) currently uses ad-hoc error handling. Should integrate with quarto-error-reporting crate for consistent, user-friendly error messages and warnings throughout the rendering process.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-21T12:19:34.525509-06:00","updated_at":"2025-12-21T12:19:34.525509-06:00"} -{"id":"k-libc","title":"Automerge schema design for quarto-hub","description":"Design the automerge schema for: (1) the project index document mapping file paths to doc-ids, (2) individual .qmd document representation. Consider what data structures work well with CRDTs.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-08T13:24:44.089038-06:00","updated_at":"2025-12-08T13:24:44.089038-06:00","dependencies":[{"issue_id":"k-libc","depends_on_id":"k-4wex","type":"related","created_at":"2025-12-08T13:24:44.091758-06:00","created_by":"cscheid"}]} -{"id":"k-m46n","title":"Design PipelineStage abstraction for full render pipeline","description":"Design explicit PipelineStage struct and variants to represent all stages of Quarto document rendering - from source file conversion through AST transformation to output generation and postprocessing. This enables validation, orchestration, and different stage sequences for different file types.\n\n**Plan**: claude-notes/plans/2026-01-06-pipeline-stage-design.md\n\n**Related analyses**:\n- claude-notes/render-pipeline/single-document/README.md\n- claude-notes/plans/lua-filter-pipeline/00-index.md\n- claude-notes/plans/2025-12-27-unified-render-pipeline.md","status":"open","priority":1,"issue_type":"feature","created_at":"2026-01-06T16:13:42.692768183Z","updated_at":"2026-01-06T16:15:37.258355308Z"} -{"id":"k-mapj","title":"Implement list-table div to Pandoc table desugaring and reverse transformation","description":"Add postprocessing transformation to convert list-table divs to Pandoc table ASTs (reader direction) and add qmd writer transformation to convert complex tables back to list-table divs (writer direction). Only use list-table format when pipe tables are insufficient.\n\nPlan: claude-notes/plans/2025-12-05-list-table-implementation.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-05T09:11:18.944162-06:00","updated_at":"2025-12-05T09:51:02.454702-06:00","closed_at":"2025-12-05T09:51:02.454702-06:00"} -{"id":"k-mr16","title":"Improve coverage: schema/parsers/combinators.rs","description":"Session baseline: 74.59% overall. Target: combinators.rs currently at 64.17% coverage. Add tests for error paths in anyOf, allOf, and maybeArrayOf parsers.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T12:07:14.481032-06:00","updated_at":"2026-01-02T12:11:54.401607-06:00","closed_at":"2026-01-02T12:11:54.401607-06:00","dependencies":[{"issue_id":"k-mr16","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T12:07:14.482286-06:00","created_by":"daemon"}]} -{"id":"k-muo0","title":"Remove dead code: raw_attribute.rs","description":"File pampa/src/pandoc/treesitter_utils/raw_attribute.rs (26 lines) is never called. The inline grammar produces attribute_specifier containing raw_specifier (not raw_attribute). The raw_specifier is handled directly in treesitter.rs lines 1042-1054.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-01-03T13:42:48.23357-06:00","updated_at":"2026-01-03T13:45:19.773692-06:00","closed_at":"2026-01-03T13:45:19.773692-06:00"} -{"id":"k-n74s","title":"Add CommonMark reader to pampa using comrak-to-pandoc","description":"Add a --from commonmark option to pampa that uses comrak for parsing. This leverages the comrak-to-pandoc crate we built for property testing. Key enhancement: add source location tracking from comrak Sourcepos to quarto-source-map SourceInfo.\n\nPlan: claude-notes/plans/2025-12-17-commonmark-reader-for-pampa.md","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-17T13:13:21.737988-06:00","updated_at":"2025-12-17T13:14:33.644673-06:00"} -{"id":"k-nkhl","title":"Abstract filesystem access in quarto-core for WASM compatibility","description":"Introduce a QuartoRuntime trait similar to LuaRuntime that abstracts filesystem access, environment, and binary discovery. This enables quarto render to run in WASM environments with a virtual filesystem.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-22T15:08:47.310583-06:00","updated_at":"2025-12-22T18:58:52.580617-06:00","closed_at":"2025-12-22T18:58:52.580617-06:00","dependencies":[{"issue_id":"k-nkhl","depends_on_id":"k-0sdx","type":"parent-child","created_at":"2025-12-22T15:08:47.311398-06:00","created_by":"daemon"}]} -{"id":"k-nwcy","title":"Improve preview pane behavior on markdown syntax errors","description":"Change preview pane to retain last good render when syntax errors occur during editing, showing errors as overlay instead of replacing content. Implements a 4-state machine: START, ERROR_AT_START, GOOD, ERROR_FROM_GOOD.\n\nPlan document: claude-notes/plans/2026-01-08-preview-error-state-machine.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-01-08T14:40:30.205021-06:00","updated_at":"2026-01-08T14:57:44.114865-06:00","closed_at":"2026-01-08T14:57:44.114865-06:00"} -{"id":"k-o399","title":"quarto-doctemplate produces extra newlines vs Pandoc's doctemplates","description":"quarto-doctemplate produces extra newlines in template output compared to Pandoc's doctemplates. This affects multiline $if$/$for$ directives where newlines after opening/closing directives should be consumed. See plan: claude-notes/plans/2025-12-06-doctemplate-newline-fix.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-06T12:11:43.863481-06:00","updated_at":"2025-12-06T12:28:32.985751-06:00","closed_at":"2025-12-06T12:28:32.985751-06:00"} -{"id":"k-oomv","title":"ExecutionEngine trait and engine detection","description":"Implement ExecutionEngine trait, engine detection from .qmd metadata, and engine execution pipeline stage. Support markdown (default), knitr, and jupyter engines.\n\nPlan: claude-notes/plans/2026-01-06-execution-engine-infrastructure.md\n\n## Progress\n\n### Phase 1 (Core Infrastructure) ✅\n- ExecutionEngine trait implemented\n- Engine detection from metadata (all YAML variants)\n- EngineRegistry with native/WASM gating\n- MarkdownEngine (no-op passthrough)\n- KnitrEngine and JupyterEngine placeholders (native-only)\n- All unit tests passing\n\n### Phase 2 (Pipeline Integration) ✅\n- EngineExecutionStage implemented\n- Stage wired into stages module\n- End-to-end markdown engine works\n- WASM build verified working\n- Fallback behavior with warnings for unknown engines\n\n### Phase 3 (Source Location Reconciliation) ✅\n- reconcile_source_locations function implemented\n- Content equality comparison for blocks and inlines\n- Block/inline matching with limited lookahead alignment\n- ReconciliationReport tracking exact matches, structural matches, additions, deletions\n- All reconciliation tests passing (96 engine tests total)\n\n### Remaining Work\n- Phase 4: Knitr engine implementation (future)\n- Phase 5: Jupyter engine implementation (future)","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-01-06T22:56:20.543548335Z","updated_at":"2026-01-07T19:25:16.261135141Z","closed_at":"2026-01-07T19:25:16.261135141Z"} -{"id":"k-os6h","title":"Define error handling strategy for config merging","description":"Define behavior for error conditions during config merging: 1) YAML parsing failures in individual layers, 2) Syntactically invalid/malformed tags, 3) Memory/stack overflow from deeply nested configs, 4) Boundary documentation for out-of-scope errors (circular includes). Plan file: claude-notes/plans/2025-12-07-config-error-handling.md","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T11:06:46.867359-06:00","updated_at":"2025-12-07T14:03:11.132977-06:00","closed_at":"2025-12-07T14:03:11.132977-06:00","dependencies":[{"issue_id":"k-os6h","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2025-12-07T11:06:46.869362-06:00","created_by":"cscheid"}]} -{"id":"k-p39g","title":"Non-deterministic test failures due to HashMap usage","description":"Tests test_chicago_author_date_style, test_bibliography_delimiters, and yaml-tags snapshot are failing due to non-deterministic behavior. Likely caused by HashMap usage where LinkedHashMap should be used.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-31T16:47:46.526333-06:00","updated_at":"2025-12-31T17:28:34.047474-06:00","closed_at":"2025-12-31T17:28:34.047474-06:00"} -{"id":"k-p4gl","title":"Phase 2.1: Jupyter daemon infrastructure","description":"Design daemon protocol, implement JupyterDaemon struct, transport file management","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-07T15:42:59.036272974Z","updated_at":"2026-01-07T19:25:01.283740946Z","closed_at":"2026-01-07T19:25:01.283740946Z","dependencies":[{"issue_id":"k-p4gl","depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-01-07T15:42:59.037648693Z","created_by":"cc"}]} -{"id":"k-p4nu","title":"Audit anyhow::anyhow\\! usages for error structure loss","description":"Several places in the codebase use anyhow::anyhow\\!() in ways that lose structured error information. This issue tracks reviewing and potentially fixing these patterns.\n\n## Problematic Patterns Found\n\n### qmd-syntax-helper crate\n\n1. **syntax_check.rs:89** - Joins error strings and wraps in anyhow:\n ```rust\n let error_msg = errors.join(\"\\n\");\n Err(anyhow::anyhow\\!(\"{}\", error_msg))\n ```\n\n2. **grid_tables.rs:137** - Uses debug format on diagnostics:\n ```rust\n anyhow::anyhow\\!(\"Failed to write markdown output: {:?}\", diagnostics)\n ```\n\n3. **definition_lists.rs:190** - Same issue as grid_tables.rs\n\n### validate-yaml crate\n\n- Uses anyhow for simple CLI errors, likely acceptable for a validation tool.\n\n## Recommended Actions\n\n1. For qmd-syntax-helper: Consider using proper diagnostic rendering with `to_text()` instead of debug format\n2. Review if these tools need the same rich error display as the main CLI\n3. Consider creating a shared error display utility\n\n## Notes\n\n- Simple IO/path errors using anyhow are acceptable\n- The main render.rs:201 issue was fixed separately (handled parse errors specially to avoid duplicate 'Error:' prefix)","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-28T16:38:54.778863-06:00","updated_at":"2025-12-28T16:38:54.778863-06:00"} -{"id":"k-p80n","title":"Add type/version field to index document for client validation","description":"When connecting to a sync server, the client currently has no way to verify that a document ID points to an index document vs a file document. Add a 'type' or 'version' field to the index document structure (e.g., {type: 'quarto-hub-index', version: 1, files: {...}}) so clients can validate they're connecting to the correct document and show a helpful error message if not.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-22T20:12:42.733023-06:00","updated_at":"2025-12-22T20:12:42.733023-06:00"} -{"id":"k-q4rm","title":"HTML writer source tracking implementation - pointer-based AST annotation","description":"Implement source location tracking in HTML writer using pointer-based AST node identification. Uses JSON writer output + parallel walk to build location map. See plan: claude-notes/plans/2025-12-21-html-source-tracking-implementation.md","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-21T15:57:32.879272-06:00","updated_at":"2025-12-21T15:57:32.879272-06:00","dependencies":[{"issue_id":"k-q4rm","depends_on_id":"k-02o9","type":"discovered-from","created_at":"2025-12-21T15:57:32.881077-06:00","created_by":"daemon"}]} -{"id":"k-r2t1","title":"Filesystem serialization strategy for quarto-hub","description":"Design how/when automerge state is serialized back to .qmd files on disk. Consider: continuous sync, on-demand save, periodic snapshots, conflict with external edits.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-08T13:24:50.277282-06:00","updated_at":"2025-12-08T13:24:50.277282-06:00","dependencies":[{"issue_id":"k-r2t1","depends_on_id":"k-4wex","type":"related","created_at":"2025-12-08T13:24:50.279298-06:00","created_by":"cscheid"}]} -{"id":"k-rem3","title":"Improve coverage: lua/types.rs","description":"Session baseline: 75.59% line coverage. lua/types.rs currently at 23.60% coverage. Focus on tag_name(), field_names(), get_field(), set_field(), and meta value conversion.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T14:10:08.467544-06:00","updated_at":"2026-01-02T14:20:07.712645-06:00","closed_at":"2026-01-02T14:20:07.712645-06:00","dependencies":[{"issue_id":"k-rem3","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T14:10:08.468967-06:00","created_by":"daemon"}]} -{"id":"k-riq2","title":"Phase 1: Create quarto-config crate with core types","description":"Create quarto-config crate skeleton with: MergeOp, Interpretation, ConfigValueKind, ConfigValue types. Implement tag parsing with error handling (Q-1-21 through Q-1-28). Implement From\u003cYamlWithSourceInfo\u003e and From\u003cMetaValueWithSourceInfo\u003e. Add error codes to error_catalog.json. Write unit tests. Plan: claude-notes/plans/2025-12-07-config-merging-design.md Phase 1","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-07T14:03:24.301377-06:00","updated_at":"2025-12-07T14:09:59.964477-06:00","closed_at":"2025-12-07T14:09:59.964477-06:00","dependencies":[{"issue_id":"k-riq2","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2025-12-07T14:03:24.303508-06:00","created_by":"cscheid"}]} -{"id":"k-rmdm","title":"Monaco cursor shifts when remote collaborator edits document","description":"In collaborative editing sessions, when a remote collaborator makes changes to the document, the local user's cursor position shifts unexpectedly. This degrades the collaborative editing UX significantly as users lose their place while typing.\n\nPlan document: claude-notes/plans/2025-12-28-fix-monaco-cursor-shift.md\n\nRoot cause: The system passes full document content from Automerge to Monaco on every remote change. Monaco has no knowledge of what changed or where, so it cannot preserve cursor position.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-28T09:32:23.697592-06:00","updated_at":"2025-12-28T10:05:55.349648-06:00","closed_at":"2025-12-28T10:05:55.349648-06:00"} -{"id":"k-rqsx","title":"Improve coverage: quarto-pandoc-types/src/inline.rs","description":"Session baseline: 74.02% line coverage. File at 61.11%. Focus on is_empty_target, make_span_inline branches, AsInline trait.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T11:18:01.085401-06:00","updated_at":"2026-01-02T11:22:31.77987-06:00","closed_at":"2026-01-02T11:22:31.77987-06:00"} -{"id":"k-sc44","title":"Phase 6: Performance and polish","description":"Benchmark against TypeScript mergeConfigs. Profile and optimize hot paths. Consider caching if needed. Documentation. Plan: claude-notes/plans/2025-12-07-config-merging-design.md Phase 6","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-07T14:04:10.627776-06:00","updated_at":"2025-12-07T14:04:10.627776-06:00","dependencies":[{"issue_id":"k-sc44","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2025-12-07T14:04:10.629309-06:00","created_by":"cscheid"}]} -{"id":"k-se1i","title":"Improve coverage: code_span.rs treesitter utils","description":"Current baseline: 71.94% line coverage. Target: pampa/src/pandoc/treesitter_utils/code_span.rs at 0% coverage (107 lines).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T11:51:51.978644-06:00","updated_at":"2026-01-01T12:03:23.415423-06:00","closed_at":"2026-01-01T12:03:23.415423-06:00","dependencies":[{"issue_id":"k-se1i","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-01T11:51:51.980538-06:00","created_by":"daemon"}]} -{"id":"k-suww","title":"Implement matched scrolling between editor and preview in hub-client","description":"Add bidirectional scroll synchronization between Monaco editor and HTML preview pane.\n\nFeatures:\n- Editor cursor movement scrolls preview to show corresponding output (scroll only if not visible)\n- Preview scroll updates editor viewport (without moving cursor)\n- Single UI toggle in toolbar to enable/disable\n- 50ms debounce to prevent jitter\n\nImplementation requires:\n1. WASM pipeline enhancement to inject source-location metadata\n2. New useScrollSync React hook\n3. UI toggle component\n\nPlan: claude-notes/plans/2025-12-29-matched-scrolling-hub-client.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-12-29T09:47:48.736879-06:00","updated_at":"2025-12-30T09:04:55.815946-06:00","closed_at":"2025-12-30T09:04:55.815946-06:00"} -{"id":"k-thpl","title":"Port Lua filter infrastructure to Rust","description":"Port quarto-cli's Lua filter infrastructure (customnodes.lua, emulatedfilter.lua, runemulation.lua) to Rust. Includes: CustomNode trait, handler/renderer registries, slot-based storage, format-conditional rendering.\n\nPlans and Analysis:\n- Custom node design: claude-notes/plans/2025-12-20-lua-filter-infrastructure-porting.md\n- Pipeline analysis: claude-notes/plans/lua-filter-pipeline/00-index.md (full stage-by-stage analysis with side effects, Pandoc API usage, WASM compatibility)","status":"open","priority":1,"issue_type":"feature","created_at":"2025-12-20T12:26:52.227604-06:00","updated_at":"2025-12-20T15:21:06.462048-06:00","dependencies":[{"issue_id":"k-thpl","depends_on_id":"k-xlko","type":"parent-child","created_at":"2025-12-20T12:26:52.228768-06:00","created_by":"daemon"}]} -{"id":"k-tjdc","title":"Set up code coverage infrastructure","description":"Set up tooling to measure and report code coverage for the Rust workspace. Plan: claude-notes/plans/2025-12-31-code-coverage-infrastructure.md","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-31T09:37:16.009471-06:00","updated_at":"2025-12-31T09:50:38.721023-06:00","closed_at":"2025-12-31T09:50:38.721023-06:00"} -{"id":"k-u1iy","title":"Phase 2: Writer integration for templates","description":"Create body rendering helpers (render_body_html, render_body_plaintext) and metadata rendering helpers (render_inlines_html, render_blocks_html, etc.) that wrap existing writers for use in template context building.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T11:44:18.098177-06:00","updated_at":"2025-12-05T11:53:45.539905-06:00","closed_at":"2025-12-05T11:53:45.539905-06:00","dependencies":[{"issue_id":"k-u1iy","depends_on_id":"k-y2f3","type":"blocks","created_at":"2025-12-05T11:44:18.101027-06:00","created_by":"cscheid"},{"issue_id":"k-u1iy","depends_on_id":"k-1c5v","type":"blocks","created_at":"2025-12-05T11:44:53.538004-06:00","created_by":"cscheid"}]} -{"id":"k-u5gt","title":"Phase 6: Template integration tests","description":"Unit tests for bundle.rs (JSON parsing), context.rs (MetaValue conversion), render.rs (full pipeline). Integration tests for end-to-end rendering, bundle vs filesystem modes.","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-05T11:44:39.51134-06:00","updated_at":"2025-12-05T11:44:39.51134-06:00","dependencies":[{"issue_id":"k-u5gt","depends_on_id":"k-y2f3","type":"blocks","created_at":"2025-12-05T11:44:39.513163-06:00","created_by":"cscheid"},{"issue_id":"k-u5gt","depends_on_id":"k-1c5v","type":"blocks","created_at":"2025-12-05T11:45:14.268552-06:00","created_by":"cscheid"}]} -{"id":"k-u909","title":"Improve coverage: quarto-pandoc-types/src/config_value.rs","description":"Session baseline: 72.93% line coverage. Target: beat baseline. Focus on serialization, constructors, and accessor methods.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T09:58:52.382041-06:00","updated_at":"2026-01-02T10:05:28.986193-06:00","closed_at":"2026-01-02T10:05:28.986193-06:00","dependencies":[{"issue_id":"k-u909","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T09:58:52.384335-06:00","created_by":"daemon"}]} -{"id":"k-uoc5","title":"Improve code coverage across workspace","description":"Epic to track code coverage improvement work. Goal: achieve as close to 100% coverage as practical.\n\nCurrent baseline (2025-12-31): 69.62% line coverage, 73.89% function coverage.\n\nWorkflow: claude-notes/workflows/code-coverage-improvement.md\nPlan: claude-notes/plans/2025-12-31-code-coverage-infrastructure.md","status":"open","priority":2,"issue_type":"epic","created_at":"2025-12-31T10:01:53.804686-06:00","updated_at":"2025-12-31T10:01:53.804686-06:00"} -{"id":"k-uvvm","title":"Phase 6: Config merging performance \u0026 polish","description":"Performance optimization and polish for the quarto-config merging system.\n\n## Context\n\nThis is Phase 6 of the config merging implementation plan documented in:\n- claude-notes/plans/2025-12-07-config-merging-design.md\n\nPhases 1-5 are complete:\n- Phase 1: quarto-config crate with types, tag parsing, conversion\n- Phase 2: Cursor-based navigation (MergedConfig, MergedCursor)\n- Phase 3: Materialization and error handling\n- Phase 4: quarto-yaml integration (underscore-separated tags)\n- Phase 5: pampa integration (template defaults merging)\n\n## Work Items\n\n### Benchmarking\n- [ ] Create benchmarks comparing Rust implementation to TypeScript mergeConfigs\n- [ ] Measure materialization performance for various config sizes\n- [ ] Benchmark cursor navigation vs eager materialization\n\n### Performance Optimization\n- [ ] Profile hot paths in MergedConfig operations\n- [ ] Consider caching for frequently-accessed subtrees\n- [ ] Evaluate lazy vs eager strategies for different use cases\n- [ ] Optimize IndexMap usage patterns\n\n### Polish\n- [ ] Review and improve documentation\n- [ ] Add more examples to module docs\n- [ ] Consider adding convenience methods based on real usage patterns\n- [ ] Ensure error messages are clear and actionable\n\n### Future Consideration\n- [ ] Evaluate changing quarto-doctemplate to operate directly with MergedConfig (avoiding materialization)\n\n## Related Files\n- crates/quarto-config/src/*.rs (core implementation)\n- crates/pampa/src/template/config_merge.rs (pampa integration)\n- crates/pampa/tests/test_template_integration.rs (integration tests)","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-07T15:11:54.315717-06:00","updated_at":"2025-12-07T15:11:54.315717-06:00"} -{"id":"k-vku8","title":"Fix bibliography spacing in quarto-citeproc to_blocks() conversion","description":"The to_blocks() method in quarto-citeproc does not correctly apply CSL group delimiters when converting the Output AST to Pandoc blocks. This results in missing spacing/punctuation between elements (e.g., 'Alice2019' instead of 'Alice. 2019.').\\n\\nPlan: claude-notes/plans/2025-12-05-citeproc-output-spacing.md","status":"open","priority":1,"issue_type":"bug","created_at":"2025-12-05T16:42:14.443669-06:00","updated_at":"2025-12-05T16:42:14.443669-06:00","labels":["citeproc","output"]} -{"id":"k-vmwg","title":"Phase 2: Implement cursor-based navigation","description":"Implement MergedConfig\u003c'a\u003e, MergedCursor\u003c'a\u003e, MergedValue\u003c'a\u003e, MergedScalar\u003c'a\u003e, MergedArray\u003c'a\u003e, MergedMap\u003c'a\u003e. Implement navigation (at, at_path, exists, keys) and resolution (as_value, as_scalar, as_array, as_map). Property-based tests for associativity. Plan: claude-notes/plans/2025-12-07-config-merging-design.md Phase 2","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-07T14:03:44.486774-06:00","updated_at":"2025-12-07T14:23:53.601939-06:00","closed_at":"2025-12-07T14:23:53.601939-06:00","dependencies":[{"issue_id":"k-vmwg","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2025-12-07T14:03:44.489904-06:00","created_by":"cscheid"},{"issue_id":"k-vmwg","depends_on_id":"k-riq2","type":"blocks","created_at":"2025-12-07T14:03:44.491652-06:00","created_by":"cscheid"}]} -{"id":"k-vpgx","title":"Design MergedConfig\u003c'a\u003e lifetime and navigation API","description":"Detail the lifetime design for MergedConfig\u003c'a\u003e, including: 1) MergedMap\u003c'a\u003e and MergedArray\u003c'a\u003e structure, 2) Nested navigation API (get chaining), 3) MergedValue\u003c'a\u003e enum design, 4) Borrowed vs owned data handling. Parent: k-zvzm","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T11:06:35.783411-06:00","updated_at":"2025-12-07T14:03:04.849222-06:00","closed_at":"2025-12-07T14:03:04.849222-06:00","dependencies":[{"issue_id":"k-vpgx","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2025-12-07T11:06:35.786589-06:00","created_by":"cscheid"}]} -{"id":"k-w6sb","title":"Improve coverage: quarto-core/src/error.rs","description":"Session baseline: 73.58% line coverage. File at 69.57%. Focus on ParseError and QuartoError.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T10:43:14.831595-06:00","updated_at":"2026-01-02T10:46:18.557357-06:00","closed_at":"2026-01-02T10:46:18.557357-06:00","dependencies":[{"issue_id":"k-w6sb","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T10:43:14.832882-06:00","created_by":"daemon"}]} -{"id":"k-xlko","title":"Prototype minimal quarto render for Rust port","description":"Implement a minimal, incrementally-improvable 'quarto render' command in the Rust port. Starts with default project type (single documents), progressively adds project system, engine infrastructure, and format support. See plan: claude-notes/plans/2025-12-20-quarto-render-prototype.md","status":"open","priority":1,"issue_type":"epic","created_at":"2025-12-20T11:41:46.4243-06:00","updated_at":"2025-12-20T11:41:46.4243-06:00"} -{"id":"k-xol0","title":"HTML postprocessor analysis and Rust DOM API design","description":"Study quarto-cli HTML postprocessors to understand DOM manipulation patterns and design appropriate Rust API. Plan: claude-notes/plans/2025-12-20-html-postprocessor-analysis.md","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-20T16:20:11.65256-06:00","updated_at":"2025-12-20T16:20:11.65256-06:00","dependencies":[{"issue_id":"k-xol0","depends_on_id":"k-xlko","type":"discovered-from","created_at":"2025-12-20T16:20:11.653996-06:00","created_by":"daemon"}]} -{"id":"k-xvte","title":"Design structural hash-based AST reconciliation algorithm","description":"Design a reconciliation algorithm for PandocAST nodes inspired by React 15's reconciliation. Use structural hashes as virtual keys for node identity since we don't have explicit id keys. The hash of a node = hash(type, content, children_hashes), excluding source locations. This enables O(n) reconciliation with efficient subtree skipping when hashes match.\n\nApproach:\n- Compute structural hashes for both pre-engine and post-engine ASTs\n- Hash serves as 'virtual key' for matching nodes across ASTs\n- If hashes match, subtrees are identical - transfer source locations wholesale\n- If hashes differ but types match, recurse into children\n- Use hash-based alignment for children lists (hash -\u003e node multimap)\n\nPlan: claude-notes/plans/2025-12-17-structural-hash-reconciliation-design.md","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-17T16:25:33.504802-06:00","updated_at":"2025-12-17T16:25:33.504802-06:00","dependencies":[{"issue_id":"k-xvte","depends_on_id":"k-6daf","type":"related","created_at":"2025-12-17T16:25:33.507196-06:00","created_by":"daemon"}]} -{"id":"k-y2f3","title":"Add doctemplate support to quarto-markdown-pandoc","description":"Add document template support to quarto-markdown-pandoc with both bundle-based (for WASM) and filesystem-based (feature-gated) template resolution.\n\nPlan: claude-notes/plans/2025-12-05-doctemplate-integration.md\n\nKey components:\n1. MetaValue to TemplateValue conversion\n2. Template bundle format (JSON with main + partials)\n3. Library API with PartialResolver support \n4. CLI integration (--template, --template-bundle)\n5. WASM entry points","status":"open","priority":1,"issue_type":"feature","created_at":"2025-12-05T11:14:01.283473-06:00","updated_at":"2025-12-05T11:14:58.723177-06:00"} -{"id":"k-y30s","title":"Improve coverage: quarto-core/src/render.rs","description":"Session baseline: 73.65% line coverage. File at 71.43%. Focus on BinaryDependencies, RenderOptions, RenderContext methods.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T10:48:50.925594-06:00","updated_at":"2026-01-02T10:51:52.729268-06:00","closed_at":"2026-01-02T10:51:52.729268-06:00","dependencies":[{"issue_id":"k-y30s","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T10:48:50.927144-06:00","created_by":"daemon"}]} -{"id":"k-yd14","title":"Phase 4: Project Type System","description":"REVISED (was Phase 4 Engine Infrastructure): Support project-level configuration. Includes: ProjectType registry with DefaultProjectType, multi-file rendering, output directory handling, project.render globs. Part of k-xlko.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-20T11:42:25.768053-06:00","updated_at":"2025-12-20T12:09:57.538163-06:00","dependencies":[{"issue_id":"k-yd14","depends_on_id":"k-xlko","type":"parent-child","created_at":"2025-12-20T11:42:25.769094-06:00","created_by":"daemon"},{"issue_id":"k-yd14","depends_on_id":"k-9aj6","type":"blocks","created_at":"2025-12-20T11:42:47.618431-06:00","created_by":"daemon"}]} -{"id":"k-ydzc","title":"Implement knitr engine (Phase 4)","description":"Implement the knitr execution engine for R code cells.\n\nPlan: claude-notes/plans/2026-01-07-knitr-engine-implementation.md\n\n## Overview\n\nPort the TypeScript knitr engine to Rust, enabling R code execution in Quarto documents.\n\n## Key Components\n\n1. **R Script Resources**: rmd.R, execute.R, hooks.R, patch.R, ojs*.R\n2. **Subprocess Management**: Spawn Rscript, communicate via stdin/stdout\n3. **JSON Protocol**: Pass parameters as JSON, receive results as JSON\n4. **Supporting Files**: Track figures and other outputs from execution\n\n## Dependencies\n\n- Requires R and knitr/rmarkdown packages installed\n- Blocked by k-oomv (execution engine infrastructure)","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-01-07T00:47:53.280153002Z","updated_at":"2026-01-07T02:29:24.776640699Z","closed_at":"2026-01-07T02:29:24.776640699Z","dependencies":[{"issue_id":"k-ydzc","depends_on_id":"k-oomv","type":"blocks","created_at":"2026-01-07T00:47:53.281345675Z","created_by":"cc"}]} -{"id":"k-yvfo","title":"Conflict resolution for filesystem/automerge divergence","description":"Design what happens when: (1) hub starts and filesystem differs from stored automerge state, (2) external process modifies .qmd file while hub is running. Options: prefer filesystem, prefer automerge, merge, user prompt.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-08T13:24:58.012901-06:00","updated_at":"2025-12-08T13:24:58.012901-06:00","dependencies":[{"issue_id":"k-yvfo","depends_on_id":"k-4wex","type":"related","created_at":"2025-12-08T13:24:58.014686-06:00","created_by":"cscheid"}]} -{"id":"k-z1ji","title":"Rename quarto-markdown-pandoc crate to pampa","description":"Rename the quarto-markdown-pandoc crate to 'pampa' as part of the project naming strategy. This includes renaming the directory, updating all Cargo.toml references, binary names, source imports, and documentation. See claude-notes/plans/2025-12-06-pampa-rename.md for detailed plan.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-06T14:44:48.188293-06:00","updated_at":"2025-12-06T15:01:18.104329-06:00","closed_at":"2025-12-06T15:01:18.104329-06:00"} -{"id":"k-z614","title":"Improve coverage: quarto-core/src/project.rs","description":"Session baseline: 73.37% line coverage. File at 47.65%. Focus on ProjectType, ProjectConfig, DocumentInfo, and ProjectContext pure method tests.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T10:28:52.683198-06:00","updated_at":"2026-01-02T10:32:17.975741-06:00","closed_at":"2026-01-02T10:32:17.975741-06:00","dependencies":[{"issue_id":"k-z614","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-01-02T10:28:52.68442-06:00","created_by":"daemon"}]} -{"id":"k-zplu","title":"Set up Emscripten SDK and build wasm-quarto-hub-client","description":"Install Emscripten SDK, configure build environment, and successfully build wasm-quarto-hub-client for wasm32-unknown-emscripten target.","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-22T19:11:05.668441-06:00","updated_at":"2025-12-22T19:11:05.668441-06:00"} -{"id":"k-zr88","title":"Source information tracking for multiple surface syntax formats","description":"Design and implement source location tracking for structured input formats (ipynb, percent scripts) so that error messages can use the coordinate system of the original format (e.g., cell IDs + offsets) rather than positions in the converted qmd.\n\nPlan: claude-notes/plans/2025-12-15-source-info-for-structured-formats.md\nRelated design: claude-notes/surface-syntax-converter-design.md","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-15T13:41:27.074296-06:00","updated_at":"2025-12-15T14:13:07.621186-06:00"} -{"id":"k-zvzm","title":"Design configuration merging system for pampa","description":"Design and document the Rust implementation of Quarto's mergeConfigs functionality. This involves studying existing code in quarto-yaml, pampa, and composable-validation, then proposing an architecture that supports !prefer/!concat tags, source location preservation, and efficient lazy/eager evaluation strategies.\n\nPlan file: claude-notes/plans/2025-12-07-config-merging-design.md","status":"in_progress","priority":1,"issue_type":"feature","created_at":"2025-12-07T09:25:04.943389-06:00","updated_at":"2025-12-07T09:30:16.359027-06:00"} +{"id":"bd-8exa","title":"Implement shareable project URLs for hub-client","description":"Add support for shareable URLs that use automerge index document IDs instead of local IndexedDB UUIDs. This enables users to share project links with others while minimizing exposure of sensitive document IDs.\n\nPlan: claude-notes/plans/2026-02-03-shareable-urls.md","status":"in_progress","priority":1,"issue_type":"feature","created_at":"2026-02-03T15:17:50.527124Z","created_by":"cscheid","updated_at":"2026-02-03T15:24:33.898151Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-02o9","title":"HTML writer source location tracking for editor integration","description":"Add optional source location tracking to HTML output to enable 'click in HTML → highlight in source' for interactive previews. See plan: claude-notes/plans/2025-12-21-html-source-location-tracking.md","status":"open","priority":1,"issue_type":"feature","created_at":"2025-12-21T21:40:02.851880Z","updated_at":"2025-12-21T21:40:02.851880Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-02rp","title":"Add project rendering from VFS to wasm-qmd-parser","description":"Add a function to render a project (multi-file) using files from the virtual filesystem. This will read _quarto.yml and referenced files from VFS and produce HTML output.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-23T01:02:56.445592Z","updated_at":"2025-12-23T01:10:58.943494Z","closed_at":"2025-12-23T01:10:58.943494Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-0dqu","title":"Refactor citeproc output rendering to unify String and Inlines paths","description":"The quarto-citeproc crate has dual code paths for Output AST conversion: render() -> String and to_inlines() -> Pandoc AST. Both implement similar logic for delimiter handling, punctuation collision avoidance, formatting, etc. This creates maintenance burden and potential for bugs (like the delimiter inheritance bug). Refactor to use Output -> Inlines as the canonical conversion, then Inlines -> String for the String path. Plan: claude-notes/plans/2025-12-05-citeproc-delimiter-inheritance-report.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-12-05T23:36:21.963061Z","updated_at":"2025-12-06T00:23:28.822793Z","closed_at":"2025-12-06T00:23:28.822793Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-0dqw","title":"Fix trailing LineBreak at end of block to match CommonMark","description":"In CommonMark, a backslash at the end of a block (paragraph, header) produces a literal backslash, not a LineBreak. pampa currently produces LineBreak in this case. The fix should convert trailing LineBreak to Str('\\\\') in the postprocess.rs handlers.\n\nPlan document: claude-notes/plans/2025-12-17-trailing-linebreak-fix.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-17T14:00:28.743309Z","updated_at":"2025-12-17T14:39:08.442844Z","closed_at":"2025-12-17T14:39:08.442844Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-0sdx","title":"Create web frontend for quarto-hub with WASM rendering","description":"Create a web frontend SPA for quarto-hub that allows users to edit project files in a browser and see live preview. Uses automerge for collaboration and WASM modules from quarto/pampa crates for rendering.\n\nPlan: claude-notes/plans/2025-12-22-quarto-hub-web-frontend-and-wasm.md","status":"open","priority":1,"issue_type":"epic","created_at":"2025-12-22T21:08:41.454563Z","updated_at":"2025-12-22T22:24:39.178837Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-1","title":"Migrate quarto-markdown error handling to quarto-error-reporting","description":"Replace custom ErrorCollector with quarto-error-reporting infrastructure using phased bridge pattern. See claude-notes/plans/2025-10-18-error-reporting-migration.md for detailed plan.\n\nPhase A: Implement rendering (to_text, to_json, generic_error helper)\nPhase B: Create DiagnosticCollector bridge\nPhase C: Switch implementations\nPhase D: Source location integration (future)\nPhase E: Retire old collectors (future)\n\nFocus is infrastructure change, not message enhancement. Use Q-0-99 with file!() line!() for now.","status":"closed","priority":2,"issue_type":"epic","created_at":"2025-10-18T19:41:31.345695Z","updated_at":"2025-10-28T17:43:01.067279Z","closed_at":"2025-10-28T17:43:01.067279Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-1","depends_on_id":"k-5","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-10","title":"Run full test suite and verify migration","description":"Run cargo test for quarto-markdown-pandoc and ensure all tests pass after ErrorCollector to DiagnosticCollector migration","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:29:07.029816Z","updated_at":"2025-10-18T20:33:05.814566Z","closed_at":"2025-10-18T20:33:05.814566Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-10","depends_on_id":"k-9","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-100","title":"Collect all warnings in ParseResult.diagnostics","description":"Combine warnings from AST conversion (error_collector) and metadata parsing into ParseResult.diagnostics instead of outputting to stderr","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:25:31.725350Z","updated_at":"2025-10-21T15:29:21.892234Z","closed_at":"2025-10-21T15:29:21.892234Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-100","depends_on_id":"k-96","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-101","title":"Update main.rs to handle new ParseResult API","description":"Remove error_formatter logic. Handle diagnostics output (text/JSON) based on --json-errors flag in main.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:25:38.909199Z","updated_at":"2025-10-21T15:29:21.905483Z","closed_at":"2025-10-21T15:29:21.905483Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-101","depends_on_id":"k-96","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-102","title":"Update all test callers for new qmd::read API","description":"Update all tests to use ParseResult instead of (Pandoc, ASTContext) tuple. Remove error_formatter None parameters","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:25:46.955046Z","updated_at":"2025-10-21T15:38:21.880567Z","closed_at":"2025-10-21T15:38:21.880567Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-102","depends_on_id":"k-96","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-103","title":"Support in-memory content for anonymous/unknown files in ariadne rendering","description":"When rendering ariadne diagnostics, we currently read file content from disk using the path. This fails for or files that don't exist on disk. We need to store content in memory for these cases while still reading from disk for real files.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T16:01:32.416755Z","updated_at":"2025-10-21T17:50:22.100652Z","closed_at":"2025-10-21T17:50:22.100652Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-104","title":"crates/quarto-markdown-pandoc/tests/claude-examples/meta-error.qmd has broken messages","description":"The meta-error.qmd test file is producing broken error messages that need investigation. This was noticed during the DiagnosticMessage consolidation work but needs separate attention to ensure error messages are properly formatted.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-21T16:07:16.610573Z","updated_at":"2025-10-21T18:51:17.142583Z","closed_at":"2025-10-21T18:51:17.142583Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-105","title":"Refactor read() to return DiagnosticMessage instead of formatted strings","description":"Replace error_formatter parameter with DiagnosticMessage return values. See claude-notes/plans/2025-10-21-diagnostic-message-refactor.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T19:01:30.792974Z","updated_at":"2025-10-21T19:25:31.639143Z","closed_at":"2025-10-21T19:25:31.639143Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-106","title":"Update read() signature to return DiagnosticMessage","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T19:01:39.635533Z","updated_at":"2025-10-21T19:03:11.811461Z","closed_at":"2025-10-21T19:03:11.811461Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-106","depends_on_id":"k-105","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-107","title":"Thread DiagnosticCollector through metadata parsing functions","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T19:01:39.650127Z","updated_at":"2025-10-21T19:06:33.632747Z","closed_at":"2025-10-21T19:06:33.632747Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-107","depends_on_id":"k-105","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-108","title":"Update main.rs to format diagnostics based on json_errors flag","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T19:01:39.663424Z","updated_at":"2025-10-21T19:08:31.949797Z","closed_at":"2025-10-21T19:08:31.949797Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-108","depends_on_id":"k-105","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-109","title":"Update all call sites (wasm, tests) to handle new return type","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T19:01:39.676749Z","updated_at":"2025-10-21T20:10:55.413016Z","closed_at":"2025-10-21T20:10:55.413016Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-109","depends_on_id":"k-105","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-11","title":"Change treesitter_to_pandoc return type to Vec","description":"Update function signature from Result> to Result> so caller decides output format","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:38:24.598967Z","updated_at":"2025-10-18T20:40:03.746055Z","closed_at":"2025-10-18T20:40:03.746055Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-11","depends_on_id":"k-10","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-110","title":"Add test verifying JSON error output for metadata warnings","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T19:01:39.694200Z","updated_at":"2025-10-26T23:55:08.741639Z","closed_at":"2025-10-26T23:55:08.741639Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-110","depends_on_id":"k-105","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-111","title":"Run cargo check and cargo test for validation","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T19:01:39.708656Z","updated_at":"2025-10-26T23:49:18.075259Z","closed_at":"2025-10-26T23:49:18.075259Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-111","depends_on_id":"k-105","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-112","title":"Create test for --json-errors flag functionality","description":"Add automated test to verify that --json-errors flag properly formats all diagnostics (errors and warnings) as JSON, including metadata parsing warnings like Q-1-101","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T19:16:03.661971Z","updated_at":"2025-10-26T23:46:15.930561Z","closed_at":"2025-10-26T23:46:15.930561Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-112","depends_on_id":"k-105","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-113","title":"Add quarto-error-reporting dependency to qmd-syntax-helper","description":"Add quarto-error-reporting.workspace = true to crates/qmd-syntax-helper/Cargo.toml dependencies section","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T21:34:17.706058Z","updated_at":"2025-10-21T21:35:00.653765Z","closed_at":"2025-10-21T21:35:00.653765Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-114","title":"Update parse_check.rs to use 4-parameter read() signature","description":"Remove 5th parameter from qmd::read() call in crates/qmd-syntax-helper/src/diagnostics/parse_check.rs (lines 22-35). Simple fix - only uses result.is_ok().","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T21:34:20.738673Z","updated_at":"2025-10-21T21:35:18.025299Z","closed_at":"2025-10-21T21:35:18.025299Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-115","title":"Investigate SourceInfo API for row/column extraction","description":"Study crates/quarto-source-map/src/lib.rs to understand how to extract row/column from SourceInfo. Needed for div_whitespace.rs migration.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T21:34:23.737466Z","updated_at":"2025-10-21T21:35:42.091665Z","closed_at":"2025-10-21T21:35:42.091665Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-116","title":"Update div_whitespace.rs to use DiagnosticMessage","description":"Update crates/qmd-syntax-helper/src/conversions/div_whitespace.rs: (1) Remove ParseError/ErrorLocation structs, (2) Remove 5th parameter from qmd::read() call, (3) Update get_parse_errors() to return Vec, (4) Update find_div_whitespace_errors() to accept &[DiagnosticMessage], (5) Extract location from DiagnosticMessage.location. See claude-notes/plans/2025-10-21-qmd-syntax-helper-diagnostic-migration.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T21:34:27.047930Z","updated_at":"2025-10-21T21:36:44.314650Z","closed_at":"2025-10-21T21:36:44.314650Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-117","title":"Verify qmd-syntax-helper compiles and tests pass","description":"Run cargo check and cargo test on qmd-syntax-helper after DiagnosticMessage migration","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T21:34:30.307715Z","updated_at":"2025-10-21T21:37:44.061757Z","closed_at":"2025-10-21T21:37:44.061757Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-118","title":"Add error code to simple format in DiagnosticMessage::to_text()","description":"Update line 335 in diagnostic.rs to include error code in simple tidyverse format, matching behavior before k-103 refactor. See claude-notes/plans/2025-10-21-fix-quarto-error-reporting-tests.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T21:45:03.592356Z","updated_at":"2025-10-21T21:45:38.861845Z","closed_at":"2025-10-21T21:45:38.861845Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-119","title":"Add location fallback in DiagnosticMessage::to_text()","description":"Add location display for diagnostics without full source context. Shows 'at row:col' even when ariadne rendering unavailable. See claude-notes/plans/2025-10-21-fix-quarto-error-reporting-tests.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T21:45:06.723921Z","updated_at":"2025-10-21T21:46:14.190057Z","closed_at":"2025-10-21T21:46:14.190057Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-12","title":"Add quarto-source-map dependency to quarto-error-reporting","description":"Update Cargo.toml to add quarto-source-map as dependency","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:58:04.842400Z","updated_at":"2025-10-18T20:58:49.265615Z","closed_at":"2025-10-18T20:58:49.265615Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-120","title":"Update quarto-error-reporting test expectations for trailing newlines","description":"Update test_to_text_simple_error and test_to_text_with_code to expect trailing newlines in output. New behavior adds \\n to all lines for cleaner multi-line display.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T21:45:09.851066Z","updated_at":"2025-10-21T21:46:47.566335Z","closed_at":"2025-10-21T21:46:47.566335Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-121","title":"Clean up compiler warnings in quarto-markdown-pandoc tests","description":"Remove unused imports and variables from test files: test_json_errors.rs, test_inline_locations.rs, test_warnings.rs, test_json_roundtrip.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T21:58:25.389625Z","updated_at":"2025-10-21T21:59:53.715645Z","closed_at":"2025-10-21T21:59:53.715645Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-122","title":"Fix qmd-syntax-helper summary file count bug","description":"Summary only counts files with issues, not all files checked. Track file count separately and pass to print_check_summary. See claude-notes/plans/2025-10-21-qmd-syntax-helper-summary-bug.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-21T23:40:27.964430Z","updated_at":"2025-10-21T23:41:35.889473Z","closed_at":"2025-10-21T23:41:35.889473Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-123","title":"Fix definition-lists rule false positive on table captions","description":"Definition list detector incorrectly flags table captions as definition lists. Add check for pipe characters (2+) in term line to distinguish table rows from definition terms. See claude-notes/plans/2025-10-21-definition-list-false-positive-revised.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-21T23:58:02.387963Z","updated_at":"2025-10-21T23:59:07.392181Z","closed_at":"2025-10-21T23:59:07.392181Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-124","title":"Improve qmd-syntax-helper output context in non-verbose mode","description":"Show filename before issues in non-verbose mode. Buffer results per file and only print filename if file has issues. See claude-notes/plans/2025-10-21-qmd-syntax-helper-output-context.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-22T00:08:28.243069Z","updated_at":"2025-10-22T00:10:10.754049Z","closed_at":"2025-10-22T00:10:10.754049Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-125","title":"Fix glob expansion to check literal paths exist and warn on empty globs","description":"Non-existent literal files are added to file list and cause confusing errors. Check literal paths exist before adding them. Warn when glob patterns match no files. See claude-notes/plans/2025-10-21-qmd-syntax-helper-glob-no-match.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-22T00:17:55.457597Z","updated_at":"2025-10-22T00:19:24.518246Z","closed_at":"2025-10-22T00:19:24.518246Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-126","title":"Fix definition list false positives on grid table captions","description":"Grid table captions (lines starting with : after grid table borders) are incorrectly detected as definition lists. See claude-notes/plans/2025-10-21-grid-table-false-positive.md for details.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-22T00:22:44.086173Z","updated_at":"2025-10-22T00:24:17.995116Z","closed_at":"2025-10-22T00:24:17.995116Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-127","title":"Fix div-whitespace O(N²) performance bug","description":"The div-whitespace rule recalculates line start offsets for every error, causing O(N²) performance. Pre-compute offsets once. See claude-notes/plans/2025-10-21-div-whitespace-performance.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-22T01:23:59.169405Z","updated_at":"2025-10-22T01:26:37.015408Z","closed_at":"2025-10-22T01:26:37.015408Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-128","title":"Optimize TreeSitterLogObserver::log() by eliminating HashMap","description":"Replace expensive HashMap allocation on every log call with direct parameter extraction into Option variables. Expected 10-15% speedup in parsing. See claude-notes/tree-sitter-log-optimization-assessment.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T11:35:44.047976Z","updated_at":"2025-10-22T11:39:14.817675Z","closed_at":"2025-10-22T11:39:14.817675Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-129","title":"Add self-health tests for location information on test suite","description":"When converting between (row,col) and byte offsets, we need tests to verify the conversions are correct. Specifically:\n\n1. Test that calculate_byte_offset and offset_to_location are proper inverses\n2. Test edge cases: EOF, empty files, files with/without trailing newlines\n3. Test that parse error locations have consistent start/end row values\n4. Add property-based tests that verify: offset_to_location(calculate_byte_offset(r,c)) == (r,c)\n\nThe bug manifested as: parse error at EOF had start.row=341 but end.row=22 because calculate_byte_offset returned an out-of-bounds offset (10188) for a 10188-byte file.","notes":"Phase 1 & 2 complete. Tests successfully implemented and found real bugs (k-135). Test infrastructure complete and working. Discovered 24 location violations in 6 smoke test files. Next: either fix bugs or continue with Phase 3-5.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T14:44:40.935813Z","updated_at":"2025-10-26T23:42:03.011089Z","closed_at":"2025-10-26T23:42:03.011089Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-13","title":"Add location field to DiagnosticMessage","description":"Add optional quarto_source_map::SourceInfo field to DiagnosticMessage struct","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:58:06.274133Z","updated_at":"2025-10-18T20:59:41.186788Z","closed_at":"2025-10-18T20:59:41.186788Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-13","depends_on_id":"k-12","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-130","title":"Phase 1: Create test infrastructure for location health checks","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T23:00:47.681619Z","updated_at":"2025-10-22T23:05:13.094318Z","closed_at":"2025-10-22T23:05:13.094318Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-130","depends_on_id":"k-129","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-131","title":"Phase 2: Implement core property tests (well-formed, consistency, bounds)","notes":"Phase 2 complete: implemented and tested well-formed ranges, offset/row/col consistency, and bounds checking. All validators working on simple,nested, multiline, empty, and edge case files.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T23:00:50.786084Z","updated_at":"2025-10-22T23:08:33.467759Z","closed_at":"2025-10-22T23:08:34.467759Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-131","depends_on_id":"k-129","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-132","title":"Phase 3: Implement structural tests (nesting, sequential)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T23:00:53.791850Z","updated_at":"2025-10-26T23:42:00.744388Z","closed_at":"2025-10-26T23:42:00.744388Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-132","depends_on_id":"k-129","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-133","title":"Phase 4: Implement SourceMapping validation tests","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T23:00:56.919971Z","updated_at":"2025-10-26T23:42:01.495515Z","closed_at":"2025-10-26T23:42:01.495515Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-133","depends_on_id":"k-129","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-134","title":"Phase 5: Integration - run on all smoke tests and edge cases","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-22T23:00:59.858531Z","updated_at":"2025-10-26T23:42:02.312977Z","closed_at":"2025-10-26T23:42:02.312977Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-134","depends_on_id":"k-129","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-135","title":"Fix bug: End locations have row=0,col=0 instead of computed values","notes":"Investigation shows: The test_location_health.rs smoke tests currently PASS with 0 violations. The issue was created on 2025-10-22 reporting 24 violations in 6 files, but testing now shows no violations. Either: (1) bugs were fixed between then and now, (2) test detection was changed, or (3) issue is on different branch. Need to check main branch or clarify what specific violations remain.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-22T23:08:30.384258Z","updated_at":"2025-10-24T20:08:57.586887Z","closed_at":"2025-10-24T20:08:57.586887Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-135","depends_on_id":"k-129","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-136","title":"Refactor SourceInfo struct into an enum","description":"Redesign SourceInfo to be an enum instead of a struct with a separate SourceMapping enum. This will make the API clearer by eliminating the confusing Range field that means different things in different contexts. Each variant should contain exactly the data it needs.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T00:27:06.106655Z","updated_at":"2025-10-26T23:31:45.414849Z","closed_at":"2025-10-26T23:31:45.414849Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-137","title":"Refactor SourceInfo to use enum with offsets-only","description":"Remove Transformed variant, change to enum storing only offsets (not Location with row/column). This fixes confusion and a bug in error.rs. See claude-notes/plans/2025-10-22-sourceinfo-enum-refactor.md and claude-notes/sourceinfo-usage-analysis.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T02:11:38.931499Z","updated_at":"2025-10-23T02:59:40.261766Z","closed_at":"2025-10-23T02:59:40.261766Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-138","title":"Phase 1: Implement new SourceInfo enum design","description":"Redesign SourceInfo as enum with Original/Substring/Concat variants, storing only offsets (no row/column). Remove Transformed variant entirely.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T02:11:54.193258Z","updated_at":"2025-10-23T02:15:27.352089Z","closed_at":"2025-10-23T02:15:27.352089Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-138","depends_on_id":"k-137","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-139","title":"Phase 2: Add helper methods and update map_offset","description":"Implement helper methods: length(), start_offset(), end_offset(), from_range(). Update map_offset() to work with new enum.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T02:11:57.232324Z","updated_at":"2025-10-23T02:19:09.658039Z","closed_at":"2025-10-23T02:19:09.658039Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-139","depends_on_id":"k-137","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-14","title":"Update DiagnosticMessageBuilder with with_location()","description":"Add .with_location() method to builder API","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:58:07.824720Z","updated_at":"2025-10-18T21:00:10.563035Z","closed_at":"2025-10-18T21:00:10.563035Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-14","depends_on_id":"k-13","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-140","title":"Phase 3: Update all quarto-source-map tests","description":"Update all tests in quarto-source-map to work with new enum design and offset-only storage.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T02:12:00.460817Z","updated_at":"2025-10-23T02:19:09.671979Z","closed_at":"2025-10-23T02:19:09.671979Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-140","depends_on_id":"k-137","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-141","title":"Phase 4: Migrate quarto-yaml to new SourceInfo API","description":"Update quarto-yaml parser and error handling to use new SourceInfo API. Fix error.rs bug where it accesses .range.start.row directly.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T02:12:03.838807Z","updated_at":"2025-10-23T02:27:28.482932Z","closed_at":"2025-10-23T02:27:28.482932Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-141","depends_on_id":"k-137","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-142","title":"Phase 5: Migrate quarto-markdown-pandoc to new SourceInfo API","description":"Update all quarto-markdown-pandoc usage of SourceInfo to work with new enum design.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T02:12:07.154970Z","updated_at":"2025-10-23T02:57:13.812166Z","closed_at":"2025-10-23T02:57:13.812166Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-142","depends_on_id":"k-137","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-143","title":"Fix error message rendering: incorrect Substring offsets in error diagnostics","description":"Error messages are not showing ariadne source snippets because Substring SourceInfo is being created with absolute file offsets instead of parent-relative offsets. This causes map_offset() to compute out-of-bounds offsets and return None. Fix: Convert absolute offsets to relative when creating Substring in qmd_error_messages.rs lines 437-441 and 472-476.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-23T12:24:59.119442Z","updated_at":"2025-10-23T12:34:44.712870Z","closed_at":"2025-10-23T12:34:44.712870Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-144","title":"Add test for error corpus ariadne rendering","description":"Add test to verify that all files in resources/error-corpus/*.qmd produce well-formatted ariadne output in text mode with source snippets and proper file:line:column information.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T12:25:08.057917Z","updated_at":"2025-10-23T12:34:44.727911Z","closed_at":"2025-10-23T12:34:44.727911Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-144","depends_on_id":"k-143","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-145","title":"Add test for error corpus JSON source locations","description":"Add test to verify that all files in resources/error-corpus/*.qmd produce JSON errors with proper source location information (file_id and offsets that can be mapped back to row/column).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T12:25:18.540142Z","updated_at":"2025-10-23T12:34:44.741261Z","closed_at":"2025-10-23T12:34:44.741261Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-145","depends_on_id":"k-143","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-146","title":"Fix JSON deserialization to populate SourceContext with files","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-23T13:12:06.976558Z","updated_at":"2025-10-23T13:20:40.231680Z","closed_at":"2025-10-23T13:20:40.231680Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-147","title":"Serialize line break information in JSON format","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-23T13:28:34.835065Z","updated_at":"2025-10-23T13:32:42.732198Z","closed_at":"2025-10-23T13:32:42.732198Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-148","title":"Refactor JSON format to use single files array instead of parallel filenames/fileInformation arrays","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-23T13:40:01.343984Z","updated_at":"2025-10-23T13:45:31.672631Z","closed_at":"2025-10-23T13:45:31.672631Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-149","title":"Implement Phase 1: SourceInfo Reconstruction","description":"Implement ts-packages/rust-qmd-json/src/source-map.ts with SourceInfoReconstructor class. Support Original, Substring, and Concat SourceInfo types with caching. See plan: claude-notes/plans/2025-10-23-json-to-annotated-parse-conversion.md Phase 1","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T17:42:26.416788Z","updated_at":"2025-10-23T17:45:20.485265Z","closed_at":"2025-10-23T17:45:20.485265Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-15","title":"Update rendering to include location","description":"Update to_text() to accept optional SourceContext and to_json() to include location. Handle display formatting (1-based)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:58:09.274555Z","updated_at":"2025-10-18T21:01:41.486977Z","closed_at":"2025-10-18T21:01:41.486977Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-150","title":"Implement Phase 2: Metadata Conversion","description":"Implement ts-packages/rust-qmd-json/src/meta-converter.ts with MetadataConverter class. Convert all MetaValue types to AnnotatedParse. Handle tagged YAML values. See plan: claude-notes/plans/2025-10-23-json-to-annotated-parse-conversion.md Phase 2","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T17:42:34.276871Z","updated_at":"2025-10-23T17:47:04.698524Z","closed_at":"2025-10-23T17:47:04.698524Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-150","depends_on_id":"k-149","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-151","title":"Implement Phase 3: Integration and Testing","description":"Implement ts-packages/rust-qmd-json/src/index.ts main entry point and types.ts. Write comprehensive tests for all phases. Document API usage. See plan: claude-notes/plans/2025-10-23-json-to-annotated-parse-conversion.md Phase 3","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T17:42:41.537826Z","updated_at":"2025-10-23T17:48:48.740615Z","closed_at":"2025-10-23T17:48:48.740615Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-151","depends_on_id":"k-150","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-152","title":"Replace any with unknown and add runtime type checks","description":"Replace all 'any' types with 'unknown' in ts-packages/rust-qmd-json and add proper runtime type checking where needed. This improves type safety.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-23T18:32:20.002258Z","updated_at":"2025-10-23T18:35:50.557744Z","closed_at":"2025-10-23T18:35:50.557744Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-153","title":"Phase 1: TypeScript Type Declarations for Pandoc AST","description":"Create complete TypeScript type definitions for Pandoc JSON schema using discriminated unions. Define Block, Inline, Attr, and supporting types. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T13:19:02.150332Z","updated_at":"2025-10-24T13:36:00.404196Z","closed_at":"2025-10-24T13:36:00.404196Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-154","title":"Phase 2: Inline Converter implementation","description":"Implement InlineConverter class to convert Pandoc Inline nodes to AnnotatedParse. Handle all inline types: Str, Space, Emph, Strong, Code, Math, Span, Link, Image, etc. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T13:19:06.347103Z","updated_at":"2025-10-25T21:07:52.581349Z","closed_at":"2025-10-25T21:07:52.581349Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-154","depends_on_id":"k-153","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-155","title":"Phase 3: Block Converter (Core Blocks)","description":"Implement BlockConverter class for core Pandoc Block nodes. Handle Para, Header, Lists, CodeBlock, Div, Figure, etc. Excludes DefinitionList and Table (separate phases). See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T13:19:11.188646Z","updated_at":"2025-10-25T21:14:20.529174Z","closed_at":"2025-10-25T21:14:20.529174Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-155","depends_on_id":"k-153","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-155","depends_on_id":"k-154","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-156","title":"Phase 3b: Definition List Support with desugaring","description":"Handle DefinitionList with proper source mapping through div.definition-list desugaring. Must verify source info preservation through the desugaring step in postprocess.rs. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T13:19:15.386033Z","updated_at":"2025-10-25T21:14:24.618835Z","closed_at":"2025-10-25T21:14:24.618835Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-156","depends_on_id":"k-155","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-157","title":"Phase 3c: Table Support (most complex)","description":"Handle Table blocks with complete structure (Attr, Caption, ColSpec, TableHead, TableBody[], TableFoot). Most complex block type requiring careful component structure design. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T13:19:19.656839Z","updated_at":"2025-10-25T21:14:28.790889Z","closed_at":"2025-10-25T21:14:28.790889Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-157","depends_on_id":"k-155","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-158","title":"Phase 4: Document Converter API","description":"Create DocumentConverter to orchestrate all converters. Provide API: parseRustQmdDocument, parseRustQmdBlocks, parseRustQmdBlock, parseRustQmdInline. Update exports and README. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T13:19:24.214798Z","updated_at":"2025-10-25T21:16:37.445561Z","closed_at":"2025-10-25T21:16:37.445561Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-158","depends_on_id":"k-153","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-158","depends_on_id":"k-154","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-158","depends_on_id":"k-155","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-158","depends_on_id":"k-156","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-158","depends_on_id":"k-157","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-159","title":"Phase 5: Testing & Validation","description":"Comprehensive testing of all converters. Create test fixtures with quarto-markdown-pandoc, write end-to-end tests, validate source mappings, performance testing. Document linting use case examples. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T13:19:28.532737Z","updated_at":"2025-10-26T23:29:52.156094Z","closed_at":"2025-10-26T23:29:52.156094Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-159","depends_on_id":"k-158","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-16","title":"Add conversion helpers in pandoc::location","description":"Add to_source_map_info() and to_source_map_info_with_mapping() to pandoc::location::SourceInfo for temporary bridge","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:58:10.719999Z","updated_at":"2025-10-18T21:02:22.538397Z","closed_at":"2025-10-18T21:02:22.538397Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-16","depends_on_id":"k-14","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-160","title":"Phase 6: quarto-cli Integration (deferred)","description":"Integration with quarto-cli validation infrastructure for linting support. Deferred until API is stable and use cases are clear. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md for details.","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-24T13:19:32.846057Z","updated_at":"2025-10-24T13:19:32.846057Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-160","depends_on_id":"k-159","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-161","title":"Design solution for recursive type annotation problem","description":"Create a small self-contained TypeScript prototype to design a solution for recursively transforming nested type references when annotating AST nodes. The intersection approach (Type & { s: number }) doesn't transform nested Inline[] to Annotated_Inline[]. See claude-notes/2025-10-24-recursive-annotation-problem.md for full problem description. Prototype should explore: conditional types, mapped types, type-level recursion to handle arrays/tuples/cross-references.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T14:12:41.397527Z","updated_at":"2025-10-24T15:27:04.140204Z","closed_at":"2025-10-24T15:27:04.140204Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-161","depends_on_id":"k-153","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-162","title":"Implement Attr/Target source location sideloading in quarto-markdown-pandoc","description":"Extend quarto-markdown-pandoc to output attrS, targetS, and citationIdS fields for tuple-based Pandoc structures that cannot have 's' fields added directly. See claude-notes/plans/2025-10-24-attr-target-sideloading.md for complete design.","notes":"Affects 15 node types: 4 inline (Code, Link, Image, Span), 5 block (CodeBlock, Header, Table, Figure, Div), 5 table components (TableHead, TableBody, TableFoot, Row, Cell), plus Citation. Implementation plan in claude-notes/plans/2025-10-24-attr-target-sideloading.md. Required for k-163 (TypeScript types).","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-24T15:26:21.119278Z","updated_at":"2025-10-24T20:48:31.557376Z","closed_at":"2025-10-24T20:48:31.557376Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-163","title":"Implement full annotated Pandoc AST types in annotated-qmd","description":"Implement complete parallel type hierarchies (Base and Annotated) for all Pandoc AST types in TypeScript. Includes handling attrS, targetS, and citationIdS sideloaded fields. Uses parallel hierarchy approach validated in src/recursive-annotation-type-experiments.ts. See claude-notes/plans/2025-10-24-pandoc-ast-annotated-parse.md and claude-notes/2025-10-24-recursive-annotation-problem.md.","notes":"Supersedes and incorporates work originally planned in k-154, k-155, and k-158. Design validated in src/recursive-annotation-type-experiments.ts. Blocked by k-162 (Rust sideloading implementation).","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-24T15:26:32.108233Z","updated_at":"2025-11-23T13:21:55.528209Z","closed_at":"2025-11-23T13:21:56.528209Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-163","depends_on_id":"k-162","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-164","title":"Fix compilation errors in readers/json.rs (15 errors)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:43:37.065085Z","updated_at":"2025-10-24T15:54:27.543970Z","closed_at":"2025-10-24T15:54:27.543970Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-164","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-165","title":"Fix compilation errors in writers/native.rs (2 errors)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:43:41.161199Z","updated_at":"2025-10-24T15:55:13.953795Z","closed_at":"2025-10-24T15:55:13.953795Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-165","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-166","title":"Fix compilation errors in filters.rs (5 errors)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:43:45.055881Z","updated_at":"2025-10-24T15:56:24.260185Z","closed_at":"2025-10-24T15:56:24.260185Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-166","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-167","title":"Fix compilation errors in pandoc/meta.rs (6 errors)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:43:49.079872Z","updated_at":"2025-10-24T15:57:52.681088Z","closed_at":"2025-10-24T15:57:52.681088Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-167","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-168","title":"Fix compilation errors in pandoc/inline.rs (2 errors)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:43:53.114748Z","updated_at":"2025-10-24T15:46:36.162552Z","closed_at":"2025-10-24T15:46:36.162552Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-168","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-169","title":"Fix compilation errors in pandoc/shortcode.rs (3 errors)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:43:56.897935Z","updated_at":"2025-10-24T15:47:34.756365Z","closed_at":"2025-10-24T15:47:34.756365Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-169","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-17","title":"Add error_at/warn_at to DiagnosticCollector","description":"Add convenience methods error_at() and warn_at() that accept location parameter","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:58:12.306284Z","updated_at":"2025-10-18T21:02:50.910791Z","closed_at":"2025-10-18T21:02:50.910791Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-17","depends_on_id":"k-14","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-170","title":"Fix compilation errors in treesitter_utils/postprocess.rs (7 errors)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:44:00.747482Z","updated_at":"2025-10-24T16:06:00.607724Z","closed_at":"2025-10-24T16:06:00.607724Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-170","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-171","title":"Fix compilation errors in treesitter_utils/pipe_table.rs (6 errors)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:44:04.763726Z","updated_at":"2025-10-24T16:06:59.864233Z","closed_at":"2025-10-24T16:06:59.864233Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-171","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-172","title":"Fix compilation errors in treesitter_utils/editorial_marks.rs (4 errors)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:44:09.065723Z","updated_at":"2025-10-24T16:07:40.188106Z","closed_at":"2025-10-24T16:07:40.188106Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-172","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-173","title":"Fix compilation errors in treesitter_utils/code_span.rs (3 errors)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:44:13.136150Z","updated_at":"2025-10-24T16:08:25.332487Z","closed_at":"2025-10-24T16:08:25.332487Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-173","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-174","title":"Fix compilation errors in treesitter_utils/section.rs (2 errors)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:44:17.307694Z","updated_at":"2025-10-24T16:09:22.376036Z","closed_at":"2025-10-24T16:09:22.376036Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-174","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-175","title":"Fix compilation errors in treesitter_utils/document.rs (2 errors)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:44:21.126357Z","updated_at":"2025-10-24T16:09:25.967312Z","closed_at":"2025-10-24T16:09:25.967312Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-175","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-176","title":"Fix compilation errors in 8 remaining treesitter_utils files (8 errors)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T15:44:25.086682Z","updated_at":"2025-10-24T16:12:39.359469Z","closed_at":"2025-10-24T16:12:39.359469Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-176","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-177","title":"Phase 2-6: Implement parser, serialization, and tests for attr/target source tracking","description":"Complete the remaining phases of attr/target source tracking implementation. See claude-notes/2025-10-24-test-plan-attr-source-tracking.md for details.\n\nPhase 1 (Structure Tests) is complete with 26 passing tests.\n\nRemaining work:\n- Phase 2A: Parser unit tests (track source locations during parsing)\n- Phase 2B: Integration tests (end-to-end parsing)\n- Phase 3: JSON serialization tests (output attrS/targetS/citationIdS)\n- Phase 4: JSON deserialization tests (input with backward compatibility)\n- Phase 5: Roundtrip property tests (qmd → JSON → qmd)\n- Phase 6: Complexity tests (nested tables, performance)\n\nTest plan document: claude-notes/2025-10-24-test-plan-attr-source-tracking.md\nTest file: tests/test_attr_source_structure.rs (26 passing tests)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T16:30:20.311470Z","updated_at":"2025-11-21T21:21:20.650903Z","closed_at":"2025-11-21T21:21:20.650903Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-178","title":"Fix remaining IntermediateAttr pattern match errors (9 files)","description":"Apply the pattern: IntermediateAttr(a) -> IntermediateAttr(a, as_) to extract attr_source in: treesitter.rs, code_span.rs, editorial_marks.rs, fenced_code_block.rs, fenced_div_block.rs, image.rs, info_string.rs, inline_link.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T16:43:59.373153Z","updated_at":"2025-10-24T16:46:42.758620Z","closed_at":"2025-10-24T16:46:42.758620Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-178","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-179","title":"Use extracted attr_source in all parser functions","description":"Replace all pattern matches IntermediateAttr(a, _) with IntermediateAttr(a, as_) and pass attr_source to final AST node constructors instead of .empty(). Affects: treesitter.rs, inline_link.rs, image.rs, fenced_div_block.rs, code_span.rs, fenced_code_block.rs, editorial_marks.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T16:48:44.890911Z","updated_at":"2025-10-24T16:54:23.889669Z","closed_at":"2025-10-24T16:54:23.889669Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-179","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-18","title":"Restore location to caption-without-table warning in postprocess.rs","description":"Update postprocess.rs to use warn_at() with caption_block.source_info for the 'Caption found without table' warning","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:58:14.138418Z","updated_at":"2025-11-23T20:42:33.122903Z","closed_at":"2025-11-23T20:42:33.122903Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-180","title":"Write unit tests for attr_source tracking","description":"Add tests that verify attr_source correctly captures source locations for IDs, classes, and key-value pairs in attributes. Test cases: Span{#id}, Link{.class1 .class2}, CodeBlock{key=value}, etc.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T16:48:48.569893Z","updated_at":"2025-10-24T17:15:46.089637Z","closed_at":"2025-10-24T17:15:46.089637Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-180","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-181","title":"Implement JSON serialization for attrS fields","description":"Extend JSON writer to serialize attrS (AttrSourceInfo) fields alongside Attr fields for all relevant Pandoc AST nodes. Format: {attr: [...], attrS: {id: {...}, classes: [...], kvs: [...]}}.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T16:48:52.197387Z","updated_at":"2025-10-24T17:49:29.713001Z","closed_at":"2025-10-24T17:49:29.713001Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-181","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-182","title":"Implement JSON deserialization for attrS fields","description":"Extend JSON reader to deserialize attrS fields from JSON and populate AttrSourceInfo in AST nodes. Handle optional attrS fields gracefully (default to empty when missing).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T16:48:55.947772Z","updated_at":"2025-10-24T17:57:51.624207Z","closed_at":"2025-10-24T17:57:51.624207Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-182","depends_on_id":"k-162","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-183","title":"Improve attr_source tests to validate actual source locations","description":"Replace weak assert_ne\\! checks with proper validation of byte offsets and ranges. Tests should verify that attr_source fields point to the correct locations in the input string, not just that they exist. Example: For '[text]{#my-id}', verify id source points to bytes 7-13 ('#my-id').","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T18:30:35.041231Z","updated_at":"2025-10-24T18:36:18.082815Z","closed_at":"2025-10-24T18:36:18.082815Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-184","title":"Fix table caption attr_source merging bug in postprocess.rs","description":"The code extracts caption_attr_source but never merges it into table.attr_source, causing compiler warnings and missing source location data for table attributes that come from captions. See claude-notes/plans/2025-10-24-table-caption-attr-source-fix.md for complete analysis and implementation plan.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-24T18:43:13.361287Z","updated_at":"2025-10-24T18:55:21.564143Z","closed_at":"2025-10-24T18:55:21.564143Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-184","depends_on_id":"k-183","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-185","title":"Table caption parsing fails without blank line before caption","description":"Table captions using the colon syntax require a blank line before the caption line, but Pandoc doesn't require this. Example that fails: '| Header |\\n|--------|\\n| Data |\\n: Caption'. Works with blank line: '| Header |\\n|--------|\\n| Data |\\n\\n: Caption'. This is a parser-level issue in the tree-sitter grammar or processing.","notes":"ROOT CAUSE IDENTIFIED:\n\nThe caption rule in grammar.js:257 requires $._blank_line as first element. When no blank line precedes ': Caption', the pipe table parser treats ':' as valid punctuation in cell contents, creating an extra table row instead of a caption.\n\nKEY INSIGHT: In qmd, ': ' at line start is ONLY used for captions (no definition lists). This means zero ambiguity - we can safely recognize captions without requiring blank lines.\n\nSOLUTION: Two-part fix:\n1. Remove blank line requirement from caption grammar rule\n2. Modify external scanner to terminate pipe tables when next line starts with ': ' (single colon for caption, not '::' for fenced div)\n\nSee detailed plan: claude-notes/plans/2025-10-27-table-caption-blank-line-fix.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-10-24T18:53:14.564757Z","updated_at":"2025-10-27T17:39:58.876960Z","closed_at":"2025-10-27T17:39:58.876960Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-185","depends_on_id":"k-184","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-186","title":"Phase 1: Define TypeScript types with attrS/targetS/citationIdS","description":"Define complete parallel type hierarchies for Annotated_Inline and Annotated_Block with proper nested references. Add AttrSourceInfo, TargetSourceInfo types. Add attrS, targetS, citationIdS fields to appropriate types.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T20:51:11.189912Z","updated_at":"2025-10-24T20:53:20.459575Z","closed_at":"2025-10-24T20:53:20.459575Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-186","depends_on_id":"k-163","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-187","title":"Phase 2: Implement InlineConverter for all inline types","description":"Create InlineConverter class following MetadataConverter pattern. Convert all 20 inline types to AnnotatedParse. Handle attrS, targetS, citationIdS sideloaded fields.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T20:51:32.476424Z","updated_at":"2025-10-24T20:59:11.937345Z","closed_at":"2025-10-24T20:59:11.937345Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-187","depends_on_id":"k-186","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-188","title":"Phase 3: Implement BlockConverter for core block types","description":"Create BlockConverter class with dependency on InlineConverter. Convert core blocks (Para, Plain, Header, CodeBlock, BulletList, OrderedList, Div, etc.). Exclude DefinitionList and Table (handled in Phase 3b/3c).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T20:51:36.397143Z","updated_at":"2025-10-24T21:01:25.654773Z","closed_at":"2025-10-24T21:01:25.654773Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-188","depends_on_id":"k-186","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-189","title":"Phase 3b: Add DefinitionList support to BlockConverter","description":"Handle DefinitionList with proper source mapping through desugaring. Structure is [(term, [definitions])]. Test with div.definition-list fixtures.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T20:51:40.326918Z","updated_at":"2025-10-24T21:02:20.215088Z","closed_at":"2025-10-24T21:02:20.215088Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-189","depends_on_id":"k-186","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-19","title":"Add tests for location rendering in diagnostics","description":"Test location rendering in to_text() and to_json(), with and without context","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:58:15.679399Z","updated_at":"2025-10-18T21:19:18.951040Z","closed_at":"2025-10-18T21:19:18.951040Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-190","title":"Phase 3c: Add Table support to BlockConverter","description":"Handle complete Table structure: Attr, Caption, ColSpec[], TableHead, TableBody[], TableFoot. Convert Rows and Cells recursively. Define Annotated_Caption, Annotated_Cell, Annotated_Row types with attrS fields.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T20:51:44.305597Z","updated_at":"2025-10-24T23:55:37.165020Z","closed_at":"2025-10-24T23:55:37.165020Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-190","depends_on_id":"k-186","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-191","title":"Phase 4: Implement DocumentConverter","description":"Create DocumentConverter that orchestrates InlineConverter and BlockConverter. Provide convenience functions: parseRustQmdDocument, parseRustQmdBlocks, parseRustQmdBlock, parseRustQmdInline. Update index.ts exports.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T20:51:48.386415Z","updated_at":"2025-10-25T00:02:11.691055Z","closed_at":"2025-10-25T00:02:11.691055Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-191","depends_on_id":"k-186","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-192","title":"Phase 5: Write comprehensive tests for annotated Pandoc AST","description":"Create test fixtures from quarto-markdown-pandoc. Write end-to-end tests for complex documents. Validate AnnotatedParse output (result, source, components, start/end). Performance test with large documents. Write documentation with examples.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T20:51:52.408933Z","updated_at":"2025-11-22T20:09:44.542169Z","closed_at":"2025-11-22T20:09:44.542169Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-192","depends_on_id":"k-186","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-192","depends_on_id":"k-199","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-192","depends_on_id":"k-226","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-192","depends_on_id":"k-227","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-192","depends_on_id":"k-228","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-192","depends_on_id":"k-229","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-192","depends_on_id":"k-230","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-193","title":"Create helper APIs for navigating flattened list structures in AnnotatedParse","description":"Create helper functions/APIs to navigate the flattened components arrays in BulletList, OrderedList, and DefinitionList AnnotatedParse nodes. These types have nested structure (items, definitions) that is flattened in components for simplicity, but consumers need convenient APIs to navigate the structure.\n\nExamples needed:\n- getListItems(bulletListAP): AnnotatedParse[][] - extract blocks grouped by item\n- getOrderedListItems(orderedListAP): AnnotatedParse[][] - extract blocks grouped by item \n- getDefinitionListEntries(defListAP): {term: AnnotatedParse[], definitions: AnnotatedParse[][]}[] - extract terms and their definitions\n\nThe result field contains the full Pandoc JSON structure, so reconstruction is possible by correlating indices. Consider adding these to a new navigation-helpers.ts module or as methods on a wrapper class.\n\nSee comments in src/block-converter.ts at BulletList, OrderedList, and DefinitionList cases.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-24T21:45:56.281991Z","updated_at":"2025-11-22T17:57:47.434955Z","closed_at":"2025-11-22T17:57:47.434955Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-193","depends_on_id":"k-215","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-194","title":"Phase 1: Add source tracking for structural elements in Rust","description":"Add source_info fields to table and list structural elements in quarto-markdown-pandoc to enable proper navigation in TypeScript AnnotatedParse.\n\n**Context**: See detailed design in claude-notes/2025-10-24-structural-components-design.md\n\n**Scope**:\n1. Study filters.rs to understand impact on filter traversal\n2. Add source_info: SourceInfo to table types:\n - Row\n - Cell\n - TableHead\n - TableBody\n - TableFoot\n - Caption (structure itself)\n3. Update table parser to capture structural boundaries\n4. Update JSON serializer to emit 's' field for these structures\n5. Consider list item source tracking (ListItem, DefinitionListItem, Definition)\n6. Update filter infrastructure if needed\n7. Add tests verifying source locations\n\n**Deliverables**:\n- Updated Rust types with source_info\n- Parser captures boundaries\n- JSON output includes 's' for structural elements\n- Filter system handles new elements\n- Tests pass\n\n**Blocks**: k-195 (Phase 2 TypeScript implementation)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T22:25:15.296125Z","updated_at":"2025-11-21T21:27:19.855441Z","closed_at":"2025-11-21T21:27:19.855441Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-195","title":"Phase 2: Implement structural AnnotatedParse nodes in TypeScript","description":"Implement structural AnnotatedParse nodes (table-row, table-cell, etc.) in TypeScript annotated-qmd package to preserve navigation structure.\n\n**Context**: See detailed design in claude-notes/2025-10-24-structural-components-design.md\n\n**Scope**:\n1. Update TypeScript types to include 's: number' for Row, Cell, TableHead, TableBody, TableFoot, Caption\n2. Define synthetic StructuralKind types (table-head, table-row, table-cell, caption-short, caption-long, etc.)\n3. Implement table converter with structural nodes:\n - convertTableHead()\n - convertTableBody()\n - convertTableFoot()\n - convertRow()\n - convertCell()\n - convertCaptionStructured()\n4. Update list converters if Phase 1 includes list support\n5. Add tests validating structural navigation\n\n**Deliverables**:\n- Updated TypeScript types\n- Synthetic kind definitions\n- Table converter with full structural preservation\n- List converters with structural nodes (if applicable)\n- Comprehensive tests\n\n**Dependencies**: Requires k-194 (Rust source tracking) to be complete first","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-24T22:25:27.833695Z","updated_at":"2025-11-21T22:43:30.621215Z","closed_at":"2025-11-21T22:43:30.621215Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-195","depends_on_id":"k-194","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-196","title":"Add source tracking for list structural elements","description":"Add source_info fields for list item structures to enable proper navigation in TypeScript AnnotatedParse.\n\n**Context**: Deferred from k-194 (table source tracking). See claude-notes/2025-10-24-structural-components-design.md and claude-notes/2025-10-24-phase1-source-tracking-plan.md\n\n**Problem**: List items are currently represented as tuples/vectors without dedicated structs:\n- BulletList: content: Vec (items are just Vec)\n- OrderedList: content: Vec\n- DefinitionList: content: Vec<(Inlines, Vec)>\n\n**Scope**:\n1. Create new structs: ListItem, DefinitionListItem with source_info fields\n2. Update parser to capture source ranges for list items\n3. Update filters.rs to handle new struct types\n4. Update JSON serialization/deserialization\n5. Add tests verifying source locations\n\n**Alternative**: Add parallel source_info arrays instead of changing from tuples to structs\n\n**Dependencies**: Should wait until k-194 (table source tracking) is complete to learn from that implementation\n\n**Blocks**: k-195 (TypeScript structural nodes) - list support will be limited without this","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-24T23:00:06.630322Z","updated_at":"2025-11-22T17:16:20.114640Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-196","depends_on_id":"k-194","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-197","title":"Create test fixtures for missing block types","description":"Add test fixtures and tests for block types not currently covered: OrderedList, DefinitionList, Div with attributes, Figure with caption, HorizontalRule, Null, RawBlock. Generate .qmd files and process with quarto-markdown-pandoc to create .json fixtures. Write integration tests validating conversion.","notes":"STATUS: Partial completion - see claude-notes/k-197-progress.md for detailed progress. ✅ OrderedList, Div, Figure, HorizontalRule, RawBlock completed. ❌ DefinitionList blocked on syntax issue. ❌ Null block not started. 46/49 tests passing. Continue with k-201.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T21:22:53.752307Z","updated_at":"2025-10-25T22:04:34.595797Z","closed_at":"2025-10-25T22:04:34.595797Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-197","depends_on_id":"k-192","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-198","title":"Create test fixtures for missing inline types","description":"Add test fixtures and tests for inline types not currently covered: Image, Span with attributes, Cite (citations), Note (footnotes), Quoted (single/double), Strikeout, Superscript, Subscript, SmallCaps, Underline, RawInline, SoftBreak, LineBreak. Generate .qmd files and process with quarto-markdown-pandoc to create .json fixtures. Write integration tests validating conversion.","notes":"STATUS: Significant progress - 10/13 inline type tests passing (60/63 total tests). Created inline-types.qmd fixture, generated JSON, wrote comprehensive tests. Fixed critical bugs in inline-converter.ts to handle programmatic attributes without source locations (classes and kvs). Remaining work: Fix 3 failing tests (Image, Note, Quoted). See ts-packages/annotated-qmd/test/inline-types.test.ts","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T21:22:57.988998Z","updated_at":"2025-10-26T13:29:10.499327Z","closed_at":"2025-10-26T13:29:10.499327Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-198","depends_on_id":"k-192","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-199","title":"Create tests for empty content edge cases","description":"Add test fixtures for edge cases: empty paragraphs, empty lists, empty metadata, empty code blocks, empty strings, null values. Verify converters handle gracefully without errors. Ensure AnnotatedParse structures are valid for empty content.","notes":"Phase 3: Edge Cases Testing. Test empty content, minimal documents, boundary values, null/missing fields, and source mapping edge cases. Create ~25-30 tests with validation helpers. See claude-notes/plans/2025-10-26-k199-edge-cases.md for detailed plan.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T21:23:02.252196Z","updated_at":"2025-10-26T20:10:34.761200Z","closed_at":"2025-10-26T20:10:34.761200Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-1c5v","title":"Phase 1: Core template infrastructure","description":"Add quarto-doctemplate dependency, create src/template/ module with bundle.rs (TemplateBundle struct, JSON parsing), context.rs (MetaValue to TemplateValue conversion), render.rs (orchestration), and mod.rs (re-exports, feature gates).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T17:43:58.954290Z","updated_at":"2025-12-05T17:52:57.650458Z","closed_at":"2025-12-05T17:52:57.650458Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-1c5v","depends_on_id":"k-y2f3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-1d4c","title":"Phase 5: WASM entry points for templates","description":"Add render_with_template entry point to wasm_entry_points accepting bundle JSON, update wasm-qmd-parser with wasm_bindgen function.","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-05T17:44:34.098318Z","updated_at":"2025-12-05T17:44:34.098318Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-1d4c","depends_on_id":"k-5u7d","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-1d4c","depends_on_id":"k-y2f3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-1qlj","title":"Phase 5: pampa integration","description":"Create pampa/src/config_meta.rs conversion layer. Implement config_to_meta(). Handle Interpretation::Markdown and PlainString. Update document rendering to use MergedConfig. Integration tests. Plan: claude-notes/plans/2025-12-07-config-merging-design.md Phase 5","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-07T20:04:03.803304Z","updated_at":"2025-12-07T20:04:03.803304Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-1qlj","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-2","title":"Phase A: Add rendering methods to quarto-error-reporting","description":"Implement to_text() and to_json() methods for DiagnosticMessage. Add generic_error() builder helper that uses Q-0-99 and accepts file!() line!() for tracking error origins.\n\nFiles to modify:\n- crates/quarto-error-reporting/src/diagnostic.rs\n- crates/quarto-error-reporting/src/rendering.rs (new)\n- crates/quarto-error-reporting/src/builder.rs\n\nJSON format should match current simple format from ErrorCollector.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T19:41:43.567512Z","updated_at":"2025-10-18T20:03:54.064275Z","closed_at":"2025-10-18T20:03:54.064275Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-2","depends_on_id":"k-1","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-20","title":"Run full test suite after location integration","description":"Run cargo test on quarto-error-reporting and quarto-markdown-pandoc, verify all pass","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:58:17.237402Z","updated_at":"2025-10-18T21:19:23.558381Z","closed_at":"2025-10-18T21:19:23.558381Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-200","title":"Performance testing and benchmarking for annotated-qmd","description":"Create performance test suite for annotated-qmd converters. Test with large documents (1000+ blocks), deeply nested structures (10+ levels deep), and complex combinations. Establish baseline performance metrics. Document acceptable performance thresholds. Create benchmark fixtures that can be run periodically to detect regressions.","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-25T21:23:06.346576Z","updated_at":"2025-11-22T17:16:20.097895Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-201","title":"Fix remaining k-197 test failures and complete fixtures","description":"1. Investigate and fix DefinitionList syntax (currently parser errors on ~ syntax). 2. Fix div-attrs test - custom attributes have null source IDs, test needs adjustment. 3. Create Null block fixture if possible (investigate if user-creatable). 4. Ensure all 49 tests pass. See claude-notes/k-197-progress.md for details.","notes":"Continuation of k-197. Full details in claude-notes/k-197-progress.md. Focus on: 1) DefinitionList syntax investigation, 2) div-attrs test fix for null attrS.kvs, 3) Null block research.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T21:36:25.616275Z","updated_at":"2025-10-25T22:04:25.755776Z","closed_at":"2025-10-25T22:04:25.755776Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-201","depends_on_id":"k-197","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-202","title":"Create test helper functions for block-types tests","description":"Create helper functions: 1) loadSourceFile(name) to load .qmd alongside JSON, 2) extractTextFromComponents(component) to recursively get text, 3) validateSourceOffset(component, expectedText, sourceFile) to verify offsets point to correct text","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T22:03:23.195605Z","updated_at":"2025-10-25T22:05:48.090250Z","closed_at":"2025-10-25T22:05:48.090250Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-202","depends_on_id":"k-201","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-203","title":"Improve OrderedList test with precise validation","description":"Replace shallow presence checks with precise validation: Check exact count (3 lists), validate text content (First/Second/Third, Fifth/Sixth/Seventh), verify start=5 for custom list, validate nested structure (parent 2 items, nested 2 items), check source locations","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T22:03:33.336516Z","updated_at":"2025-10-25T22:12:44.094540Z","closed_at":"2025-10-25T22:12:44.094540Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-203","depends_on_id":"k-201","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-203","depends_on_id":"k-202","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-204","title":"Improve DefinitionList test with precise validation","description":"Replace shallow presence checks with precise validation: Check exact count (3 definition items), validate term text (Term 1, Term 2, Formatted Term), check Term 2 has 2 definitions, validate definition content text, check source locations","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T22:03:42.531580Z","updated_at":"2025-10-25T22:19:35.159696Z","closed_at":"2025-10-25T22:19:35.159696Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-204","depends_on_id":"k-201","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-204","depends_on_id":"k-202","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-205","title":"Improve Div attributes test with precise validation","description":"Complete the partially-done test: Check actual class values (callout-note, important, panel, outer, inner), validate nested div structure (outer contains inner), check inner div content, validate all attribute source locations point to correct text","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T22:03:50.942750Z","updated_at":"2025-10-25T22:23:17.567920Z","closed_at":"2025-10-25T22:23:17.567920Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-205","depends_on_id":"k-201","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-205","depends_on_id":"k-202","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-206","title":"Improve Figure test with precise validation","description":"Replace shallow presence checks with precise validation: Check exact count (3 figures), validate IDs (fig-simple, fig-with-caption, fig-layout), check caption text content, verify image sources, validate source locations","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T22:03:59.330056Z","updated_at":"2025-10-25T22:32:59.817754Z","closed_at":"2025-10-25T22:32:59.817754Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-206","depends_on_id":"k-201","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-206","depends_on_id":"k-202","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-207","title":"Improve RawBlock test with precise validation","description":"Complete the partially-done test: Validate actual HTML content text (check for expected HTML string), validate actual LaTeX content text (check for expected LaTeX commands), ensure content matches source file text, validate source locations","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-25T22:04:08.479852Z","updated_at":"2025-10-25T22:36:04.510263Z","closed_at":"2025-10-25T22:36:04.510263Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-207","depends_on_id":"k-201","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-207","depends_on_id":"k-202","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-208","title":"Fix Image inline test - validate target structure","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-26T13:18:01.862451Z","updated_at":"2025-10-26T13:19:08.044421Z","closed_at":"2025-10-26T13:19:08.044421Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-208","depends_on_id":"k-198","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-209","title":"Fix Note (footnote) inline test - validate footnote structure","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-26T13:18:02.811801Z","updated_at":"2025-10-26T13:28:59.968188Z","closed_at":"2025-10-26T13:28:59.968188Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-209","depends_on_id":"k-198","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-21","title":"Replace SourceFile.content with FileInformation struct","description":"Replace the full content string storage in SourceFile with a FileInformation struct that stores line break offsets for efficient offset->location conversion. This is a prerequisite for the larger quarto-source-map migration.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T22:02:48.466002Z","updated_at":"2025-10-18T22:05:55.916257Z","closed_at":"2025-10-18T22:05:55.916257Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-210","title":"Fix Quoted inline test - validate SingleQuote and DoubleQuote","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-26T13:18:03.572465Z","updated_at":"2025-10-26T13:21:47.518356Z","closed_at":"2025-10-26T13:21:47.518356Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-210","depends_on_id":"k-198","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-211","title":"Fix document-level source mapping in parseRustQmdDocument","description":"CRITICAL: parseRustQmdDocument returns AnnotatedParse with empty source (start=0, end=0, source.value=''). Should compute document span from first/last elements. User-reported bug blocking interactive usage. See TODO-AUDIT-2025-10-26.md and test/document-level-source.test.ts","notes":"Detailed implementation plan in claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md. Root cause: AnnotatedParse.source should be top-level MappedString, but currently uses local substrings. Need to fix SourceInfoReconstructor to maintain top-level references and update all converters to use new API.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-26T13:47:52.697172Z","updated_at":"2025-10-26T16:01:13.072053Z","closed_at":"2025-10-26T16:01:13.072053Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-211","depends_on_id":"k-215","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-212","title":"Improve YAML tagged value encoding in AnnotatedParse","description":"Currently encodes YAML tags in kind string (e.g. 'MetaInlines:tagged:expr'). Enhancement: add optional tag field to AnnotatedParse interface in @quarto/mapped-string package. See src/meta-converter.ts:288-290 and TODO-AUDIT-2025-10-26.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-26T13:47:59.832220Z","updated_at":"2025-10-26T19:11:24.255824Z","closed_at":"2025-10-26T19:11:24.255824Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-212","depends_on_id":"k-215","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-213","title":"Improve Concat SourceInfo error reporting","description":"Concat SourceInfo uses first piece's location. May cause confusion in error reporting if error is in later piece. Consider tracking all piece locations or using span of all pieces. See src/source-map.ts:267-268 and TODO-AUDIT-2025-10-26.md","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-26T13:48:06.121405Z","updated_at":"2025-10-26T16:58:31.135004Z","closed_at":"2025-10-26T16:58:31.135004Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-213","depends_on_id":"k-215","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-214","title":"Add circular reference detection to SourceInfo resolution","description":"SourceInfo resolution doesn't detect circular references. Could cause infinite loops with malformed data. Add visited ID tracking during resolveChain traversal. Low priority (Rust parser shouldn't produce malformed data). See src/source-map.ts:302-303 and TODO-AUDIT-2025-10-26.md","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-26T13:48:12.402972Z","updated_at":"2025-11-23T13:23:08.030986Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-214","depends_on_id":"k-215","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-215","title":"TODO Audit and Resolution for @quarto/annotated-qmd","description":"Comprehensive audit of TODOs in TypeScript package found 7 items (4 untracked, 3 tracked in k-193). Created tracking tasks k-211 (critical doc source), k-212 (YAML tags), k-213 (Concat), k-214 (circular refs). Must also update TODO comments to reference beads task IDs. See TODO-AUDIT-2025-10-26.md for full report.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-26T13:48:19.434375Z","updated_at":"2025-10-26T18:41:12.897767Z","closed_at":"2025-10-26T18:41:12.897767Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-216","title":"Step 1: Add top-level MappedStrings to SourceInfoReconstructor","description":"Add topLevelMappedStrings field, validate file content in constructor, create MappedString for each file. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 1","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T15:41:30.621972Z","updated_at":"2025-10-26T15:51:28.968013Z","closed_at":"2025-10-26T15:51:28.968013Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-216","depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-217","title":"Step 2: Fix handleOriginal() to use mappedSubstring","description":"Change handleOriginal() to use mappedSubstring of top-level instead of creating new MappedString. Maintains connection to top-level file. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 2","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T15:41:36.825677Z","updated_at":"2025-10-26T15:52:07.126355Z","closed_at":"2025-10-26T15:52:07.126355Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-217","depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-217","depends_on_id":"k-216","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-218","title":"Step 3: Add public API for AnnotatedParse source fields","description":"Add getTopLevelMappedString(), getSourceLocation(), and getAnnotatedParseSourceFields() methods to SourceInfoReconstructor. Primary API for converters. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 3","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T15:41:43.395494Z","updated_at":"2025-10-26T15:52:48.294202Z","closed_at":"2025-10-26T15:52:48.294202Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-218","depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-218","depends_on_id":"k-217","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-219","title":"Step 4: Update InlineConverter to use new API","description":"Replace source/start/end extraction with getAnnotatedParseSourceFields() in all convertInline cases, convertAttr, convertTarget, and convertCitation. Run inline-types.test.ts. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 4","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T15:41:50.590981Z","updated_at":"2025-10-26T15:55:17.061504Z","closed_at":"2025-10-26T15:55:17.061504Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-219","depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-219","depends_on_id":"k-218","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-22","title":"Create FileInformation struct in quarto-source-map","description":"Create new FileInformation struct with line_breaks: Vec, total_length: usize. Implement new(content: &str) to build line breaks, and offset_to_location(offset: usize) -> Option using binary search.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T22:02:56.232581Z","updated_at":"2025-10-18T22:05:45.641994Z","closed_at":"2025-10-18T22:05:45.641994Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-22","depends_on_id":"k-21","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-220","title":"Step 5: Update BlockConverter to use new API","description":"Replace source/start/end extraction with getAnnotatedParseSourceFields() in all convertBlock cases and convertCaption. Run block-types.test.ts. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 5","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T15:41:56.222441Z","updated_at":"2025-10-26T15:56:38.514039Z","closed_at":"2025-10-26T15:56:38.514039Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-220","depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-220","depends_on_id":"k-218","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-221","title":"Step 6: Update MetadataConverter to use new API","description":"Replace source/start/end extraction with getAnnotatedParseSourceFields() in convertMetaValue and convertMeta. Run meta-conversion.test.ts. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 6","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T15:42:01.393932Z","updated_at":"2025-10-26T15:59:03.606461Z","closed_at":"2025-10-26T15:59:03.606461Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-221","depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-221","depends_on_id":"k-218","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-222","title":"Step 7: Fix DocumentConverter for document-level source","description":"Update convertDocument() to use getTopLevelMappedString(0) for document source with start=0, end=content.length. Run document-level-source.test.ts. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 7","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T15:42:08.577908Z","updated_at":"2025-10-26T15:59:39.285131Z","closed_at":"2025-10-26T15:59:39.285131Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-222","depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-222","depends_on_id":"k-219","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-222","depends_on_id":"k-220","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-222","depends_on_id":"k-221","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-223","title":"Step 8: Fix test assertions in document-level-source.test.ts","description":"Fix incorrect assertions - document start IS 0. Change notStrictEqual to strictEqual for start and end checks. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 8","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T15:42:14.577444Z","updated_at":"2025-10-26T16:00:37.293217Z","closed_at":"2025-10-26T16:00:37.293217Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-223","depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-223","depends_on_id":"k-222","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-224","title":"Step 9: Remove TODO comment and verify all tests pass","description":"Remove TODO comment from document-converter.ts. Run full test suite (npm test) - all 64 tests should pass. Close k-211 with summary. See claude-notes/plans/2025-10-26-k211-document-source-mapping-fix.md Step 9","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-26T15:42:20.667693Z","updated_at":"2025-10-26T16:01:03.217626Z","closed_at":"2025-10-26T16:01:03.217626Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-224","depends_on_id":"k-211","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-224","depends_on_id":"k-223","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-225","title":"Fix Str node source mapping off-by-one error for \"information.\"","description":"The Str node for \"information.\" in links.qmd has result=\"information.\" but source range [81, 92] which only extracts \"information\" (missing the period at position 92). The end should be 93. This was discovered by comprehensive substring invariant tests that verify source.value.substring(start, end) matches expected text.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-26T16:23:55.000071Z","updated_at":"2025-10-26T16:58:22.696385Z","closed_at":"2025-10-26T16:58:22.696385Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-226","title":"Phase 1: DocumentConverter Tests","description":"Create test/document-converter.test.ts with comprehensive tests for DocumentConverter class. Test convertDocument(), convertBlocks(), convertBlock(), convertInline(). Verify component ordering. See claude-notes/plans/2025-10-26-k192-comprehensive-testing.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-26T19:49:10.705274Z","updated_at":"2025-10-26T19:53:02.425030Z","closed_at":"2025-10-26T19:53:02.425030Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-227","title":"Phase 2: Complex Document Tests","description":"Create test/complex-documents.test.ts with end-to-end tests using realistic complex documents. Create blog-post.qmd, academic-paper.qmd, tutorial.qmd fixtures. Validate full document structure. See claude-notes/plans/2025-10-26-k192-comprehensive-testing.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-26T19:49:22.874276Z","updated_at":"2025-10-26T19:59:08.815485Z","closed_at":"2025-10-26T19:59:08.815485Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-228","title":"Phase 4: Components Tree Validation","description":"Create validateComponentsTree() helper function. Enhance existing tests with tree structure validation. Test component ordering, nesting, and navigation patterns. See claude-notes/plans/2025-10-26-k192-comprehensive-testing.md","notes":"Phase 4 complete - 27 tree validation tests created and committed. Successfully found and fixed 2 bugs: k-231 (metadata ordering) and k-233 (Figure source ranges). Current: 142/145 tests passing (98%). Remaining 3 failures need investigation: (1) Image attr-value ordering (Str@826 vs attr-value@876), (2) Child/parent start position mismatch, (3) Table attr-id nesting (child end 210 > parent end 180). Code committed in 861dcb3.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-26T19:49:29.306526Z","updated_at":"2025-10-26T23:02:19.102887Z","closed_at":"2025-10-26T23:02:19.102887Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-229","title":"Phase 5: Performance Baseline Tests","description":"Create test/performance.test.ts with performance baseline tests. Generate large test documents (100-200 blocks, deeply nested structures). Measure conversion time, set baseline expectations. See claude-notes/plans/2025-10-26-k192-comprehensive-testing.md","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-26T19:49:34.117898Z","updated_at":"2025-11-22T19:42:44.401741Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-23","title":"Add comprehensive tests for FileInformation","description":"Test FileInformation::new and offset_to_location with: empty files, single line, multiple lines, offsets at line boundaries, out of bounds, Unicode content. Verify binary search correctness.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T22:03:02.484217Z","updated_at":"2025-10-18T22:05:50.600484Z","closed_at":"2025-10-18T22:05:50.600484Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-23","depends_on_id":"k-21","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-23","depends_on_id":"k-22","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-230","title":"Phase 6: Documentation and Examples","description":"Expand README with linting examples, complete API reference, and cookbook recipes. Document AnnotatedParse tree structure and source mapping best practices. See claude-notes/plans/2025-10-26-k192-comprehensive-testing.md","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-26T19:49:39.672447Z","updated_at":"2025-11-22T20:09:34.747691Z","closed_at":"2025-11-22T20:09:34.747691Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-231","title":"Bug: Metadata components not in source order","notes":"Tree validation tests found that metadata (mapping) components are not in source order. Example from simple.json: components array has [key@26, value@34, key@4, value@11] instead of [key@4, value@11, key@26, value@34]. This violates the source ordering invariant. Bug is in meta-converter.ts.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-26T20:23:27.043263Z","updated_at":"2025-10-26T21:07:37.710896Z","closed_at":"2025-10-26T21:07:37.710896Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-231","depends_on_id":"k-228","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-232","title":"Bug: Invalid source ranges (start=0, end=0) for Plain/Figure blocks","notes":"Tree validation found Plain blocks inside Figure elements with invalid source ranges (start=0, end=0). Root cause: Figure contains nested blocks (block.c[2]) that don't have their own source info IDs in the Rust JSON output. These are synthetic Plain blocks created by Pandoc for figure captions and image wrappers. Options: 1) Skip validation for synthetic blocks, 2) Derive source ranges from parent/children context, 3) Fix Rust parser to provide source info for these blocks.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-26T20:23:27.903527Z","updated_at":"2025-10-26T20:37:15.192830Z","closed_at":"2025-10-26T20:37:15.192830Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-232","depends_on_id":"k-228","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-233","title":"Bug: quarto-markdown-pandoc provides invalid source ranges for Figure blocks","notes":"Rust parser bug: Figure blocks and their nested Plain blocks have source ranges [0, 0] in sourceInfoPool. Diagnosed with minimal test case (examples/minimal-figure.qmd). Root cause: Source tracking not working for Figure AST construction. See detailed diagnosis in claude-notes/plans/2025-10-26-k233-figure-source-bug.md. Blocking: k-228 tree validation (5 failing tests).","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-26T20:36:24.625848Z","updated_at":"2025-10-26T20:54:16.503510Z","closed_at":"2025-10-26T20:54:16.503510Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-233","depends_on_id":"k-228","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-234","title":"Bug: Image/Link components not in source order","description":"In inline-converter.ts, Image and Link elements construct their components array as [attr, content, target], but in the source the order is [content, target, attr]. This violates source ordering and causes tree validation failures. Example: blog-post.qmd has ![Quarto Logo](url){width=200} where caption is at 826-837 and attr is at 870-879, but components array has attr before caption.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-26T21:10:00.438422Z","updated_at":"2025-10-26T21:10:41.080365Z","closed_at":"2025-10-26T21:10:41.080365Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-234","depends_on_id":"k-228","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-235","title":"Bug: Space element at position 0 inside Para at position 543","description":"Tree validation found a Space inline element with start position 0 inside a Para block starting at position 543 in academic-paper.qmd. This violates the nesting invariant (child start >= parent start). Investigation needed to determine if this is a TypeScript converter issue or Rust parser issue. Test: 'children source ranges checked recursively' in tree-validation.test.ts.","notes":"ROOT CAUSE IDENTIFIED: Rust parser bug. Space after Cite element in footnote gets sourceInfoPool entry with range [0,0]. Found in academic-paper.qmd at source ID 148. The Space appears after '@ipcc2021' inside footnote '^[See @ipcc2021 for comprehensive discussion]'. Source ID 148 maps to range [0,0] instead of actual position (~558-559). This causes TypeScript tree validation to fail because Space reconstructs with start=0, end=0. Location: likely in inline parser when processing Cite elements inside Note content.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-26T21:12:20.784021Z","updated_at":"2025-10-26T21:28:19.311741Z","closed_at":"2025-10-26T21:28:19.311741Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-235","depends_on_id":"k-228","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-236","title":"Bug: Table attr-id extends beyond table boundary","description":"Tree validation found a Table element with an attr-id child that extends beyond the table's end position (attr-id ends at 210, table ends at 180). This violates the nesting invariant (child end <= parent end). Likely occurs when table attributes are positioned after the table in source. Test: 'comprehensive validation - all test documents' in tree-validation.test.ts.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-26T21:12:30.035402Z","updated_at":"2025-10-26T21:47:18.290867Z","closed_at":"2025-10-26T21:47:18.290867Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-236","depends_on_id":"k-228","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-237","title":"Bug: Multi-citation component ordering violates source order","description":"Tree validation fails with 'Space start 811 >= citation-id start 813' in academic-paper.qmd. In multi-citation contexts like [@doe2020; @smith2020], citation-id components are placed after all content (Str/Space), but should be interleaved by source position. Current: [Str, Space, Str, cit-id-1, cit-id-2]. Expected: [Str, cit-id-1, Space, Str, cit-id-2]. See claude-notes/plans/2025-10-26-k237-cite-ordering.md for detailed analysis.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-26T22:48:43.787387Z","updated_at":"2025-10-26T23:01:47.435407Z","closed_at":"2025-10-26T23:01:47.435407Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-237","depends_on_id":"k-236","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-238","title":"Bug: Table nesting violation - Plain caption extends beyond Table boundary","description":"After fixing k-236 and k-237, a new table nesting issue appeared: 'Child Plain end 1168 should be <= parent Table end 1132'. This indicates the table caption Plain element extends beyond the Table's end position. Need to investigate if k-236 fix over-extended table bounds or if caption Plain has wrong bounds.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-26T22:54:06.715172Z","updated_at":"2025-10-26T23:01:49.334469Z","closed_at":"2025-10-26T23:01:49.334469Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-238","depends_on_id":"k-237","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-239","title":"bd-8 Phase 1: Audit existing Schema::from_yaml() implementation","description":"Audit the existing Rust Schema::from_yaml() implementation against quarto-cli patterns. Test all 12 YAML syntax patterns. Document what works, what's broken, what's missing. Deliverable: Comprehensive audit report written to claude-notes/.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T18:04:24.035941Z","updated_at":"2025-10-27T18:08:16.912137Z","closed_at":"2025-10-27T18:08:16.912137Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-239","depends_on_id":"k-8","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-24","title":"Update SourceFile to use FileInformation","description":"Replace content: Option with file_info: Option in SourceFile struct. Update SourceContext::add_file to accept content and build FileInformation. Update without_content() method.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T22:03:07.306929Z","updated_at":"2025-10-18T22:05:50.601812Z","closed_at":"2025-10-18T22:05:50.601812Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-24","depends_on_id":"k-21","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-24","depends_on_id":"k-23","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-240","title":"bd-8 Phase 2: Fix identified gaps in Schema::from_yaml()","description":"Fix all gaps identified in Phase 1 audit. Priority order: Critical (common use cases) → High (many quarto-cli schemas) → Medium (completeness) → Low (nice-to-have). Test-driven: failing test → implementation → passing test for each fix.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T18:04:30.876111Z","updated_at":"2025-10-27T19:08:07.071665Z","closed_at":"2025-10-27T19:08:07.071665Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-240","depends_on_id":"k-239","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-240","depends_on_id":"k-8","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-241","title":"bd-8 Phase 3: Comprehensive testing with real quarto-cli schemas","description":"Parse all quarto-cli definition schemas from definitions.yml. Parse schemas from document-execute.yml. Create round-trip validation tests. Ensure all quarto-cli schemas parse successfully without errors.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T18:04:36.879689Z","updated_at":"2025-10-27T19:12:40.073286Z","closed_at":"2025-10-27T19:12:40.073286Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-241","depends_on_id":"k-240","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-241","depends_on_id":"k-8","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-242","title":"bd-8 Phase 4: Documentation for Schema::from_yaml()","description":"Create comprehensive documentation: API docs with quarto-cli examples, pattern correspondence table mapping YAML → Rust, usage guide. File: private-crates/quarto-yaml-validation/SCHEMA-FROM-YAML.md","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T18:04:43.589719Z","updated_at":"2025-10-27T19:23:12.685582Z","closed_at":"2025-10-27T19:23:12.685582Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-242","depends_on_id":"k-241","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-242","depends_on_id":"k-8","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-243","title":"Refactor schema.rs into smaller modules before Phase 2 implementation","description":"schema.rs is 1299 lines and will grow significantly with Phase 2 additions (arrayOf, maybeArrayOf, record, etc.). Split into logical modules for better maintainability and reduced context size:\n\nProposed structure:\n- schema/mod.rs - Schema enum, types, SchemaRegistry\n- schema/types.rs - Schema struct definitions (Boolean, Number, String, etc.)\n- schema/annotations.rs - SchemaAnnotations and parsing\n- schema/parser.rs - from_yaml() entry point and dispatch\n- schema/parsers/primitive.rs - boolean, number, string, null, any parsers\n- schema/parsers/composite.rs - anyOf, allOf, array, object parsers\n- schema/parsers/enum.rs - enum parser\n- schema/parsers/ref.rs - ref parser\n- schema/helpers.rs - Helper functions (get_hash_string, yaml_to_json_value, etc.)\n\nBenefits:\n- Smaller files (<300 lines each)\n- Reduced token usage when editing specific parsers\n- Easier to review and test\n- Clear separation of concerns\n- Prepares for Phase 2 additions\n\nThis refactoring should be completed BEFORE starting Phase 2 (k-240).","notes":"Detailed refactoring plan: claude-notes/plans/2025-10-27-schema-refactoring-structure.md\n\nModule structure:\n- schema/mod.rs (~150 lines) - Schema enum, public API\n- schema/types.rs (~250 lines) - All schema struct definitions\n- schema/annotations.rs (~100 lines) - SchemaAnnotations\n- schema/parser.rs (~100 lines) - from_yaml entry point\n- schema/parsers/primitive.rs (~200 lines) - boolean, number, string, null, any\n- schema/parsers/enum.rs (~100 lines) - enum parser\n- schema/parsers/ref.rs (~50 lines) - ref parser\n- schema/parsers/combinators.rs (~120 lines) - anyOf, allOf\n- schema/parsers/arrays.rs (~90 lines) - array parser\n- schema/parsers/objects.rs (~250 lines) - object parser\n- schema/parsers/wrappers.rs (~50 lines) - future use\n- schema/helpers.rs (~200 lines) - helper functions\n\nLargest file after Phase 2: ~280 lines (objects.rs)\nEstimated time: 2-3 hours","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T18:13:15.494043Z","updated_at":"2025-10-27T18:26:27.793481Z","closed_at":"2025-10-27T18:26:27.793481Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-243","depends_on_id":"k-240","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-243","depends_on_id":"k-8","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-244","title":"Implement P2/P3 YAML schema patterns for completeness","description":"Implement remaining YAML schema patterns identified in the bd-8 audit but deferred as lower priority. These patterns are not critical for current quarto-cli usage but would provide completeness.\n\nReference: claude-notes/plans/2025-10-27-bd-8-yaml-schema-from-yaml-comprehensive-plan.md\nReference: claude-notes/audits/2025-10-27-bd-8-phase1-schema-from-yaml-audit.md\n\nP2 Patterns (Medium priority - used in some quarto-cli schemas):\n- Nested property extraction (double setBaseSchemaProperties pattern)\n- Schema inheritance (super/baseSchema)\n- ResolveRef vs ref distinction\n- PropertyNames support\n- NamingConvention validation\n- AdditionalCompletions support\n\nP3 Patterns (Lower priority - rarely used):\n- Pattern as schema type\n\nCurrent status: All P0/P1 patterns complete with 100% success rate on tested schemas. These P2/P3 patterns are enhancements for edge cases and advanced usage.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-27T19:28:37.353676Z","updated_at":"2025-10-27T20:44:24.504843Z","closed_at":"2025-10-27T20:44:24.504843Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-245","title":"Implement nested property extraction (double setBaseSchemaProperties)","description":"Implement the double property application pattern from quarto-cli where annotations can be applied at multiple levels.\n\nPattern: Properties defined at outer level should merge with/override properties at inner level.\n\nExample from quarto-cli:\n\n\nThe inner schema gets its own annotations, plus inherits/merges with outer annotations.\n\nSee: claude-notes/plans/2025-10-27-bd-8-yaml-schema-from-yaml-comprehensive-plan.md\nImplementation location: src/schema/parsers/wrappers.rs (TODO comment exists)\n\nEstimated: 2-3 hours","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T19:28:48.030448Z","updated_at":"2025-10-27T19:38:17.309306Z","closed_at":"2025-10-27T19:38:17.309306Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-245","depends_on_id":"k-244","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-246","title":"Implement schema inheritance (super/baseSchema)","description":"Implement schema inheritance pattern where schemas can extend base schemas. Pattern allows composing schemas by inheriting properties from a base schema. See claude-notes/plans/2025-10-27-bd-8-yaml-schema-from-yaml-comprehensive-plan.md for details. Estimated: 3-4 hours","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T19:28:55.328787Z","updated_at":"2025-10-27T20:44:06.294854Z","closed_at":"2025-10-27T20:44:06.294854Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-246","depends_on_id":"k-244","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-247","title":"Implement resolveRef vs ref distinction","description":"Implement distinction between ref and resolveRef for more sophisticated reference resolution. Currently both ref and $ref are treated identically. This pattern allows different resolution strategies. See claude-notes/plans/2025-10-27-bd-8-yaml-schema-from-yaml-comprehensive-plan.md. Estimated: 1-2 hours","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T19:29:01.798451Z","updated_at":"2025-10-27T19:46:02.772603Z","closed_at":"2025-10-27T19:46:02.772603Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-247","depends_on_id":"k-244","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-248","title":"Add propertyNames support to object schemas","description":"Add propertyNames validation to object schemas. This allows validating property names against a schema pattern (e.g., all property names must match a regex). JSON Schema standard feature. Implementation location: src/schema/parsers/objects.rs and src/schema/types.rs. Estimated: 2 hours","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T19:29:08.156793Z","updated_at":"2025-10-27T19:49:55.414023Z","closed_at":"2025-10-27T19:49:55.414023Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-248","depends_on_id":"k-244","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-249","title":"Add namingConvention validation support","description":"Add namingConvention validation for property names. Quarto extension that validates property names follow conventions like camelCase, snake_case, kebab-case. Implementation location: src/schema/parsers/objects.rs. Estimated: 2 hours","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T19:29:15.181382Z","updated_at":"2025-10-27T19:58:22.784063Z","closed_at":"2025-10-27T19:58:22.784063Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-249","depends_on_id":"k-244","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-25","title":"Update mapping.rs to use FileInformation","description":"In SourceInfo::map_offset, change from file.content.as_ref() + utils::offset_to_location to file.file_info.as_ref() + file_info.offset_to_location(). Update error handling.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T22:03:12.879249Z","updated_at":"2025-10-18T22:05:50.602620Z","closed_at":"2025-10-18T22:05:50.602620Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-25","depends_on_id":"k-21","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-25","depends_on_id":"k-24","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-250","title":"Add additionalCompletions support","description":"Add additionalCompletions annotation support. This allows specifying additional sources for IDE completions beyond static values. Quarto extension for dynamic completion support. Implementation location: src/schema/annotations.rs. Estimated: 1-2 hours","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T19:29:20.831447Z","updated_at":"2025-10-27T20:06:09.812703Z","closed_at":"2025-10-27T20:06:09.812703Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-250","depends_on_id":"k-244","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-251","title":"Implement pattern as schema type (P3)","description":"Implement pattern as a primary schema type (not just a string validation constraint). Rarely used pattern from quarto-cli. Lower priority as not commonly needed. See claude-notes/plans/2025-10-27-bd-8-yaml-schema-from-yaml-comprehensive-plan.md. Estimated: 2-3 hours","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-27T19:29:27.504693Z","updated_at":"2025-11-23T21:31:46.507675Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-251","depends_on_id":"k-244","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-252","title":"Implement schema compilation with registry support","description":"Implement Schema::compile() method that resolves eager references and merges inheritance at compilation time. This enables two-phase schema processing: (1) stateless parsing without registry, (2) compilation with registry that produces structurally complete schemas ready for validation.\n\nKey components:\n- Schema::compile(®istry) method with recursive compilation\n- Resolve eager refs (resolveRef) during compilation\n- Keep lazy refs (ref) for validation-time resolution\n- Support circular lazy references\n- Error handling for missing eager refs and circular eager refs\n- Comprehensive tests with real quarto-cli schemas\n\nSee claude-notes/designs/2025-10-27-schema-compilation-phase.md for full design.\n\nEstimated: 4-6 hours","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-27T20:31:24.990369Z","updated_at":"2025-10-27T20:49:23.303020Z","closed_at":"2025-10-27T20:49:23.303020Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-252","depends_on_id":"k-246","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-253","title":"Improve YAML validation error reporting with contextual hints and JSON output","description":"Study and improve error messages in quarto-yaml-validation to provide contextual hints about validation failures and structured JSON output. Use validate-yaml binary as test bed. Compare with TypeScript validator implementation.","notes":"Study and improve error messages in quarto-yaml-validation to provide contextual hints about validation failures and structured JSON output. Use validate-yaml binary as test bed.\n\n**Plan**: See claude-notes/plans/2025-10-27-k-253-yaml-validation-error-reporting.md\n\n**Summary**: Comprehensive analysis complete. Found key issues:\n1. Source location tracking broken (shows at line 0)\n2. No ariadne visual source highlighting (infrastructure exists but not wired up)\n3. No JSON output mode\n4. AnyOf error pruning not implemented (TypeScript has sophisticated heuristics)\n\n**Recommended phases**:\n- Phase 1 (Essential): Fix source location tracking (3-4h)\n- Phase 2 (High value): Enable ariadne visual reports (2-3h) \n- Phase 3 (Nice to have): Enhanced error messages (4-5h)\n- Phase 4 (Essential): JSON output mode (2-3h)\n- Phase 5 (Advanced): AnyOf error pruning (6-8h)\n\n**Next**: Review plan and decide which phases to implement.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T21:01:41.540528Z","updated_at":"2025-10-28T00:00:17.403934Z","closed_at":"2025-10-28T00:00:17.403934Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-254","title":"Phase 1: Fix source location tracking in YAML validation","description":"Fix broken source location tracking in quarto-yaml-validation. Currently shows '' at line 0. Need to thread SourceContext through validation pipeline.\n\n**Plan**: claude-notes/plans/2025-10-27-k-253-yaml-validation-error-reporting.md (Phase 1)\n\n**Changes**:\n1. Thread SourceContext through validate() and ValidationContext\n2. Update with_yaml_node() to properly extract file/line/column using SourceContext\n3. Update validate-yaml binary to build and pass SourceContext\n4. Test that errors show real file names and line numbers\n\n**Estimate**: 3-4 hours\n**Blocks**: k-253 (parent), k-255, k-256 (phases 2 & 3 depend on this)","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-27T21:11:34.537137Z","updated_at":"2025-10-27T21:16:13.911919Z","closed_at":"2025-10-27T21:16:13.911919Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-254","depends_on_id":"k-253","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-255","title":"Phase 2: Enable ariadne visual reports for YAML validation","description":"Add beautiful ariadne source highlighting to YAML validation errors.\n\n**Plan**: claude-notes/plans/2025-10-27-k-253-yaml-validation-error-reporting.md (Phase 2)\n\n**Changes**:\n1. Store SourceInfo in ValidationError (instead of yaml_node)\n2. Update error_conversion to set location on DiagnosticMessage\n3. Update display_diagnostic to pass SourceContext for ariadne rendering\n4. Add tests for visual output\n\n**Expected**: Box-drawing output with source highlighting showing exact error location\n\n**Estimate**: 2-3 hours\n**Depends on**: Phase 1 (k-254)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T21:11:35.341424Z","updated_at":"2025-10-27T23:42:53.114542Z","closed_at":"2025-10-27T23:42:53.114542Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-255","depends_on_id":"k-253","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-255","depends_on_id":"k-254","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-256","title":"Phase 3: Enhanced error messages for YAML validation","description":"Add richer contextual information to YAML validation error messages.\n\n**Plan**: claude-notes/plans/2025-10-27-k-253-yaml-validation-error-reporting.md (Phase 3)\n\n**Improvements**:\n1. Schema location hints (where in schema the constraint comes from)\n2. Expected value hints (show allowed enum values, number ranges)\n3. Property name suggestions (spell-check for unknown properties)\n4. Better schema path formatting (breadcrumbs instead of raw path)\n\n**Estimate**: 4-5 hours\n**Depends on**: Phase 1 (k-254)","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-27T21:11:36.370317Z","updated_at":"2025-11-22T17:16:20.080536Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-256","depends_on_id":"k-253","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-256","depends_on_id":"k-254","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-257","title":"Phase 4: Add JSON output mode to validate-yaml","description":"Add structured JSON output mode for machine-readable error reporting.\n\n**Plan**: claude-notes/plans/2025-10-27-k-253-yaml-validation-error-reporting.md (Phase 4)\n\n**Changes**:\n1. Add --json flag to validate-yaml CLI\n2. JSON output for validation errors (using DiagnosticMessage::to_json())\n3. JSON output for success case\n4. Tests for JSON output structure\n\n**Use cases**: Editor integrations, CI/CD pipelines, programmatic error handling\n\n**Estimate**: 2-3 hours\n**Independent**: Can be done in parallel with Phase 1","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-27T21:11:37.388934Z","updated_at":"2025-10-27T21:17:17.713815Z","closed_at":"2025-10-27T21:17:17.713815Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-257","depends_on_id":"k-253","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-258","title":"Phase 5: Implement anyOf error pruning in YAML validator","description":"Port sophisticated anyOf error pruning heuristics from TypeScript validator.\n\n**Plan**: claude-notes/plans/2025-10-27-k-253-yaml-validation-error-reporting.md (Phase 5)\n\n**Features**:\n1. Error quality scoring based on error type\n2. Prefer 'required field' errors over 'invalid property' errors\n3. Select best error group by quality and span size\n4. Update validate_any_of() to use pruning\n\n**Complexity**: Complex heuristics, needs careful testing against TypeScript validator\n\n**Estimate**: 6-8 hours\n**Depends on**: Phase 1 (k-254)","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-27T21:11:39.556529Z","updated_at":"2025-11-22T17:16:20.060665Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-258","depends_on_id":"k-253","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-258","depends_on_id":"k-254","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-259","title":"Redesign validation error architecture to match quarto-markdown-pandoc","description":"Redesign validation error structs to separate error data from presentation, following quarto-markdown-pandoc's architecture.\n\n**Current problem**:\n- ValidationError → DiagnosticMessage conversion loses machine-readable structure\n- JSON output is just rendered DiagnosticMessage, not purpose-built\n- Missing: full source ranges, schema paths, instance paths in structured format\n\n**Goal**:\n- Validator returns rich error struct with all information\n- Error struct can be rendered for humans (ariadne) or machines (JSON)\n- JSON output has full source ranges, paths, filenames in machine-readable format\n\n**Study**: Compare quarto-markdown-pandoc error architecture with validate-yaml\n**Output**: Written plan with proposed design","notes":"**Updated Plan (v2)**: See claude-notes/plans/2025-10-27-k-259-validation-error-architecture-redesign-v2.md\n\n**Key Changes from v1**:\n1. ✅ Use wrapper type (ValidationDiagnostic) instead of metadata field\n2. ✅ Use filename strings instead of file_id numbers\n3. ✅ Full SourceRange with start/end offsets + line/column\n\n**Architecture**:\n- Create ValidationDiagnostic wrapper type in quarto-yaml-validation\n- Wraps DiagnosticMessage for text rendering\n- Custom to_json() with purpose-built structure\n- SourceRange has filename + full range info\n\n**Benefits**:\n- Type-safe (no Option, no pattern matching)\n- Clean separation (DiagnosticMessage stays generic)\n- Filename-based JSON (no file registry needed)\n- Custom JSON tailored for validation\n- Extensible (other diagnostics can follow same pattern)\n\n**Timeline**: 6-9 hours (3-4h diagnostic + 1-2h binary + 2-3h testing)\n\n**Next**: Review v2 plan and start implementation","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-27T21:26:36.023571Z","updated_at":"2025-11-23T22:33:25.614765Z","closed_at":"2025-11-23T22:33:25.614765Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-259","depends_on_id":"k-253","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-26","title":"Update quarto-source-map tests for FileInformation","description":"Update all existing tests in context.rs and mapping.rs to work with FileInformation instead of content. Ensure serialization tests still pass. Run full test suite.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T22:03:18.170754Z","updated_at":"2025-10-18T22:05:50.603342Z","closed_at":"2025-10-18T22:05:50.603342Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-26","depends_on_id":"k-21","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-26","depends_on_id":"k-25","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-260","title":"Phase 1: Create ValidationDiagnostic wrapper type","description":"Create ValidationDiagnostic wrapper type with structured error data.\n\n**Plan**: claude-notes/plans/2025-10-27-k-259-validation-error-architecture-redesign-v2.md (Phase 1)\n\n**Tasks**:\n1. Create private-crates/quarto-yaml-validation/src/diagnostic.rs\n2. Define ValidationDiagnostic, PathSegment, SourceRange structs\n3. Implement from_validation_error() with SourceContext\n4. Implement to_json() with custom structure\n5. Implement to_text() by building DiagnosticMessage\n6. Add unit tests for conversion and serialization\n\n**Key feature**: SourceRange has filename (not file_id) + full range with start/end offsets and line/column\n\n**Estimate**: 3-4 hours","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-27T21:46:55.734981Z","updated_at":"2025-10-27T21:49:11.657292Z","closed_at":"2025-10-27T21:49:11.657292Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-260","depends_on_id":"k-259","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-261","title":"Phase 2: Update validate-yaml to use ValidationDiagnostic","description":"Switch validate-yaml binary to use ValidationDiagnostic instead of error_conversion.\n\n**Plan**: claude-notes/plans/2025-10-27-k-259-validation-error-architecture-redesign-v2.md (Phase 2)\n\n**Tasks**:\n1. Import ValidationDiagnostic from quarto-yaml-validation\n2. Update error handling in main.rs to use ValidationDiagnostic\n3. Remove error_conversion.rs module\n4. Move error code inference to ValidationDiagnostic\n5. Test both JSON and text output modes\n\n**Expected**: JSON has structured paths, filename-based source ranges\n\n**Estimate**: 1-2 hours\n**Depends on**: Phase 1 (k-260)","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-27T21:46:56.721787Z","updated_at":"2025-10-27T22:32:26.093957Z","closed_at":"2025-10-27T22:32:26.093957Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-261","depends_on_id":"k-259","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-261","depends_on_id":"k-260","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-261","depends_on_id":"k-263","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-262","title":"Phase 3: Testing and documentation for ValidationDiagnostic","description":"Add comprehensive tests and documentation for new error architecture.\n\n**Plan**: claude-notes/plans/2025-10-27-k-259-validation-error-architecture-redesign-v2.md (Phase 3)\n\n**Tasks**:\n1. Add integration tests for JSON structure (instance_path, schema_path, source_range)\n2. Add integration tests for text output (ariadne visual display)\n3. Document JSON schema for downstream consumers\n4. Add usage examples to documentation\n5. Optional: Create TypeScript type definitions for JSON output\n\n**Success criteria**: \n- JSON output has structured arrays for paths\n- JSON has filename + full source ranges\n- Text output uses ariadne box-drawing\n- All tests pass\n\n**Estimate**: 2-3 hours\n**Depends on**: Phase 2 (k-261)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T21:46:57.559367Z","updated_at":"2025-10-27T23:47:22.612432Z","closed_at":"2025-10-27T23:47:22.612432Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-262","depends_on_id":"k-259","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-262","depends_on_id":"k-261","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-263","title":"Add structured ValidationErrorKind enum to replace string parsing","description":"Replace string-based error messages with structured ValidationErrorKind enum.\n\n**Problem**: Current code parses error message strings to infer error codes and types. This is fragile and not machine-readable.\n\n**Solution**: Add ValidationErrorKind enum with variants like:\n- TypeMismatch { expected, got }\n- MissingRequiredProperty { property }\n- InvalidEnumValue { value, allowed }\n- etc.\n\n**Changes**:\n1. Create ValidationErrorKind enum in error.rs\n2. Update ValidationError to have 'kind' field\n3. Update validator.rs to create structured errors\n4. Update ValidationDiagnostic to use kind instead of parsing\n5. Add message() method to format human-readable text from kind\n\n**Benefits**:\n- No string parsing for error codes\n- Type-safe error handling\n- Better JSON output with structured data\n- Extensible for future error types\n\n**Estimate**: 3-4 hours (touches many validation sites)\n**Blocks**: k-261 (Phase 2)","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-27T22:10:32.279643Z","updated_at":"2025-10-27T22:18:56.921501Z","closed_at":"2025-10-27T22:18:56.921501Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-263","depends_on_id":"k-259","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-264","title":"Make ValidationDiagnostic JSON output machine-readable by serializing ValidationErrorKind directly","description":"Store ValidationErrorKind structurally in ValidationDiagnostic and serialize it to JSON instead of converting to strings early.\n\n**Plan**: claude-notes/plans/2025-10-27-machine-readable-validation-errors.md\n\n**Summary**: Currently ValidationDiagnostic converts ValidationErrorKind to strings at construction time, losing structured data. JSON consumers must parse strings instead of accessing typed fields.\n\n**Solution**: Add Serialize/Deserialize to ValidationErrorKind, store it in ValidationDiagnostic, serialize directly to JSON. Generate message/hints lazily only when needed for text output.\n\n**Estimate**: 2-3 hours","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-27T22:48:38.257347Z","updated_at":"2025-10-27T22:53:08.602927Z","closed_at":"2025-10-27T22:53:08.602927Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-265","title":"Implement Pandoc AST to ANSI terminal writer","description":"Implement a complete Pandoc AST to ANSI terminal writer using crossterm for styling. This will enable rich formatted console output for diagnostic messages and other terminal content.\n\n**Design**: claude-notes/designs/pandoc-ast-to-ansi-writer.md\n\n**Approach**: Option B (Full writer with block support)\n- Use crossterm for terminal styling\n- Follow existing writer pattern in quarto-markdown-pandoc/src/writers/\n- Implement incrementally: inlines first, then blocks\n\n**Architecture**:\n- Location: quarto-markdown-pandoc/src/writers/ansi.rs\n- Pattern: AnsiWriter struct with recursive traversal\n- Config: Colors, width, indent settings\n\n**Integration**:\n- Complement ariadne (source context) with formatted content rendering\n- Use in DiagnosticMessage for rich message content\n- Reusable for debug output, help text, console messages","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-28T00:18:43.258418Z","updated_at":"2025-10-28T17:41:33.456561Z","closed_at":"2025-10-28T17:41:33.456561Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-266","title":"Implement inline element rendering for ANSI writer","description":"Implement ANSI rendering for all Pandoc inline elements using crossterm.\n\n**Scope**: All inline types from src/pandoc/inline.rs\n\n**Minimal implementation for**:\n- Str, Space, SoftBreak, LineBreak (plain text)\n- Emph (italic via crossterm)\n- Strong (bold via crossterm)\n- Code (styled background/foreground)\n- Link (underline + cyan)\n- Math (yellow text)\n- Strikeout, Underline, Superscript, Subscript\n- SmallCaps, Quoted\n- Span (with attribute handling)\n\n**Defer complex rendering**:\n- Cite (render as plain text for now)\n- Note (render as superscript marker for now)\n- Image (render as [Image: alt text] for now)\n- RawInline (pass through or skip)\n\n**Testing**:\n- Unit tests for each inline type\n- Snapshot tests with ANSI escape codes\n- Test nested inlines (e.g., **bold with *italic* inside**)\n\n**Estimate**: 4-5 hours","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T00:18:53.377275Z","updated_at":"2025-10-28T17:41:10.099815Z","closed_at":"2025-10-28T17:41:10.099815Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-266","depends_on_id":"k-265","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-267","title":"Implement block element rendering for ANSI writer","description":"Implement ANSI rendering for Pandoc block elements using crossterm.\n\n**Phase 1 - Minimal blocks (initial implementation)**:\n- Plain: Render inlines directly\n- Para: Render inlines with newline after\n- **Panic on all other blocks** with helpful message\n\n**Phase 2 - Core blocks** (expand incrementally):\n- Header (levels 1-6 with styling)\n- BulletList (with indentation)\n- OrderedList (with numbering)\n- CodeBlock (with syntax highlighting via syntect?)\n- BlockQuote (with left border/indent)\n- HorizontalRule (line across terminal)\n\n**Phase 3 - Complex blocks** (future):\n- DefinitionList\n- Table (ASCII table layout)\n- Figure (with caption)\n- Div (with class/id styling)\n- LineBlock (preserve line breaks)\n\n**Implementation strategy**:\n- Start with Plain/Para only (panic on others)\n- Add blocks incrementally based on need\n- Each block added in separate commit\n- Update tests as blocks are implemented\n\n**Testing**:\n- Test Plain and Para thoroughly first\n- Verify panic messages are helpful\n- Add tests as each block type is implemented\n\n**Estimate**: \n- Phase 1: 2 hours\n- Phase 2: 8-10 hours\n- Phase 3: 8-12 hours (defer)","notes":"Implementation plan: claude-notes/plans/2025-10-27-ansi-writer-block-types.md\n\nPhase 2 in progress: Implementing Paragraph, consecutive Plain handling, Div with colors, BulletList with depth cycling, and OrderedList with calculated indentation.\n\nUsing context pattern from qmd.rs with DivContext for line-by-line color styling.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-28T00:19:04.115095Z","updated_at":"2025-10-28T17:41:16.899192Z","closed_at":"2025-10-28T17:41:16.899192Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-267","depends_on_id":"k-265","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-267","depends_on_id":"k-266","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-268","title":"Parser fails to recognize horizontal rules (---) in qmd files","description":"The qmd parser is not correctly parsing horizontal rules (---). They appear to be getting confused with YAML metadata delimiters. When parsing a file with --- horizontal rules, they are completely omitted from the AST.\n\nTest case in test-fixtures/horizontal-rule.qmd shows the issue - only 2 paragraphs are parsed instead of 3 paragraphs with 2 horizontal rules between them.\n\nThis needs investigation in the tree-sitter grammar or block parser logic.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-28T15:30:49.771050Z","updated_at":"2025-10-28T16:15:27.884278Z","closed_at":"2025-10-28T16:15:27.884278Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-269","title":"Implement smart terminal color detection using OSC 10/11 queries","description":"Terminals support querying their current foreground/background colors using OSC 10/11 escape sequences. This could enable smart color selection in the ANSI writer.\n\nImplementation would:\n- Query terminal colors using \\x1b]10;?\\x1b\\ and \\x1b]11;?\\x1b\\\n- Parse RGB response format (rgb:RRRR/GGGG/BBBB)\n- Detect dark vs light backgrounds\n- Adapt color palette for better contrast\n- Fall back to current defaults if query fails\n\nChallenges:\n- Requires raw terminal mode\n- Not available in pipes/redirects\n- Adds complexity and latency\n- Should be behind feature flag\n\nSee claude-notes/terminal-color-querying.md for detailed research and implementation notes.","status":"open","priority":4,"issue_type":"feature","created_at":"2025-10-28T15:52:38.687896Z","updated_at":"2025-11-23T20:12:12.904383Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-27","title":"Migrate quarto-markdown-pandoc to use quarto-source-map","description":"Replace pandoc::location types with quarto-source-map throughout quarto-markdown-pandoc. Integrate quarto-yaml for YAML parsing with Substring mappings. Enable proper source location tracking for all errors. See docs/for-claude/quarto-source-map-integration-plan.md","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-18T22:16:55.284427Z","updated_at":"2025-10-20T20:01:48.597932Z","closed_at":"2025-10-20T20:01:48.597932Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-27","depends_on_id":"k-26","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-270","title":"Phase E: Retire old ErrorCollector implementations","description":"Remove TextErrorCollector and JsonErrorCollector implementations now that DiagnosticCollector has replaced them.\n\n**Files to modify**:\n- crates/quarto-markdown-pandoc/src/utils/error_collector.rs\n - Remove TextErrorCollector struct and impl\n - Remove JsonErrorCollector struct and impl\n - Keep ErrorCollector trait (used by DiagnosticCollector)\n - Move tests to diagnostic_collector.rs if needed\n\n**Verification**:\n- Run cargo test to ensure no code depends on old collectors\n- Only DiagnosticCollector should be used in production code\n- Old collectors exist only for their own tests currently","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-28T17:46:03.678537Z","updated_at":"2025-10-28T17:47:48.299992Z","closed_at":"2025-10-28T17:47:48.299992Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-271","title":"Add HTML comment support to block parser (tree-sitter-markdown)","description":"Implement HTML_COMMENT external token in tree-sitter-markdown scanner to handle comments that span block boundaries. This is the critical first step - comments starting inline can span across what would be block markers (lists, headings, etc.) and must be consumed atomically. Reference: claude-notes/plans/2025-10-28-html-comment-REVISED.md","notes":"Block parser HTML comment support implemented and working! Cross-boundary test (test 36) successfully prevents list recognition inside comments. Block parser now consumes HTML comments atomically. Inline parser still needed for proper tokenization.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-28T21:28:16.360174Z","updated_at":"2025-10-28T21:32:43.820599Z","closed_at":"2025-10-28T21:32:43.820599Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-272","title":"Add HTML comment support to inline parser (tree-sitter-markdown-inline)","description":"Implement HTML_COMMENT external token in tree-sitter-markdown-inline scanner. Handles simple inline comments that don't span blocks. Depends on block parser being done first. Reference: claude-notes/plans/2025-10-28-html-comment-REVISED.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-28T21:28:17.503552Z","updated_at":"2025-10-28T21:38:04.698925Z","closed_at":"2025-10-28T21:38:04.698925Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-272","depends_on_id":"k-271","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-273","title":"Add HTML comment AST conversion in quarto-markdown-pandoc","description":"Add handlers to convert html_comment nodes to RawInline/RawBlock in Pandoc AST. Convert to format 'quarto-html-comment'. Requires both parsers to be complete. Reference: claude-notes/plans/2025-10-28-html-comment-REVISED.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-28T21:28:18.290599Z","updated_at":"2025-10-28T21:40:59.039113Z","closed_at":"2025-10-28T21:40:59.039113Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-273","depends_on_id":"k-271","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-273","depends_on_id":"k-272","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-274","title":"Refactor tree-sitter grammar processing for new node structure","description":"Major refactoring to handle completely redesigned tree-sitter grammar. All node names changed and grammar provides much more fine-grained syntax tree. Need to rewrite native_visitor processor one node at a time. See plan: claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md","status":"closed","priority":0,"issue_type":"epic","created_at":"2025-10-31T14:36:55.340098Z","updated_at":"2025-11-03T01:43:36.133317Z","closed_at":"2025-11-03T01:43:36.133317Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-275","title":"Implement pandoc_str node handler","description":"First node to implement in refactoring. Handler for basic text strings. Test with simple 'hello' document. Should convert to Pandoc Str inline.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T14:37:34.058615Z","updated_at":"2025-10-31T14:48:36.628598Z","closed_at":"2025-10-31T14:48:36.628598Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-275","depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-276","title":"Implement pandoc_emph node handler","description":"Implement handler for pandoc_emph (emphasis with * or _) in tree-sitter refactoring.\n\nTest-driven approach:\n1. Write test for basic emphasis: *hello*\n2. Verify test fails\n3. Implement handler in treesitter.rs\n4. Verify test passes\n5. Test with verbose mode (no MISSING warnings)\n\nComplexity: Medium - has children (recursive inline content)\nEstimate: 30-45 minutes\n\nSee: claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md (Phase 2)","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T15:57:12.683711Z","updated_at":"2025-10-31T20:18:54.857654Z","closed_at":"2025-10-31T20:18:54.857654Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-276","depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-277","title":"Implement pandoc_strong node handler","description":"Implement handler for pandoc_strong (strong emphasis **text** or __text__). Use same pattern as pandoc_emph with delimiter space injection. See claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md and 2025-10-31-fix-emphasis-space-nodes.md for reference.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T17:22:18.614636Z","updated_at":"2025-10-31T17:24:44.809925Z","closed_at":"2025-10-31T17:24:44.809925Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-277","depends_on_id":"k-276","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-278","title":"Implement pandoc_strikeout node handler","description":"Implement handler for pandoc_strikeout (strikeout ~~text~~). Use same pattern as pandoc_emph with delimiter space injection. See claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md and 2025-10-31-fix-emphasis-space-nodes.md for reference.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T17:22:20.386978Z","updated_at":"2025-10-31T17:26:10.708652Z","closed_at":"2025-10-31T17:26:10.708652Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-278","depends_on_id":"k-276","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-279","title":"Implement pandoc_superscript node handler","description":"Implement handler for pandoc_superscript (superscript ^text^). Use same pattern as pandoc_emph with delimiter space injection. See claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md and 2025-10-31-fix-emphasis-space-nodes.md for reference.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T17:22:22.343854Z","updated_at":"2025-10-31T17:26:10.724745Z","closed_at":"2025-10-31T17:26:10.724745Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-279","depends_on_id":"k-276","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-28","title":"Phase 1: Replace quarto-yaml::SourceInfo with quarto-source-map::SourceInfo","description":"Update all structs, function signatures in quarto-yaml to use quarto-source-map::SourceInfo. Remove old SourceInfo type. Update all tests. This makes quarto-yaml use the unified source tracking system.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T22:17:02.001689Z","updated_at":"2025-10-18T22:22:04.031733Z","closed_at":"2025-10-18T22:22:04.031733Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-28","depends_on_id":"k-27","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-280","title":"Implement pandoc_subscript node handler","description":"Implement handler for pandoc_subscript (subscript ~text~). Use same pattern as pandoc_emph with delimiter space injection. See claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md and 2025-10-31-fix-emphasis-space-nodes.md for reference.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T17:22:24.211415Z","updated_at":"2025-10-31T17:26:10.740469Z","closed_at":"2025-10-31T17:26:10.740469Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-280","depends_on_id":"k-276","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-281","title":"Implement pandoc_code_span node handler","description":"Implement handler for pandoc_code_span (inline code with backticks) in tree-sitter refactoring.\n\nTest-driven approach:\n1. Write tests for basic code spans: `code`\n2. Verify tests fail\n3. Implement handler in treesitter.rs\n4. Verify tests pass\n5. Test with verbose mode (no MISSING warnings)\n\nComplexity: Medium - has content extraction and optional attributes\nEstimate: 2-3 hours\n\nSee: claude-notes/plans/2025-10-31-implement-pandoc-code-span.md (Phase 2)","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T18:02:42.782274Z","updated_at":"2025-10-31T18:09:46.765Z","closed_at":"2025-10-31T18:09:46.765Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-281","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-282","title":"Fix backslash escape handling in pandoc_str","description":"Backslash escapes are currently captured inside pandoc_str nodes but not processed correctly.\n\n**Current behavior**:\nInput: hello\\*world\nOur output: Str \"hello\\\\*world\" (backslash preserved)\nPandoc output: Str \"hello*world\" (backslash consumed)\n\n**Root cause**:\nThe tree-sitter grammar captures backslashes as part of pandoc_str (see regex with \\\\. at tree-sitter-markdown/grammar.js:531). They need post-processing to convert escape sequences to literal characters.\n\n**Investigation needed**:\n- Determine if backslashes should be in separate backslash_escape nodes or handled within pandoc_str\n- Check if the grammar needs changes or just the handler logic\n- Add comprehensive tests for all escapable characters\n\n**Context**: Discovered during tree-sitter refactoring (k-274). See also: claude-notes/plans/2025-10-31-tree-sitter-qmd-cleanup-completion.md which mentions this as future work.\n\n**Estimate**: 2-3 hours (investigation + fix + tests)","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-31T20:22:28.124505Z","updated_at":"2025-10-31T21:26:24.646709Z","closed_at":"2025-10-31T21:26:24.646709Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-282","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-283","title":"Implement atx_heading node handler","description":"Implement handler for atx_heading (# Heading syntax) in tree-sitter refactoring.\n\n**Current behavior**:\nInput: # Heading\nError: [TOP-LEVEL MISSING NODE] Warning: Unhandled node kind: atx_heading\nPanic: Expected Block or Section, got IntermediateUnknown\n\n**Node structure** (from verbose output):\n- atx_heading (parent)\n - atx_h1_marker (# symbol)\n - pandoc_str (heading text)\n - Optional: attribute_specifier ({#id .class})\n\n**Handler needs to**:\n1. Extract heading level from marker (atx_h1_marker through atx_h6_marker)\n2. Process inline content (children between marker and end)\n3. Handle optional attribute specifier\n4. Return Pandoc Header block\n\n**Test-driven approach**:\n1. Write tests for all 6 heading levels (# through ######)\n2. Test with attributes: # Heading {#id}\n3. Test with inline formatting: # Heading with *emphasis*\n4. Verify tests fail\n5. Implement handler in treesitter.rs\n6. Verify tests pass\n\n**Complexity**: Medium - needs level extraction, inline content processing, attribute handling\n**Estimate**: 1-2 hours\n\n**Phase**: Phase 3 (Structure and Headings)\nSee: claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T20:22:40.410877Z","updated_at":"2025-10-31T20:27:18.613533Z","closed_at":"2025-10-31T20:27:18.613533Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-283","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-284","title":"Implement pandoc_math node handler","description":"Implement handler for pandoc_math (inline math with $...$) in tree-sitter refactoring.\n\n**Current behavior**:\nInput: $x + y$\nError: [TOP-LEVEL MISSING NODE] Warning: Unhandled node kind: pandoc_math\n\n**Node structure** (from verbose output):\n- pandoc_math (parent)\n - $ (opening delimiter)\n - (content - anonymous regex match)\n - $ (closing delimiter)\n\n**Pandoc expects**:\nMath InlineMath \"x + y\"\n\n**Handler needs to**:\n1. Extract content from middle child (between delimiters)\n2. Create Math inline with InlineMath type\n3. Return Pandoc Math inline\n\n**Test-driven approach**:\n1. Write tests for basic inline math: $x$, $x + y$\n2. Test with complex expressions: $\\frac{a}{b}$\n3. Verify tests fail\n4. Implement handler in treesitter.rs\n5. Verify tests pass\n\n**Complexity**: Medium - similar to code_span but simpler (no attributes)\n**Estimate**: 45-60 minutes\n\n**Phase**: Phase 4 (Links and Math)\nSee: claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T20:29:53.947253Z","updated_at":"2025-10-31T20:34:08.012522Z","closed_at":"2025-10-31T20:34:08.012522Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-284","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-285","title":"Implement pandoc_display_math node handler","description":"Implement handler for pandoc_display_math (display math with $$...$$) in tree-sitter refactoring.\n\n**Current behavior**:\nInput: $$x + y$$\nError: [TOP-LEVEL MISSING NODE] Warning: Unhandled node kind: pandoc_display_math\n\n**Node structure** (from verbose output):\n- pandoc_display_math (parent)\n - $$ (opening delimiter)\n - (content - anonymous regex match)\n - $$ (closing delimiter)\n\n**Pandoc expects**:\nMath DisplayMath \"x + y\"\n\n**Handler needs to**:\n1. Extract content from middle child (between delimiters)\n2. Create Math inline with DisplayMath type\n3. Return Pandoc Math inline\n\n**Test-driven approach**:\n1. Write tests for basic display math: $$x$$, $$x + y$$\n2. Test with complex expressions: $$\\frac{a}{b}$$\n3. Verify tests fail\n4. Implement handler in treesitter.rs\n5. Verify tests pass\n\n**Complexity**: Medium - nearly identical to pandoc_math\n**Estimate**: 30-45 minutes\n\n**Phase**: Phase 4 (Links and Math)\nSee: claude-notes/plans/2025-10-31-treesitter-grammar-refactoring.md","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T20:30:04.836140Z","updated_at":"2025-10-31T20:34:25.418640Z","closed_at":"2025-10-31T20:34:25.418640Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-285","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-286","title":"Implement attribute processing for code_span nodes","description":"Add support for processing attribute nodes (id, classes, key-value pairs) in tree-sitter refactoring.\n\n**Current behavior**:\nInput: `code`{.lang}\nOutput: Code ( \"\" , [] , [] ) \"code\"\nExpected: Code ( \"\" , [ \"lang\" ] , [] ) \"code\"\n\n**Problem**: Attribute-related nodes are not handled in native_visitor:\n- attribute_specifier, attribute_id, attribute_class\n- key_value_specifier, key_value_key, key_value_value\n- Delimiter nodes: {, }, =\n\n**Solution**: Add handlers for all attribute nodes to convert them to intermediate types that existing processors expect.\n\n**Phases**:\n1. Add leaf node handlers (attribute_id, attribute_class, key_value nodes)\n2. Add key_value_specifier handler\n3. Add commonmark_specifier handler\n4. Add attribute_specifier handler\n5. Add comprehensive tests\n\n**Estimate**: 2 hours\n\n**Plan**: claude-notes/plans/2025-10-31-attribute-processing-plan.md","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T21:00:10.572098Z","updated_at":"2025-10-31T21:06:03.468672Z","closed_at":"2025-10-31T21:06:03.468672Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-286","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-287","title":"Implement pandoc_span and pandoc_image node handlers","description":"Implement handlers for spans, links, and images in tree-sitter refactoring.\n\n**Three node types to handle**:\n- pandoc_span with target → Link\n- pandoc_span without target → Span\n- pandoc_image → Image\n\n**QMD Design Difference**: [text] produces Span with empty attributes (differs from Pandoc which outputs literal brackets).\n\n**Phases**:\n1. Add leaf node handlers (url, title, delimiters)\n2. Add target handler\n3. Add content handler\n4. Add pandoc_span handler\n5. Add pandoc_image handler\n6. Add comprehensive tests\n\n**Plan**: claude-notes/plans/2025-10-31-spans-links-images.md\n\n**Estimate**: 2.5-3 hours\n\n**Note**: Figure block conversion for standalone images is deferred to future work.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-31T21:48:59.425928Z","updated_at":"2025-10-31T21:56:50.024368Z","closed_at":"2025-10-31T21:56:50.024368Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-287","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-288","title":"Implement pandoc_single_quote and pandoc_double_quote handlers","description":"Add support for quoted text (single and double quotes). See plan at claude-notes/plans/2025-10-31-quoted-nodes.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T22:27:44.235081Z","updated_at":"2025-10-31T22:31:33.507566Z","closed_at":"2025-10-31T22:31:33.507566Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-289","title":"Refactor complex match arms in treesitter.rs to helper files","description":"Extract pandoc_span, pandoc_image, pandoc_single_quote, pandoc_double_quote, target, and content handlers into span_link_helpers.rs and quote_helpers.rs. See plan at claude-notes/plans/2025-10-31-refactor-helpers.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T22:40:20.839551Z","updated_at":"2025-10-31T22:45:27.917951Z","closed_at":"2025-10-31T22:45:27.917951Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-29","title":"Phase 1: Add parent source tracking to YamlBuilder","description":"Add parent_source_info: Option field to YamlBuilder. Modify make_source_info() to create Substring mappings when parent exists. This enables parsing YAML extracted from .qmd files.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T22:17:08.484045Z","updated_at":"2025-10-18T22:38:35.985808Z","closed_at":"2025-10-18T22:38:35.985808Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-29","depends_on_id":"k-27","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-290","title":"Implement pandoc_strikeout node handler","description":"Implement handler for pandoc_strikeout (strikethrough with ~~text~~) in tree-sitter refactoring. Similar pattern to emph/strong. Includes delimiter handling and content processing. Estimate: 45-60 minutes.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T23:21:41.619424Z","updated_at":"2025-10-31T23:25:35.363177Z","closed_at":"2025-10-31T23:25:35.363177Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-291","title":"Implement editorial mark node handlers (insert, delete, highlight, edit_comment)","description":"Implement handlers for editorial marks in tree-sitter refactoring: pandoc_insert, pandoc_delete, pandoc_highlight, pandoc_edit_comment. These are used for tracking changes and comments. Similar patterns with delimiter + content. Estimate: 2-3 hours.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T23:21:48.712666Z","updated_at":"2025-10-31T23:43:51.661380Z","closed_at":"2025-10-31T23:43:51.661380Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-292","title":"Implement citation node handler","notes":"See claude-notes/citation-grammar-limitation.md for detailed explanation of how bracketed citations are handled. The grammar parses [@cite] as a span containing a citation, so we unwrap and transform the citation mode in process_pandoc_span().","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T23:51:02.067565Z","updated_at":"2025-11-01T00:27:43.842428Z","closed_at":"2025-11-01T00:18:04.049524Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-292","depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-293","title":"Implement inline_note node handler","description":"Implement handler for inline_note nodes (^[note text]) in tree-sitter refactoring. Current behavior: node is parsed but not handled, causing MISSING warnings. Estimate: 2-3 hours.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T23:51:13.479057Z","updated_at":"2025-11-01T00:33:23.693705Z","closed_at":"2025-11-01T00:33:23.693705Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-293","depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-294","title":"Implement note_reference node handler","description":"Implement handler for note_reference nodes ([^note_id]) in tree-sitter refactoring. Current behavior: causes parse error. Needs grammar investigation and handler implementation. Estimate: 2-3 hours.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T23:51:23.953311Z","updated_at":"2025-11-01T00:55:15.367334Z","closed_at":"2025-11-01T00:55:15.367334Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-294","depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-295","title":"Implement shortcode node handler","description":"Implement handler for shortcode nodes ({{< shortcode >}}) in tree-sitter refactoring. Current behavior: node is parsed but not handled, causing MISSING warnings. Needs to handle shortcode_name, parameters, and delimiters. Estimate: 3-4 hours.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-31T23:51:26.006737Z","updated_at":"2025-11-01T00:01:04.973064Z","closed_at":"2025-11-01T00:01:04.973064Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-295","depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-296","title":"Fix citation whitespace handling - leading space should be Space node, not in Str content","description":"Citations currently include leading whitespace in their content Str instead of creating a separate Space node.\n\n**Current behavior**:\n- 'Hi @cite' produces: [Str \"Hi\", Cite [...] [Str \" @cite\"]]\n Note the leading space in \" @cite\"\n- 'Hi@cite' produces: [Str \"Hi\", Cite [...] [Str \"@cite\"]]\n\n**Expected behavior**:\n- 'Hi @cite' should produce: [Str \"Hi\", Space, Cite [...] [Str \"@cite\"]]\n- 'Hi@cite' should produce: [Str \"Hi\", Cite [...] [Str \"@cite\"]]\n\n**Root cause**:\nThe citation handler in treesitter.rs uses node_text() which includes leading whitespace from the tree-sitter node. Similar to inline_note_reference, citations need to detect leading whitespace and inject a Space node.\n\n**Location**: \n- Handler: crates/quarto-markdown-pandoc/src/pandoc/treesitter.rs:727-730\n- Helper: crates/quarto-markdown-pandoc/src/pandoc/treesitter_utils/citation.rs\n\n**Solution approach**:\nSimilar to the inline_note_reference fix, check if the node text starts with whitespace and return IntermediateInlines with [Space, Cite] instead of just IntermediateInline(Cite).\n\n**Related**: Same issue exists in inline_note_reference (currently being fixed).","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-01T01:43:05.552750Z","updated_at":"2025-11-01T01:48:55.678220Z","closed_at":"2025-11-01T01:48:55.678220Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-297","title":"Implement pandoc_block_quote handler","description":"Block quotes (> quote) currently crash with 'Expected Block or Section, got IntermediateUnknown'.\n\n**Status**: Handler commented out at line 1098\n**Helper**: process_block_quote exists in treesitter_utils/block_quote.rs\n**Impact**: CRASHES on any document with block quotes\n\n**Implementation**:\n1. Uncomment line 1098 in treesitter.rs\n2. Write failing test for basic block quote\n3. Verify helper works with new grammar\n4. Add edge case tests (empty, nested, multi-line)\n\n**Test cases needed**:\n- Basic single-line quote\n- Multi-line quote\n- Nested quotes\n- Quotes containing other blocks (paragraphs, lists)\n- Empty quotes\n\n**Priority**: CRITICAL - Phase 1, no dependencies","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-01T02:13:00.705623Z","updated_at":"2025-11-01T02:14:33.743053Z","closed_at":"2025-11-01T02:14:33.743053Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-297","depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-298","title":"Implement pandoc_horizontal_rule handler","description":"Horizontal rules (---) currently crash.\n\n**Status**: Handler commented out at line 1101 (as 'thematic_break')\n**Helper**: process_thematic_break exists\n**Impact**: CRASHES on horizontal rules\n\n**Implementation**:\n1. Uncomment line 1101 in treesitter.rs\n2. Write tests (trivial - no children)\n\n**Test cases needed**:\n- Basic horizontal rule\n- Multiple rules in document\n- Rules between paragraphs\n\n**Priority**: CRITICAL - Phase 1, very simple","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-01T02:13:02.084294Z","updated_at":"2025-11-01T02:26:25.684869Z","closed_at":"2025-11-01T02:26:25.684869Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-298","depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-299","title":"Implement pandoc_code_block handler","description":"Fenced code blocks (```code```) currently crash.\n\n**Status**: Handler commented out at line 943 (as 'fenced_code_block')\n**Helper**: process_fenced_code_block exists\n**Impact**: CRASHES on any fenced code block\n\n**Note**: Only backtick fences supported (no tildes, no indented code blocks)\n\n**Implementation**:\n1. Uncomment line 943 in treesitter.rs\n2. Write tests for code with/without language\n3. Test attribute handling\n4. Test multi-line code\n\n**Test cases needed**:\n- Code block without language\n- Code block with language\n- Code block with attributes\n- Empty code block\n- Multi-line code\n- Code with special characters\n\n**Priority**: CRITICAL - Phase 1","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-01T02:13:03.487717Z","updated_at":"2025-11-01T02:32:27.301036Z","closed_at":"2025-11-01T02:32:27.301036Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-299","depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-2lz5","title":"Add tests for error types (quarto-csl, quarto-citeproc)","description":"Error handling code in quarto-csl/error.rs and quarto-citeproc/error.rs has 0% coverage. Add tests for error creation, display, and conversion.","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-31T16:02:11.501812Z","updated_at":"2025-12-31T16:13:09.415728Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-2lz5","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-2po4","title":"Improve coverage: shortcode.rs","description":"Session baseline: 76.33% line coverage. Target: beat baseline. Focus on shortcode processing functions.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-03T19:42:58.391673Z","updated_at":"2026-01-03T19:55:59.905970Z","closed_at":"2026-01-03T19:55:59.905970Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-2po4","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-2sts","title":"HTML writer incorrectly prefixes all attributes with data-","description":"The pampa HTML writer prefixes ALL key-value attributes with 'data-'. This causes: 1) Standard HTML5 attributes like style, title, dir to become data-style, data-title, data-dir. 2) Existing data-* attributes to be doubled (data-foo -> data-data-foo). 3) ARIA attributes to become data-aria-*. See plan: claude-notes/plans/2025-12-27-html-attr-handling.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-27T19:29:42.542869Z","updated_at":"2025-12-27T20:03:00.911330Z","closed_at":"2025-12-27T20:03:00.911330Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-2tu9","title":"Unify MetaValueWithSourceInfo and ConfigValue","description":"Replace MetaValueWithSourceInfo with ConfigValue throughout the codebase.\n\nCurrently we have two very similar types:\n- MetaValueWithSourceInfo (quarto-pandoc-types) - for document metadata\n- ConfigValue (quarto-config) - for configuration merging\n\nThis duplication causes:\n- Conversion functions between the types\n- Utility functions written twice\n- Growing complexity as codebase expands\n\nThe unification requires:\n1. Refactor ConfigValueKind: add Path/Glob/Expr variants, remove unused interpretation field\n2. Add ConfigMapEntry with key_source tracking (matches MetaMapEntry)\n3. Add InterpretationContext for default interpretation (doc vs project)\n4. Update yaml_to_meta_with_source_info to produce ConfigValue\n5. Migrate all 32 files that reference MetaValueWithSourceInfo\n6. Remove MetaValueWithSourceInfo\n\nKey insight: The current interpretation field is never read outside tests. Using explicit ConfigValueKind variants (Path, Glob, Expr) is cleaner and fixes the bug where !path is treated identically to !str.\n\nThis is a prerequisite for k-ic1o (ConfigValue integration into pipeline).\n\nPlan: claude-notes/plans/2025-12-29-unify-meta-and-config-types.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-29T16:58:54.378421Z","updated_at":"2025-12-30T03:55:24.256186Z","closed_at":"2025-12-30T03:55:24.256186Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-2tu9","depends_on_id":"k-ic1o","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-3","title":"Phase B: Create DiagnosticCollector bridge","description":"Create DiagnosticCollector that implements ErrorCollector trait but uses quarto-error-reporting internally.\n\nFiles to create:\n- crates/quarto-markdown-pandoc/src/utils/diagnostic_collector.rs\n\nFiles to modify:\n- crates/quarto-markdown-pandoc/Cargo.toml (add quarto-error-reporting dep)\n- crates/quarto-markdown-pandoc/src/utils/mod.rs\n\nShould be drop-in replacement for TextErrorCollector/JsonErrorCollector.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T19:41:44.514766Z","updated_at":"2025-10-18T20:14:40.405072Z","closed_at":"2025-10-18T20:14:40.405072Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-3","depends_on_id":"k-1","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-3","depends_on_id":"k-2","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-3","depends_on_id":"k-7","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-30","title":"Phase 1: Add parse_with_parent API to quarto-yaml","description":"Add new parse_with_parent(content: &str, parent: SourceInfo) function. Passes parent to YamlBuilder. Creates Substring mappings for all YAML nodes relative to parent.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T22:17:15.191598Z","updated_at":"2025-10-18T22:39:34.512581Z","closed_at":"2025-10-18T22:39:34.512581Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-30","depends_on_id":"k-27","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-300","title":"Implement pandoc_list and list_item handlers","description":"Lists (bullet and ordered) currently crash.\n\n**Status**: Both handlers commented out at lines 1093-1094\n**Helpers**: process_list and process_list_item exist\n**Impact**: CRASHES on any list (bullet or ordered)\n\n**Complexity**: HIGH - recursive structure, list attributes, tight/loose spacing\n\n**Implementation**:\n1. Uncomment both handlers (lines 1093-1094)\n2. Write tests for bullet lists\n3. Write tests for ordered lists\n4. Test nested lists (recursion)\n5. Test tight vs loose spacing\n6. Test list attributes (start number, etc.)\n\n**Test cases needed**:\n- Simple bullet list\n- Simple ordered list\n- Nested bullet lists\n- Nested ordered lists\n- Mixed nesting\n- Tight lists\n- Loose lists\n- Lists with complex content (paragraphs, code blocks)\n- List start numbers\n\n**Priority**: CRITICAL - Phase 2, recursive structure","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-01T02:13:04.736166Z","updated_at":"2025-11-01T03:01:51.434711Z","closed_at":"2025-11-01T03:01:51.434711Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-300","depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-301","title":"Implement pandoc_div handler","description":"Fenced divs (::: {.class}) currently crash.\n\n**Status**: Handler commented out at line 1099 (as 'fenced_div_block')\n**Helper**: process_fenced_div_block exists\n**Impact**: CRASHES on any fenced div\n\n**Implementation**:\n1. Uncomment line 1099 in treesitter.rs\n2. Write tests for divs without attributes\n3. Write tests for divs with attributes\n4. Test nested divs\n5. Test divs with complex content\n\n**Test cases needed**:\n- Basic div without attributes\n- Div with id and classes\n- Div with key-value attributes\n- Nested divs\n- Divs containing other blocks (lists, quotes, code)\n- Empty divs\n\n**Priority**: CRITICAL - Phase 3","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-01T02:13:06.000104Z","updated_at":"2025-11-01T02:38:59.095103Z","closed_at":"2025-11-01T02:38:59.095103Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-301","depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-302","title":"Implement note_definition_fenced_block handler","description":"Fenced note definitions (::: ^ref) produce warnings and likely crash.\n\n**Status**: Handler commented out at lines 992-994\n**Helper**: process_note_definition_fenced_block exists\n**Impact**: Cannot use multi-block note definitions\n\n**Example**:\n```\n::: ^mynote\nMulti-block note content.\n\nSecond paragraph.\n:::\n```\n\n**Implementation**:\n1. Uncomment lines 992-994 in treesitter.rs\n2. Write tests for basic single-block notes\n3. Write tests for multi-block notes\n4. Test with complex content (lists, quotes)\n5. Verify integration with note references ([^mynote])\n\n**Test cases needed**:\n- Single-block note definition\n- Multi-block note definition\n- Note with lists\n- Note with quotes\n- Note with code blocks\n- Integration with [^ref] references\n\n**Priority**: HIGH - Phase 3, user-requested feature","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T02:13:07.372432Z","updated_at":"2025-11-01T02:42:05.008450Z","closed_at":"2025-11-01T02:42:05.008450Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-302","depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-303","title":"Implement pipe_table handlers (6 sub-handlers)","description":"Pipe tables (| Header |) currently crash.\n\n**Status**: All 6 handlers commented out at lines 1111-1118\n**Helpers**: Complete suite exists\n**Impact**: CRASHES on any pipe table\n\n**Complexity**: VERY HIGH - multiple sub-nodes, alignment, caption\n\n**Sub-handlers needed**:\n1. pipe_table_delimiter_cell (line 1111)\n2. pipe_table_header | pipe_table_row (lines 1112-1113)\n3. pipe_table_delimiter_row (line 1115)\n4. pipe_table_cell (line 1116)\n5. caption (line 1117)\n6. pipe_table (line 1118)\n\n**Implementation**:\n1. Uncomment all 6 handlers\n2. Write test for basic 2x2 table\n3. Test column alignment (:---, :---:, ---:)\n4. Test with caption (: Caption text)\n5. Test with inline formatting in cells\n6. Test edge cases (empty cells, single column)\n\n**Test cases needed**:\n- Basic 2x2 table\n- Table with left alignment\n- Table with center alignment\n- Table with right alignment\n- Table with mixed alignment\n- Table with caption\n- Table with formatted cells (bold, code, etc.)\n- Single-column table\n- Tables with empty cells\n- Wide tables\n\n**Priority**: MEDIUM - Phase 4, most complex, can defer","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-01T02:13:08.806054Z","updated_at":"2025-11-01T04:14:26.674066Z","closed_at":"2025-11-01T04:14:26.674066Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-303","depends_on_id":"k-274","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-304","title":"Add caption node support to pipe_table grammar","description":"The tree-sitter grammar currently does NOT support captions for pipe tables, even though the handler code in process_pipe_table() has caption support (lines 188-194).\n\n**Current state**:\n- Grammar (tree-sitter-qmd): No caption rule for pipe tables\n- Handler code: Has caption processing logic (commented out in treesitter.rs:1123)\n- Pandoc syntax: Supports captions like:\n\n```\n| Col1 | Col2 |\n|------|------|\n| A | B |\n\n: Caption text here\n```\n\n**Work needed**:\n1. Add caption node to tree-sitter-qmd grammar in grammar.js\n2. Update pipe_table rule to optionally include caption\n3. Run tree-sitter generate and tree-sitter build\n4. Run tree-sitter test and verify\n5. Uncomment caption handler in treesitter.rs:1123\n6. Write tests for tables with captions\n7. Test multi-line captions\n8. Test captions with inline formatting\n\n**Files to modify**:\n- crates/tree-sitter-qmd/tree-sitter-markdown/grammar.js\n- crates/quarto-markdown-pandoc/src/pandoc/treesitter.rs (line 1123)\n- tests/test_treesitter_refactoring.rs\n\n**Estimate**: 2-3 hours\n\n**Note**: Discovered during k-303 (pipe table implementation). See claude-notes/plans/2025-10-31-pipe-table-implementation.md line 101-104.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-01T04:21:51.580375Z","updated_at":"2025-11-01T12:28:54.434190Z","closed_at":"2025-11-01T12:28:54.434190Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-305","title":"Implement caption support for pipe tables","description":"Implement caption support for pipe tables with dual grammar structure (immediate and separated captions).\n\n**Background**: Grammar supports captions in two ways:\n1. Immediate: Caption inside pipe_table node (no empty line)\n2. Separated: Caption as sibling block after pipe_table (with empty line)\n\nBoth need to produce same Pandoc output with caption attached to table.\n\n**Implementation phases**:\n1. Update process_caption() to handle new grammar (direct inline nodes)\n2. Uncomment caption handler in treesitter.rs:1123\n3. Add post-processing to process_section() to attach separated captions\n4. Write comprehensive tests (7 tests)\n\n**Plan**: claude-notes/plans/2025-10-31-caption-implementation.md\n\n**Estimate**: 3 hours\n\n**Files to modify**:\n- src/pandoc/treesitter_utils/caption.rs\n- src/pandoc/treesitter.rs (line 1123)\n- src/pandoc/treesitter_utils/section.rs\n- tests/test_treesitter_refactoring.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T12:24:22.361377Z","updated_at":"2025-11-01T12:28:42.208115Z","closed_at":"2025-11-01T12:28:42.208115Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-306","title":"Fix reference note definition parsing causing document-level crashes","description":"tests/smoke/001.qmd with '^ he llo^' crashes with 'Expected Block or Section, got IntermediateUnknown'. Need to investigate tree-sitter node for reference note definitions and add handler. Blocks: test_do_not_smoke, unit_test_snapshots_qmd. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 1","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-01T19:50:31.823921Z","updated_at":"2025-11-03T02:04:50.201748Z","closed_at":"2025-11-03T02:04:50.201748Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-306","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-307","title":"Fix YAML frontmatter handling causing document crashes","description":"tests/snapshots/qmd/horizontal-rules-vs-metadata.qmd crashes when document has YAML frontmatter. Need to fix document-level parsing to handle metadata blocks. Blocks: unit_test_snapshots_qmd. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 1","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-01T19:50:33.208941Z","updated_at":"2025-11-03T01:50:25.625159Z","closed_at":"2025-11-03T01:50:25.625159Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-307","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-308","title":"Fix citation parsing logic - wrong mode and prefix/suffix distribution","description":"[prefix @c1 suffix; @c2; @c3] should produce single Cite with 3 citations (NormalCitation mode), but produces Spans with individual Cites (AuthorInText mode). Fix citation processing in pandoc/treesitter_utils/spans.rs. Blocks: unit_test_snapshots_native, test_qmd_roundtrip_consistency. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 2","notes":"Analysis complete. Found existing make_cite_inline() function in inline.rs that handles multi-citation parsing. Just need to call it from span_link_helpers.rs. See: claude-notes/investigations/2025-11-02-k-308-code-reuse-analysis.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-01T19:50:34.510781Z","updated_at":"2025-11-03T02:33:34.131856Z","closed_at":"2025-11-03T02:33:34.131856Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-308","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-309","title":"Fix LineBreak vs SoftBreak - hard line breaks not recognized","description":"'Line one \\nLine two' (two trailing spaces) should produce LineBreak but produces SoftBreak. Check tree-sitter grammar for hard_line_break node and add handler. Blocks: test_html_writer, test_json_writer. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 2","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-01T19:50:35.834553Z","updated_at":"2025-11-03T13:59:13.885450Z","closed_at":"2025-11-03T13:59:14.885450Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-309","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-31","title":"Phase 1: Update parse() to use new quarto-source-map system","description":"Update parse() and parse_file() to create FileId and SourceInfo, then call parse_with_parent. Maintain backward compatibility.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T22:17:21.470005Z","updated_at":"2025-10-18T22:41:22.376621Z","closed_at":"2025-10-18T22:41:22.376621Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-31","depends_on_id":"k-27","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-310","title":"Add validation to reject raw attributes in QMD","description":"'# Hello {=world}' should fail to parse (raw attributes not allowed in QMD) but currently passes. Add validation logic. Blocks: test_disallowed_in_qmd_fails. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 2","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-01T19:50:38.318053Z","updated_at":"2025-11-03T14:06:29.115490Z","closed_at":"2025-11-03T14:06:29.115490Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-310","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-311","title":"Fix nested inline formatting - strikeout inside subscript","description":"'~he~~l~~lo~' should parse as subscript containing strikeout, but produces RawInline leftover. Grammar issue with nested ~ and ~~. Blocks: unit_test_corpus_matches_pandoc_commonmark. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 3","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-01T19:50:39.684354Z","updated_at":"2025-11-03T14:12:51.300456Z","closed_at":"2025-11-03T14:12:51.300456Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-311","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-312","title":"Add underline class to Underline inline conversion","description":"'[underline]{.underline}' should produce Underline inline, not Span. Add special case in span processing. Blocks: unit_test_corpus_matches_pandoc_markdown. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 3","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-01T19:50:41.081508Z","updated_at":"2025-11-01T20:00:04.740233Z","closed_at":"2025-11-01T20:00:04.740233Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-312","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-313","title":"Fix blockquote header roundtrip - extra Space in output","description":"'> ## Header' roundtrips with extra Space at end. Fix header inline content generation. Blocks: test_empty_blockquote_roundtrip. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 3","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-01T19:50:42.533997Z","updated_at":"2025-11-03T14:18:53.658811Z","closed_at":"2025-11-03T14:18:53.658811Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-313","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-314","title":"Fix source map range calculation in tree-sitter processing","description":"Source info pool ranges are incorrect causing snapshot test failures. Review source location tracking. Blocks: unit_test_snapshots_json. See plan: claude-notes/plans/2025-11-01-fix-test-suite.md Phase 4","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-01T19:50:43.951908Z","updated_at":"2025-11-03T14:41:02.451758Z","closed_at":"2025-11-03T14:41:02.451758Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-314","depends_on_id":"k-274","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-315","title":"Fix list item block ending detection - lists not ending after blank lines","description":"List items never 'end' properly. Example: '- a\\n\\nb' keeps the list item open when it should end. Block quotes work correctly with the same pattern. Likely issue in scanner.c block ending logic.","notes":"Session 2 investigation: claude-notes/investigations/2025-11-01-session-2-approaches-tried.md. Confirmed Pandoc behavior, attempted 2 implementation approaches. Core issue: tree-sitter has no non-consuming lookahead API. Blank line ambiguity (continue vs end list) requires looking at what follows. All approaches blocked by lexer limitations. May need grammar-level restructuring or acceptance of Pandoc differences.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-01T20:28:42.009884Z","updated_at":"2025-11-03T15:05:33.123244Z","closed_at":"2025-11-03T15:05:33.123244Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-316","title":"Fix quote delimiter space handling - spaces being lost between adjacent quoted elements","description":"Test tests/writers/json/quoted.md fails because spaces captured in quote delimiters are being lost. Need to modify process_quoted to handle delimiter spaces like emphasis/strong/code-span do. Plan: claude-notes/investigations/2025-11-03-quote-delimiter-space-handling-plan.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-03T15:45:18.757343Z","updated_at":"2025-11-03T15:54:03.088546Z","closed_at":"2025-11-03T15:54:03.088546Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-317","title":"Fix table caption attribute handling and stray space","description":"Table captions with attributes (e.g., {tbl-colwidths=\"[30,70]\"}) are not properly parsed. The attribute should be applied to the Table element, and the trailing space before the attribute should be trimmed from caption text. See claude-notes/plans/2025-11-03-table-caption-attr-fix.md for details.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-03T17:30:59.098098Z","updated_at":"2025-11-03T17:45:28.627632Z","closed_at":"2025-11-03T17:45:28.627632Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-318","title":"Replace HashMap with LinkedHashMap in Attr type for deterministic ordering","description":"The Attr type uses HashMap which doesn't preserve insertion order, causing non-deterministic test output (e.g., test 030.qmd). Need to replace with LinkedHashMap to ensure attributes appear in insertion order consistently.","notes":"Plan: claude-notes/plans/2025-11-03-hashmap-to-linkedhashmap-migration.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-03T19:49:25.667321Z","updated_at":"2025-11-03T20:04:22.926055Z","closed_at":"2025-11-03T20:04:22.926055Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-319","title":"Fix definition list div tests - add blank lines before closing fence","description":"After tree-sitter grammar overhaul, fenced divs containing bullet lists require a blank line before the closing :::. This is due to how the external scanner handles block closing tokens when lists are involved. The definition list processing code in postprocess.rs is working correctly, but the test files need to be updated to conform to the new grammar requirement.\n\nFiles to update:\n- tests/snapshots/native/definition-list-basic.qmd\n- tests/snapshots/native/definition-list-complex-term.qmd \n- tests/snapshots/native/definition-list-invalid-extra-blocks.qmd\n- tests/snapshots/native/definition-list-invalid-no-nested-list.qmd\n- tests/snapshots/native/definition-list-multiple-defs.qmd\n\nThe transformation logic in crates/quarto-markdown-pandoc/src/pandoc/treesitter_utils/postprocess.rs (lines 169-400) correctly:\n1. Validates div structure with is_valid_definition_list_div()\n2. Transforms valid divs into DefinitionList blocks with transform_definition_list_div()\n3. Applies the transformation via the .with_div() filter\n\nTest with blank line works correctly and produces expected output.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-03T20:26:40.029493Z","updated_at":"2025-11-03T20:29:15.855063Z","closed_at":"2025-11-03T20:29:15.855063Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-32","title":"Phase 1: Add tests for substring parsing in quarto-yaml","description":"Test that offsets map correctly through Substring. Test with SourceContext to verify mapping back to original. Test nested YAML structures with parent SourceInfo.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T22:17:28.912005Z","updated_at":"2025-10-18T22:43:13.262464Z","closed_at":"2025-10-18T22:43:13.262464Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-32","depends_on_id":"k-27","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-32","depends_on_id":"k-5","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-320","title":"Fix div fence to allow no space between ::: and attributes","description":"The div fence parser currently requires a space between ::: and attributes like :::{#id}. Pandoc supports both with and without space. Tests failing: test_div_with_id_has_attr_source, test_div_with_classes_has_attr_source","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-03T21:09:29.011271Z","updated_at":"2025-11-14T14:41:19.757841Z","closed_at":"2025-11-14T14:41:19.757841Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-321","title":"Fix target source info for links and images not being serialized to JSON","description":"When links and images are serialized to JSON, the targetS field (containing source location info for URL and title) is null. Tests failing: test_link_target_source_json_serialization, test_link_target_source_without_title, test_image_target_source_json_serialization","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-03T21:09:35.606552Z","updated_at":"2025-11-03T21:13:26.130344Z","closed_at":"2025-11-03T21:13:26.130344Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-322","title":"Update error corpus snapshot 004 for error message ordering","description":"The error corpus snapshot test for 004.qmd is failing because error messages are now appearing in a different order. Need to review and update the snapshot.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-03T21:22:04.247374Z","updated_at":"2025-11-03T21:37:04.679866Z","closed_at":"2025-11-03T21:37:04.679866Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-323","title":"Implement iterative fixing with temporary files for qmd-syntax-helper","description":"Add iterative fixing capability using temporary file architecture to handle parser limitation where only first error location is reliable.\n\n**Problem**: Parser only reliably reports first error; subsequent errors have wrong locations after error recovery\n**Solution**: Iterate (fix → reparse → fix) until convergence, using temp files as working copies\n**Plan**: claude-notes/plans/2025-11-03-iterative-fixing-with-temp-files.md\n\n**Key changes**:\n- Add tempfile dependency\n- Create temp copy of file, work on temp (all modes)\n- Iterate until convergence (no fixes in iteration)\n- Finalize: copy temp→original (in-place) or print temp (not in-place) or discard (check)\n- Add --max-iterations and --no-iteration flags\n- Add oscillation detection\n\n**Fixes**: test_div_whitespace_conversion failing test","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-04T00:07:41.857396Z","updated_at":"2025-11-04T00:14:19.103121Z","closed_at":"2025-11-04T00:14:19.103121Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-324","title":"Resolve parsing issues from large document corpus","description":"Systematically investigate and fix parsing failures in files from external-sites corpus after grammar migration. Use investigation template in claude-notes/plans/2025-11-04-parsing-failure-investigation-template.md","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-04T15:34:24.382556Z","updated_at":"2025-11-21T22:34:00.180804Z","closed_at":"2025-11-21T22:34:00.180804Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-325","title":"Fix autolink token including leading whitespace","description":"Autolink tokens from tree-sitter scanner include leading whitespace consumed during indentation calculation. Example: token spans ' ' instead of ''. Need to split token in Rust code similar to boundary marker handling. File: crates/quarto-markdown-pandoc/src/pandoc/treesitter_utils/uri_autolink.rs:25","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-04T15:34:32.944423Z","updated_at":"2025-11-04T15:49:05.993299Z","closed_at":"2025-11-04T15:49:05.993299Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-325","depends_on_id":"k-324","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-326","title":"Emit errors for unsupported constructs in native writer","description":"Inline note definitions ([^1]: content) are silently dropped by the native writer, producing malformed output. Need to emit clear DiagnosticMessage errors when encountering unsupported constructs. See plan: claude-notes/plans/2025-11-04-inline-note-writer-error-handling-v2.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-04T16:25:26.651564Z","updated_at":"2025-11-04T16:43:01.190870Z","closed_at":"2025-11-04T16:43:01.190870Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-327","title":"Audit other Quarto extension types for silent writer failures","description":"After fixing inline note definitions (k-326), audit other Quarto extension types (Shortcode, EditorialMarks, etc.) to ensure they don't have similar silent failures in writers. Each type found should get its own issue.","notes":"AUDIT COMPLETE - Found 29 panic!() statements across 4 writers:\n\nCRITICAL (P0 - Crashes on valid input):\n- Native writer: 3 panics affecting 10 extension types + ColWidth::Percentage\n- JSON writer: 2 panics affecting 4 editorial marks + CaptionBlock\n- QMD writer: 1 panic on CaptionBlock\n\nMEDIUM (P2 - Incomplete):\n- ANSI writer: 10 panics (incomplete implementation)\n\nSee comprehensive analysis:\n- claude-notes/plans/2025-11-21-k-327-extension-type-audit.md\n- claude-notes/plans/2025-11-21-k-327-all-writer-panics.md\n\nRECOMMENDATION: Start with Phase 1 - Fix native writer panics (4-6 hours)\nThen address JSON writer based on user priorities.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-04T16:25:35.162814Z","updated_at":"2025-11-22T00:21:50.917881Z","closed_at":"2025-11-22T00:21:50.917881Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-327","depends_on_id":"k-326","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-328","title":"Unicode offset bug in error diagnostics","description":"Error positions are incorrectly calculated when unicode characters precede the error. The checkmark ✓ (3-byte UTF-8) causes a 2-byte offset in error reporting.","notes":"CORRECTED ROOT CAUSE: We're passing byte offsets to ariadne but using default mode (IndexType::Char). Ariadne expects character offsets by default. Fix: Either use IndexType::Byte or convert byte offsets to char offsets. See: claude-notes/plans/2025-11-04-unicode-offset-bug.md","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-05T00:57:46.416514Z","updated_at":"2025-11-05T01:29:16.200370Z","closed_at":"2025-11-05T01:29:16.200370Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-329","title":"Fix qmd roundtrip escaping bug - all punctuation characters lose backslash escapes","description":"When parsing escaped punctuation like $3.14, the parser correctly removes the backslash, but the writer doesn't re-escape it when writing back to qmd. This affects all 30 escapable punctuation characters defined in the grammar. See plan: claude-notes/plans/2025-11-05-fix-qmd-roundtrip-escaping.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-05T12:58:26.988444Z","updated_at":"2025-11-05T13:02:51.864538Z","closed_at":"2025-11-05T13:02:51.864538Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-33","title":"Phase 2: Add SourceContext to ASTContext","description":"Add source_context: SourceContext field to ASTContext. Update constructors (new, with_filename, anonymous). Add helper primary_file_id() -> Option. Embed SourceContext inside ASTContext per Option B design.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T22:17:36.662455Z","updated_at":"2025-10-18T23:27:15.657617Z","closed_at":"2025-10-18T23:27:15.657617Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-33","depends_on_id":"k-27","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-330","title":"Fix crash in error reporting with multi-byte characters","description":"Error reporting crashes when trying to display errors in text with multi-byte UTF-8 characters. The byte indices don't align with character boundaries when passed to ariadne. Repro file: ~/today/characters.qmd","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-05T19:42:56.551912Z","updated_at":"2025-11-05T19:46:40.465850Z","closed_at":"2025-11-05T19:46:40.465850Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-331","title":"Update grammar to accept smart quotes and en-dash characters","description":"The parser currently rejects smart quotes (\", \") and en-dash (–) characters, treating them as parse errors. Need to update the pandoc_str rules in the grammar to accept these Unicode characters.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-05T19:48:08.446527Z","updated_at":"2025-11-05T20:01:28.613813Z","closed_at":"2025-11-05T20:01:28.613813Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-331","depends_on_id":"k-330","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-332","title":"Fixed column offset calculation in error reporting","description":"calculate_byte_offset was treating tree-sitter column as character offset, but tree-sitter reports column as byte offset within the line. This caused error messages to highlight wrong positions when multi-byte UTF-8 characters were present.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-05T20:01:27.544639Z","updated_at":"2025-11-05T20:01:36.295285Z","closed_at":"2025-11-05T20:01:36.295285Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-332","depends_on_id":"k-330","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-333","title":"Define CommonMark-compatible subset of qmd grammar","description":"Design and implement a formal subset of quarto-markdown that guarantees output compatibility with CommonMark 0.31.2. See claude-notes/plans/2025-11-06-commonmark-compatible-subset.md for full design.\n\nGoals:\n- 100% CommonMark spec test compliance (652 tests)\n- Validation tooling (--strict-commonmark flag)\n- Clear documentation of in/out features\n- Differential testing against reference implementation\n\nRationale: Provides migration confidence, testing foundation, and interoperability guarantees. CommonMark chosen over Pandoc because it's stable, formally specified, and testable.","notes":"REVISED PLAN - see claude-notes/plans/2025-11-06-commonmark-compatible-subset.md\n\nKEY INSIGHT: CommonMark spec only defines HTML output, not AST. We need to be precise about what we promise.\n\nREFERENCE IMPLEMENTATION: comrak (Rust CommonMark parser)\n- **Full compliance**: Passes 652/652 CommonMark 0.31.2 spec tests\n- **Critical**: Must configure for CommonMark-only mode (disable GFM extensions)\n- See claude-notes/plans/2025-11-06-comrak-ast-structure.md for detailed AST analysis\n\nAPPROACH: Whitelist subset where qmd_subset ⊂ qmd AND qmd_subset ⊂ CommonMark\n\nINCLUDED: ATX headings, fenced code, emphasis/strong, inline links, lists, blockquotes, hr\nEXCLUDED: qmd features (divs, callouts), edge cases (Setext, indented code, HTML, reference links)\n\nSEMANTIC GRAMMAR: Define subset in terms of abstract semantic structure (Document, Block, Inline, etc.)\n- Level 3: Abstract semantic structure (what we promise)\n- Level 4: Pandoc AST (how we verify - secondary test)\n- Level 5: HTML output (primary test - matches CommonMark spec)\n- Level 2: Tree-sitter CST (implementation detail - NOT what we promise)\n\nTESTING: \n- Primary: HTML output comparison (comrak HTML vs qmd HTML)\n- Secondary: Pandoc AST equivalence (comrak → HTML → Pandoc vs qmd → Pandoc)\n- Both using comrak configured for pure CommonMark (no GFM)\n\nVALIDATION: --validate-subset flag + tree-sitter queries\n\nESTIMATE: 6-9 weeks over 4 phases","status":"open","priority":2,"issue_type":"epic","created_at":"2025-11-06T17:28:34.372497Z","updated_at":"2025-11-06T22:35:30.578778Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-334","title":"Convert naked HTML elements to warnings with auto-fix to RawInline","description":"Change Q-2-6 hard error to Q-2-9 warning. Auto-convert HTML elements like ,
to RawInline nodes with format='html'. See claude-notes/plans/2025-11-12-html-element-warning-autofix.md for details.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-12T14:30:30.884858Z","updated_at":"2025-11-12T14:36:00.378413Z","closed_at":"2025-11-12T14:36:00.378413Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-335","title":"Add resolved source locations to JSON writer","description":"Add optional 'l' field to JSON output with fully resolved source positions (line/column/offset). See plan: claude-notes/plans/2025-11-12-json-resolved-locations.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-12T19:26:29.786637Z","updated_at":"2025-11-12T19:40:55.718065Z","closed_at":"2025-11-12T19:40:55.718065Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-336","title":"Add JsonConfig struct and write_with_config function","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-12T19:31:19.647326Z","updated_at":"2025-11-12T19:32:36.891887Z","closed_at":"2025-11-12T19:32:36.891887Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-336","depends_on_id":"k-335","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-337","title":"Add resolve_location helper with file_id support","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-12T19:31:20.568572Z","updated_at":"2025-11-12T19:33:41.519292Z","closed_at":"2025-11-12T19:33:41.519292Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-337","depends_on_id":"k-335","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-338","title":"Update SourceInfoSerializer to support optional locations","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-12T19:31:21.519419Z","updated_at":"2025-11-12T19:36:15.751848Z","closed_at":"2025-11-12T19:36:15.751848Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-338","depends_on_id":"k-335","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-339","title":"Update all node serialization sites (Inline/Block/etc)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-12T19:31:22.959203Z","updated_at":"2025-11-12T19:36:15.771082Z","closed_at":"2025-11-12T19:36:15.771082Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-339","depends_on_id":"k-335","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-34","title":"TypeScript/WASM Integration: SourceContext JSON Serialization","description":"Design and implement JSON serialization strategy for SourceContext/SourceInfo to enable TypeScript/quarto-cli consumption via WASM. Create bridge code to convert from Rust data structures to TypeScript MappedString. See claude-notes/source-context-typescript-integration.md for detailed analysis.","status":"closed","priority":2,"issue_type":"epic","created_at":"2025-10-19T00:24:21.492971Z","updated_at":"2025-11-22T17:48:16.603529Z","closed_at":"2025-11-22T17:48:16.603529Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-340","title":"Add --json-source-location CLI flag to main.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-12T19:31:24.309535Z","updated_at":"2025-11-12T19:37:36.301652Z","closed_at":"2025-11-12T19:37:36.301652Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-340","depends_on_id":"k-335","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-341","title":"Write tests for resolved locations feature","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-12T19:31:25.229975Z","updated_at":"2025-11-12T19:40:55.699049Z","closed_at":"2025-11-12T19:40:55.699049Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-341","depends_on_id":"k-335","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-342","title":"Implement error pruning based on outermost tree-sitter ERROR nodes","description":"Reduce excessive error diagnostics by grouping them into outermost ERROR node ranges and keeping only the first error per range.\n\nImplementation:\n- Strategy 1: Outermost ERROR nodes with first-error heuristic\n- For each ERROR range, keep earliest error (tiebreak with scoring function)\n- Add --no-prune-errors flag for debugging\n- Discard error diagnostics outside ERROR nodes\n\nSee plan: claude-notes/plans/2025-11-13-error-pruning-strategy.md\n\nTest case: ~/today/categorical-predictors.qmd (49 errors -> 2 expected)","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-13T19:51:43.108527Z","updated_at":"2025-11-13T20:39:11.144489Z","closed_at":"2025-11-13T20:39:11.144489Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-343","title":"Add Q-2-10 error detection for apostrophes in all inline constructs","description":"The apostrophe-as-quote-close error (Q-2-10) currently only detects cases in:\n- Plain text (010.qmd)\n- Bold text (011.qmd: **a' b.**)\n- Emphasis (012.qmd: *a' b.*)\n- Link text (013.qmd: [a' b](url))\n\nNeed to add error corpus examples for ALL inline constructs that contain _inlines:\n- Superscript: ^a' b.^\n- Subscript: ~a' b.~\n- Strikeout: ~~a' b.~~\n- Image alt text: ![a' b](url)\n- Span: [a' b]{.class}\n\nFor each construct:\n1. Create minimal example .qmd file\n2. Run --_internal-report-error-state to get parse state\n3. Create corresponding .json with Q-2-10 code and appropriate captures\n4. Rebuild error table with ./scripts/build_error_table.ts\n5. Test that error is properly detected\n\nThis ensures comprehensive coverage across all markdown inline syntax.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-14T16:12:24.915640Z","updated_at":"2025-11-14T16:15:41.543373Z","closed_at":"2025-11-14T16:15:41.543373Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-344","title":"Add qmd-syntax-helper conversion rule for Q-2-10 apostrophe errors","description":"Now that we have comprehensive Q-2-10 error detection for apostrophes being misinterpreted as quote closes (covering 17 inline construct types), add an automatic conversion rule in qmd-syntax-helper to fix these errors.\n\n**Error Pattern**: Q-2-10 \"Closed Quote Without Matching Open Quote\"\n- Occurs when apostrophe followed by space is interpreted as closing single quote\n- Example: `**Humans' Conceptions**` triggers error at the apostrophe\n\n**Fix Strategy**: Escape the apostrophe with backslash\n- Input: `a' b.` → Output: `a\\' b.`\n- Input: `**Humans' Conceptions**` → Output: `**Humans\\' Conceptions**`\n\n**Coverage**: Works across all inline constructs (17 types):\n- Plain text, bold, emphasis, links, images, quotes\n- Superscript, subscript, strikeout\n- Editorial marks (insert, delete, edit comment, highlight)\n- Inline footnotes, headings\n- Both star and underscore variants\n\n**Implementation**:\n1. Detect Q-2-10 error code in parser output\n2. Extract error location from error message\n3. Insert backslash before the apostrophe at that location\n4. Preserve all other formatting\n\n**Testing**:\n- Test with all 17 error corpus examples (010.qmd through 026.qmd)\n- Verify fixed output parses cleanly\n- Verify formatting is preserved (especially in nested constructs)\n\n**Reference**: Error corpus examples in resources/error-corpus/010-026.qmd","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-14T16:27:03.553254Z","updated_at":"2025-11-14T17:10:24.027024Z","closed_at":"2025-11-14T17:10:24.027024Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-345","title":"Add error messages and conversion rules for all unclosed inlines","description":"Add Q-2-12 through Q-2-26 error messages and conversion rules for 15 unclosed inline types: emphasis variants, superscript/subscript, strikeout, editorial marks, inline math, code spans, images, inline footnotes. Each gets error_catalog.json entry, error corpus files, and conversion rule.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-14T18:57:59.162421Z","updated_at":"2025-11-14T19:29:05.396509Z","closed_at":"2025-11-14T19:29:05.396509Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-346","title":"Q-2-12: Unclosed Star Emphasis","description":"Add Q-2-12 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 028.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_12.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.004982Z","updated_at":"2025-11-14T19:05:14.240363Z","closed_at":"2025-11-14T19:05:14.240363Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-346","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-347","title":"Q-2-13: Unclosed Strong Star Emphasis","description":"Add Q-2-13 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 029.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_13.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.024680Z","updated_at":"2025-11-14T19:08:00.189647Z","closed_at":"2025-11-14T19:08:00.189647Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-347","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-348","title":"Q-2-14: Unclosed Underscore Emphasis","description":"Add Q-2-14 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 030.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_14.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.042977Z","updated_at":"2025-11-14T19:10:12.751588Z","closed_at":"2025-11-14T19:10:12.751588Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-348","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-349","title":"Q-2-15: Unclosed Strong Underscore Emphasis","description":"Add Q-2-15 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 031.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_15.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.061834Z","updated_at":"2025-11-14T19:11:35.251671Z","closed_at":"2025-11-14T19:11:35.251671Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-349","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-35","title":"Add comprehensive SourceInfo JSON serialization tests","description":"Add tests in quarto-source-map that serialize various SourceInfo structures (Original, Substring, Concat, Transformed) to JSON and verify the format. Document expected JSON schema. Include examples with nested structures matching real .qmd frontmatter use case.","notes":"Tests added for all SourceMapping types (Original, Substring, Concat, Transformed) with 6 new comprehensive tests. Blocked on k-54 (unify 'l' and 's' keys) before documenting final JSON schema.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-19T00:24:29.181738Z","updated_at":"2025-11-22T00:04:48.900860Z","closed_at":"2025-11-22T00:04:48.900860Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-35","depends_on_id":"k-34","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-350","title":"Q-2-16: Unclosed Superscript","description":"Add Q-2-16 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 032.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_16.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.080788Z","updated_at":"2025-11-14T19:17:10.408383Z","closed_at":"2025-11-14T19:17:10.408383Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-350","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-351","title":"Q-2-17: Unclosed Subscript","description":"Add Q-2-17 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 033.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_17.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.099573Z","updated_at":"2025-11-14T19:17:10.410164Z","closed_at":"2025-11-14T19:17:10.410164Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-351","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-352","title":"Q-2-18: Unclosed Strikeout","description":"Add Q-2-18 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 034.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_18.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.117890Z","updated_at":"2025-11-14T19:17:10.410723Z","closed_at":"2025-11-14T19:17:10.410723Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-352","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-353","title":"Q-2-19: Unclosed Editorial Insert","description":"Add Q-2-19 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 035.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_19.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.136989Z","updated_at":"2025-11-14T19:23:39.416458Z","closed_at":"2025-11-14T19:23:39.416458Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-353","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-354","title":"Q-2-20: Unclosed Editorial Delete","description":"Add Q-2-20 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 036.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_20.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.155625Z","updated_at":"2025-11-14T19:23:39.418322Z","closed_at":"2025-11-14T19:23:39.418322Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-354","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-355","title":"Q-2-21: Unclosed Editorial Comment","description":"Add Q-2-21 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 037.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_21.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.174441Z","updated_at":"2025-11-14T19:23:39.418988Z","closed_at":"2025-11-14T19:23:39.418988Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-355","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-356","title":"Q-2-22: Unclosed Editorial Highlight","description":"Add Q-2-22 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 038.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_22.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.192589Z","updated_at":"2025-11-14T19:23:39.419721Z","closed_at":"2025-11-14T19:23:39.419721Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-356","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-357","title":"Q-2-23: Unclosed Inline Math","description":"Add Q-2-23 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 039.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_23.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.211717Z","updated_at":"2025-11-14T19:28:54.946892Z","closed_at":"2025-11-14T19:28:54.946892Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-357","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-358","title":"Q-2-24: Unclosed Code Span","description":"Add Q-2-24 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 040.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_24.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.230901Z","updated_at":"2025-11-14T19:28:54.948769Z","closed_at":"2025-11-14T19:28:54.948769Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-358","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-359","title":"Q-2-25: Unclosed Image","description":"Add Q-2-25 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 041.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_25.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.249212Z","updated_at":"2025-11-14T19:28:54.949325Z","closed_at":"2025-11-14T19:28:54.949325Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-359","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-36","title":"Design and document SourceInfo JSON schema for TypeScript","description":"Create formal documentation of the JSON schema produced by SourceInfo serialization. Include TypeScript type definitions for the deserialized structure. Document how each SourceMapping variant is represented in JSON. Create example JSON for each variant type.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-19T00:24:36.076544Z","updated_at":"2025-11-22T00:04:49.822970Z","closed_at":"2025-11-22T00:04:49.822970Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-36","depends_on_id":"k-34","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-360","title":"Q-2-26: Unclosed Inline Footnote","description":"Add Q-2-26 error message and conversion rule for unclosed inline. Steps: (1) Add to error_catalog.json, (2) Create 042.qmd/.json, (3) Run build_error_table.ts, (4) Create conversions/Q_2_26.rs, (5) Register rule, (6) Write tests","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-14T18:58:14.268605Z","updated_at":"2025-11-14T19:28:54.949855Z","closed_at":"2025-11-14T19:28:54.949855Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-360","depends_on_id":"k-345","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-361","title":"Implement prefixes feature for error corpus","description":"Add support for 'prefixes' field in error corpus JSON files to automatically generate variant test cases. See claude-notes/analysis/2025-11-14-prefixes-feature-design.md for detailed design.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-15T01:01:01.646988Z","updated_at":"2025-11-15T01:04:00.707457Z","closed_at":"2025-11-15T01:04:00.707457Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-362","title":"Fix byte vs character offset bug in error URL generation","description":"Error text shows column 113 but clickable URL shows column 118, likely due to multi-byte characters. Need to ensure both use character offsets, not byte offsets.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-19T22:09:27.976177Z","updated_at":"2025-11-19T22:18:08.690160Z","closed_at":"2025-11-19T22:18:08.690160Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-363","title":"Fix source location tracking for recursive qmd parsing in YAML metadata","description":"When YAML metadata values are parsed as markdown (e.g., in include-in-header.text), warnings show incorrect source locations (e.g., line 1:1 instead of line 12). The recursive parse creates a new context with filename '' and offsets relative to the substring, but diagnostics are added to the parent without adjusting offsets.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-19T22:23:50.854501Z","updated_at":"2025-11-20T20:27:40.567512Z","closed_at":"2025-11-20T20:27:40.567512Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-364","title":"Analyze downsides of Option 1 for YAML recursive parse fix","description":"Deep analysis of Option 1 (post-process diagnostics) approach","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-19T22:27:01.147969Z","updated_at":"2025-11-20T20:26:22.926768Z","closed_at":"2025-11-20T20:26:22.926768Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-364","depends_on_id":"k-363","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-365","title":"Q-2-28 Phase 1: Error Detection (catalog + corpus)","description":"Implement Q-2-28 error detection for line breaks before escaped shortcode closing delimiter >}}}\n\nTasks:\n- Add Q-2-28 entry to error_catalog.json\n- Create Q-2-28.json corpus file with prefixes and suffixes\n- Run build_error_table.ts to generate 241 test cases\n- Verify all cargo tests pass\n\nPlan document: claude-notes/plans/2025-11-20-q-2-28-escaped-shortcode-linebreak.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T16:06:53.436565Z","updated_at":"2025-11-20T16:10:30.541919Z","closed_at":"2025-11-20T16:10:30.541919Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-366","title":"Q-2-28 Phase 2: Automatic Fix (qmd-syntax-helper rule)","description":"Implement qmd-syntax-helper conversion rule to automatically fix Q-2-28 errors\n\nTasks:\n- Create crates/qmd-syntax-helper/src/conversions/q_2_28.rs\n- Implement violation detection from diagnostics\n- Implement fix logic (remove line breaks before >}}})\n- Register in mod.rs\n- Add tests for conversion rule\n- Test end-to-end\n\nDepends on: k-365 (Phase 1 must complete first)\nPlan document: claude-notes/plans/2025-11-20-q-2-28-escaped-shortcode-linebreak.md","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-20T16:07:03.809077Z","updated_at":"2025-11-20T16:28:28.684132Z","closed_at":"2025-11-20T16:28:28.684132Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-366","depends_on_id":"k-365","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-367","title":"Add error diagnostic for indented footnote content","description":"Pattern found in lino-galiana corpus:\n\nUsers are writing footnotes with indented content (Pandoc syntax):\n\n```markdown\nSome text[^ref].\n\n[^ref]:\n Indented content here\n with multiple lines\n```\n\nThis is **not supported** in quarto-markdown (we don't support pure-indentation blocks).\n\nThe parser currently emits generic 'Parse error: unexpected character or token here'.\n\n**Action**: Add specific error code (e.g., Q-2-XX) that:\n1. Detects footnote definitions followed by indented content\n2. Explains that indented footnotes are not supported\n3. Shows the correct alternative syntax (if any exists in qmd)\n\n**Files affected in lino-galiana corpus**:\n- getting-started/intro/_pourquoi_python_data.qmd (4 errors)\n- getting-started/intro/_intro.qmd\n- NLP/01_intro/exercise2.qmd\n- Others (5+ files total)\n\n**Impact**: Would fix ~5+ files in validation corpus\n\nSee: claude-notes/investigations/2025-11-20-lino-galiana-uncoded-errors.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T18:58:59.089641Z","updated_at":"2025-11-20T19:59:11.904645Z","closed_at":"2025-11-20T19:59:11.904645Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-368","title":"Fix parser handling of multi-byte emoji characters","description":"The tree-sitter grammar fails to parse multi-byte emoji characters (particularly numbered emojis like 1️⃣, 2️⃣, 3️⃣).\n\n**Minimal reproduction**:\n```markdown\n::: {.content-visible when-profile=\"fr\"}\n1️⃣ Trouver le tableau\n:::\n```\n\n**Error**: 'Parse error: unexpected character or token here' at the emoji position\n\n**Technical details**:\n- Emoji like 1️⃣ is a multi-byte UTF-8 sequence:\n - Digit '1' (U+0031): `31`\n - Variation Selector-16 (U+FE0F): `efb88f`\n - Combining Enclosing Keycap (U+20E3): `e283a3`\n- Simplified emoji test cases parse correctly\n- Error only occurs in real corpus files with complex context\n- Likely issue with tree-sitter grammar's UTF-8 handling in certain states\n\n**Files affected in lino-galiana corpus**:\n- 04_webscraping/_exo1_solution.qmd (23 errors)\n- 04_webscraping/_exo2b_suite.qmd (2 errors)\n- git/exogit.qmd (4 errors)\n\n**Impact**: ~29+ errors across 3+ files\n\n**Priority**: High - this is the highest impact uncoded error pattern\n\nSee: claude-notes/investigations/2025-11-20-lino-galiana-uncoded-errors.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-20T18:59:17.190448Z","updated_at":"2025-11-20T19:25:44.888949Z","closed_at":"2025-11-20T19:25:44.888949Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-369","title":"Add error diagnostic for inline code execution in image URLs","description":"Pattern found in lino-galiana corpus:\n\nUsers are attempting to use inline code execution inside image URLs:\n\n```markdown\n![](\\`{python} url_image\\`)\n```\n\nThis syntax is **not valid** in Quarto markdown. The parser currently emits generic 'Parse error: unexpected character or token here'.\n\n**Action**: Add specific error code (e.g., Q-2-XX) that:\n1. Detects backtick-based inline code execution attempts inside image URLs\n2. Explains this syntax is not allowed\n3. Suggests alternatives:\n - Use OJS: `![]({url_image})`\n - Use output block to generate markdown\n - Compute URL in earlier chunk and use variable\n\n**Files affected in lino-galiana corpus**:\n- manipulation/04_api/_exo3_solution.qmd\n\n**Impact**: 1 file, but likely a common user error pattern\n\n**Priority**: Medium - easy win (just add error code), clear user benefit\n\nSee: claude-notes/investigations/2025-11-20-lino-galiana-uncoded-errors.md","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-20T18:59:31.788492Z","updated_at":"2025-11-20T20:52:07.524457Z","closed_at":"2025-11-20T20:52:07.524457Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-37","title":"Implement TypeScript source-map-bridge module in quarto-cli","description":"Create src/core/lib/source-map-bridge.ts in quarto-cli. Implement functions to convert Rust SourceInfo JSON to TypeScript MappedString. Handle all SourceMapping variants (Original, Substring, Concat, Transformed). Include helper to resolve SourceContext FileId to file content.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-19T00:24:43.515818Z","updated_at":"2025-11-22T17:48:04.808557Z","closed_at":"2025-11-22T17:48:04.808557Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-37","depends_on_id":"k-34","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-37","depends_on_id":"k-36","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-370","title":"Add error code for spaces in link targets","description":"Found in Tail-Winds corpus validation: 3 files with spaces in image filenames cause parse errors.\n\nExample files:\n- frm/pot_survey.qmd: ![](images/CFRM schema.png)\n- frm/rec_survey.qmd: ![](images/RFRM schema.png) \n- news/index.qmd: ![](images/FW detection 1 panel 30Sept2023.png)\n\nError: Parse error - unexpected character or token (no code)\nLocation: At the space character in the link target\n\nProposed fix strategy: \n- Add error code (e.g., Q-2-33)\n- Error message: 'Link targets cannot contain spaces. Replace spaces with %20'\n- Hint: Show the corrected link with %20 encoding\n\nExample:\nBad: ![](images/CFRM schema.png)\nGood: ![](images/CFRM%20schema.png)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-21T16:50:12.507563Z","updated_at":"2025-11-21T16:52:18.540504Z","closed_at":"2025-11-21T16:52:18.540504Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-371","title":"Add error code for unquoted shortcode parameter starting with digit","description":"Found in Tail-Winds corpus validation: shortcode parameter without quotes that starts with a number followed by non-numeric character.\n\nExample file:\n- team/index.qmd: {{< fa envelope size=1x >}}\n\nError: Parse error - unexpected character or token (no code)\nLocation: At the parameter value '1x' (digit followed by letter, unquoted)\n\nMinimal reproduction: {{< a k=1b >}}\n\nProposed fix strategy:\n- Add error code (e.g., Q-2-34)\n- Error message: 'Shortcode parameter values starting with digits must be quoted'\n- Hint: 'Use quotes around the parameter value: k=\"1b\"'\n\nExample:\nBad: {{< fa envelope size=1x >}}\nGood: {{< fa envelope size=\"1x\" >}}","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-21T16:50:24.468390Z","updated_at":"2025-11-21T16:52:19.237997Z","closed_at":"2025-11-21T16:52:19.237997Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-372","title":"Fix Math+Attr source tracking in postprocess.rs","description":"Implement proper source tracking for Math+Attr pattern in postprocess.rs:667. Currently uses SourceInfo::default() when wrapping Math with following Attr in a Span.\n\n**Pattern**: $math$ {.attr} → Span wrapping Math\n\n**Solution**: Create AttrSourceInfo::combine_all() helper to extract overall SourceInfo from attribute pieces, then combine with math.source_info.\n\n**Plan**: claude-notes/plans/2025-11-21-math-attr-source-tracking.md\n\n**Changes**:\n1. Add combine_all() method to AttrSourceInfo in attr.rs\n2. Update postprocess.rs:667 to use math.source_info.combine(attr.combine_all())\n3. Write comprehensive tests\n\n**Estimate**: 3-4 hours\n\n**Benefits**:\n- Complete source tracking for Math+Attr constructs\n- Better error messages\n- No AST structure changes needed","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-21T21:47:32.899369Z","updated_at":"2025-11-21T22:17:43.181211Z","closed_at":"2025-11-21T22:17:43.181211Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-372","depends_on_id":"k-373","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-373","title":"CRITICAL: Math+Attr feature completely broken - attributes silently dropped","description":"The Math+Attr desugaring feature documented in docs/syntax/desugaring/math-attributes.qmd is completely non-functional. Attributes following math expressions (e.g., $x$ {.eq}) are being silently dropped.\n\n**Root Cause**: paragraph.rs only handles IntermediateInline and IntermediateInlines, silently dropping IntermediateAttr.\n\n**Impact**: \n- Documented feature doesn't work\n- No error messages (silent failure)\n- Affects both inline and display math\n\n**Example**:\nInput: $E = mc^2$ {#eq-einstein}\nExpected: Span wrapping Math with id\nActual: Just Math, attribute disappears\n\n**Fix**: Add IntermediateAttr case to paragraph.rs (3 line change)\n\n**Plan**: claude-notes/plans/2025-11-21-math-attr-bug-fix.md\n\n**Blocks**: k-372 (source tracking improvement depends on this working)\n\n**Estimate**: 4-4.5 hours (mostly tests)","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-21T21:54:46.725587Z","updated_at":"2025-11-21T22:08:41.290257Z","closed_at":"2025-11-21T22:08:41.290257Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-374","title":"Fix panic!() crashes in native writer","description":"The native writer has 3 panic!() statements that crash the program instead of emitting helpful DiagnosticMessage errors:\n\n1. Line 667: Unsupported block types (BlockMetadata, CaptionBlock)\n2. Line 355: Unsupported inline types (Shortcode, Insert, Delete, Highlight, EditComment, Attr, NoteReference)\n3. Line 94: ColWidth::Percentage (valid Pandoc type!)\n\nThese should emit errors with codes Q-3-20 through Q-3-36.\n\nSee: claude-notes/plans/2025-11-21-k-327-all-writer-panics.md\n\nFiles:\n- crates/quarto-markdown-pandoc/src/writers/native.rs\n\nEstimate: 4-6 hours","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-22T00:21:37.217509Z","updated_at":"2025-11-22T00:25:25.520456Z","closed_at":"2025-11-22T00:25:25.520456Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-374","depends_on_id":"k-327","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-375","title":"Fix panic!() crashes in JSON writer","description":"The JSON writer has panic!() statements for extension types that should emit defensive errors instead:\n\n1. Line 542: Editorial marks (Insert, Delete, Highlight, EditComment) - defensive check since they're desugared\n2. Line 993: CaptionBlock - defensive (should be processed in postprocess but might reach via filters)\n3. Line 1070: Non-MetaMap metadata - defensive\n\nReplace with proper DiagnosticMessage errors.\n\nSee: claude-notes/plans/2025-11-21-k-327-all-writer-panics.md\n\nFiles:\n- crates/quarto-markdown-pandoc/src/writers/json.rs\n\nEstimate: 2-3 hours","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-22T00:21:38.639455Z","updated_at":"2025-11-23T13:22:18.115493Z","closed_at":"2025-11-23T13:22:19.115493Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-375","depends_on_id":"k-327","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-376","title":"Fix panic!() crashes in QMD writer","description":"The QMD writer has defensive panic!() statements that should emit proper errors:\n\n1. Line 1284: CaptionBlock - defensive (should be processed in postprocess but might reach via filters)\n2. Line 272: Non-MetaMap metadata - defensive\n\nReplace with proper DiagnosticMessage errors.\n\nSee: claude-notes/plans/2025-11-21-k-327-all-writer-panics.md\n\nFiles:\n- crates/quarto-markdown-pandoc/src/writers/qmd.rs\n\nEstimate: 1-2 hours","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-22T00:21:39.731796Z","updated_at":"2025-11-22T01:24:47.758567Z","closed_at":"2025-11-22T01:24:47.758567Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-376","depends_on_id":"k-327","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-377","title":"Fix panic!() crashes in ANSI writer","description":"The ANSI writer has 10 panic!() statements for unimplemented features. Since ANSI writer is user-facing, these should emit proper errors:\n\n1. LineBlock, CodeBlock, Table, Figure (standard Pandoc types)\n2. BlockMetadata, NoteDefinitionPara, NoteDefinitionFencedBlock, CaptionBlock (extension types)\n\nOptions:\n- Implement the missing features\n- Or emit clear 'not supported in ANSI format' errors\n\nSee: claude-notes/plans/2025-11-21-k-327-all-writer-panics.md\n\nFiles:\n- crates/quarto-markdown-pandoc/src/writers/ansi.rs\n\nEstimate: 3-5 hours (depends on implement vs error approach)","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-11-22T00:21:41.226518Z","updated_at":"2025-11-22T01:54:03.547745Z","closed_at":"2025-11-22T01:54:03.547745Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-377","depends_on_id":"k-327","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-378","title":"Add diagnostic error reporting to JSON writer","description":"The JSON writer currently uses panic!() and eprintln!() for defensive error cases. It needs proper diagnostic reporting like the native writer.\n\nCurrent issues:\n- Editorial marks (Insert, Delete, Highlight, EditComment) use eprintln!\n- Shortcode, NoteReference, Attr use eprintln!\n- CaptionBlock uses eprintln!\n- Non-MetaMap metadata uses eprintln!\n\nThese should emit proper DiagnosticMessage errors that work with --json-errors.\n\nRefactoring needed:\n1. Change write() signature from io::Result<()> to Result<(), Vec>\n2. Thread errors Vec through write_pandoc, write_block, write_inline, etc.\n3. Replace eprintln! with errors.push(DiagnosticMessageBuilder...)\n4. Add error codes to catalog (or reuse Q-3-20 through Q-3-36 from native writer)\n\nDependencies: k-375 (blocked until this is done)\nEstimate: 3-4 hours","status":"closed","priority":0,"issue_type":"task","created_at":"2025-11-22T00:29:53.651635Z","updated_at":"2025-11-22T00:39:09.781466Z","closed_at":"2025-11-22T00:39:09.781466Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-378","depends_on_id":"k-375","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-379","title":"Port Pandoc template functionality to quarto-markdown-pandoc","description":"Replicate Pandoc's complete template system in Rust, including template syntax parsing, variable interpolation, control flow (if/else/for), partials, pipes, and integration with all writers. This will enable standalone document generation with customizable headers, footers, and metadata handling.","notes":"Plans:\n- Initial analysis: claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md\n- Evaluator implementation: claude-notes/plans/pandoc-template-port/2025-11-24-evaluator-implementation-plan.md","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-23T22:46:21.904560Z","updated_at":"2025-11-25T19:42:04.043711Z","closed_at":"2025-11-25T19:42:04.043711Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-38","title":"Add unit tests for TypeScript source-map-bridge","description":"Create comprehensive unit tests in quarto-cli for source-map-bridge module. Test conversion of all SourceMapping variants. Test offset resolution through nested Substring chains. Test edge cases (empty strings, out-of-bounds, etc). Verify MappedString.map() behavior matches expectations.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-19T00:24:50.328408Z","updated_at":"2025-11-22T17:48:05.641805Z","closed_at":"2025-11-22T17:48:05.641805Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-38","depends_on_id":"k-34","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-38","depends_on_id":"k-37","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-380","title":"Extract quarto-parse-errors shared crate from qmd error system","description":"Extract the error generation infrastructure from quarto-markdown-pandoc into a shared quarto-parse-errors crate that can be reused by both qmd and template parsers.\n\nThis implements Phase 0.1 from the template port plan.\n\nDeliverables:\n- New quarto-parse-errors crate with generic error types\n- Generic TreeSitterLogObserver (grammar-agnostic)\n- Generic error generation functions\n- Shared build_error_table.ts script (parameterized)\n- include_error_table! macro for compile-time embedding\n- Comprehensive tests\n\nKey types to extract and generalize:\n- ErrorTable, ErrorTableEntry\n- ErrorInfo, ErrorCapture, ErrorNote\n- TreeSitterLogObserver, TreeSitterParseLog\n- ConsumedToken, ProcessMessage\n- produce_diagnostic_messages() function\n\nDependencies:\n- quarto-error-reporting (DiagnosticMessage)\n- quarto-source-map (SourceInfo)\n- tree-sitter (logging)\n- serde, serde_json\n\nReference: claude-notes/plans/pandoc-template-port/2025-11-23-tree-sitter-parsing-subplan.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T14:00:16.271220Z","updated_at":"2025-11-24T21:49:58.895960Z","closed_at":"2025-11-24T21:49:58.895960Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-380","depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-381","title":"Refactor qmd writer to use QmdWriterContext for emphasis delimiter tracking","description":"Refactor the qmd writer to introduce a QmdWriterContext struct that wraps the errors vector and adds an emphasis_stack field. This will allow us to track parent emphasis delimiters and avoid generating ambiguous *** sequences that quarto-markdown doesn't support. See claude-notes/plans/2025-11-24-qmd-writer-context-refactoring.md for detailed analysis and implementation plan.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T17:19:47.394864Z","updated_at":"2025-11-24T17:54:04.183731Z","closed_at":"2025-11-24T17:54:04.183731Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-382","title":"Create quarto-doctemplate crate structure","description":"Create the basic crate structure for quarto-doctemplate:\n\n- Cargo.toml with dependencies (tree-sitter-doctemplate, quarto-parse-errors, quarto-error-reporting, quarto-source-map)\n- src/lib.rs with module declarations\n- src/ast.rs placeholder\n- src/parser.rs placeholder\n- src/context.rs placeholder\n- src/evaluator.rs placeholder\n- src/error.rs placeholder\n\nThis is the foundation for the template engine implementation.\n\nReference: Phase 1, Task 1 from claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T21:48:06.944414Z","updated_at":"2025-11-24T21:54:34.349376Z","closed_at":"2025-11-24T21:54:34.349376Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-382","depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-383","title":"Define template AST types","description":"Define the Rust AST types for parsed templates in src/ast.rs:\n\n- TemplateNode enum with variants:\n - Literal(String)\n - Variable(VariableRef)\n - Conditional { branches, else_branch }\n - ForLoop { var, separator, body }\n - Partial { name, var, separator, pipes }\n - Nesting(children)\n - BreakableSpace(children)\n - Comment(String)\n\n- VariableRef struct with:\n - path: Vec (e.g., [\"employee\", \"salary\"])\n - pipes: Vec\n\n- Pipe struct with:\n - name: String\n - args: Vec\n\n- PipeArg enum for pipe parameters\n\nReference: Phase 1, Task 2 from claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T21:48:15.693141Z","updated_at":"2025-11-24T22:05:32.336525Z","closed_at":"2025-11-24T22:05:32.336525Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-383","depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-383","depends_on_id":"k-382","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-384","title":"Define TemplateValue and TemplateContext types","description":"Define the value and context types in src/context.rs:\n\nTemplateValue enum (NO Pandoc dependencies!):\n- String(String)\n- Bool(bool)\n- List(Vec)\n- Map(HashMap)\n- Null\n\nTemplateContext struct:\n- variables: HashMap\n- parent: Option> for nested scopes (for loops)\n\nKey methods:\n- TemplateValue::is_truthy() - truthiness rules for conditionals\n- TemplateValue::get_path() - nested field access (e.g., \"employee.salary\")\n- TemplateContext::get() - variable lookup with parent chain\n- TemplateContext::with_scope() - create child scope for loops\n\nNote: Numbers are represented as Strings (formatted when converted from JSON).\n\nReference: Phase 1, Task 3 from claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T21:48:25.696993Z","updated_at":"2025-11-24T22:05:33.710566Z","closed_at":"2025-11-24T22:05:33.710566Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-384","depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-384","depends_on_id":"k-382","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-385","title":"Implement tree-sitter CST to AST conversion","description":"Implement the conversion from tree-sitter parse tree to template AST in src/parser.rs.\n\nModel the implementation on quarto-markdown-pandoc's bottom-up traversal pattern:\n- Use tree-sitter cursor to traverse the parse tree\n- Convert each node type to corresponding AST node\n- Handle nested structures (conditionals, loops, partials)\n- Preserve source locations for error reporting\n\nKey conversions:\n- source_file -> Vec\n- text -> Literal\n- interpolation -> Variable\n- conditional -> Conditional\n- forloop -> ForLoop\n- partial -> Partial\n- nesting -> Nesting\n- breakable_block -> BreakableSpace\n- comment -> Comment (or skip)\n- escaped_dollar -> Literal(\"$\")\n\nReference: Phase 1, Tasks 4-5 from claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T21:48:33.191452Z","updated_at":"2025-11-24T22:56:27.881729Z","closed_at":"2025-11-24T22:56:27.881729Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-385","depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-385","depends_on_id":"k-383","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-386","title":"Integrate error generation with quarto-parse-errors","description":"Integrate the template parser with quarto-parse-errors for beautiful error messages.\n\nTasks:\n1. Create template error corpus in resources/error-corpus/\n - T-*.json files for template-specific errors\n - Common errors: unclosed delimiters, invalid variable names, malformed pipes\n2. Create build script to generate error table\n3. Use TreeSitterLogObserver during parsing\n4. Call produce_diagnostic_messages() on parse errors\n5. Return DiagnosticMessage errors with source locations\n\nThis follows the same pattern as qmd error generation but with template-specific error messages.\n\nReference: Phase 1, Task 6 from claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md","notes":"Implementation plan: claude-notes/plans/2025-01-25-k-386-template-error-corpus.md\n\nPhase 1 scope (this ticket):\n- Add Q-10-* error codes to error_catalog.json (Q-10-1 through Q-10-7)\n- Update DiagnosticCollector and EvalContext to support error codes\n- Update evaluation errors to use Q-10-2 (undefined var), Q-10-5 (unresolved partial), etc.\n- Generic Q-10-1 parse error with source location\n\nFuture work (separate tickets):\n- Full TreeSitterLogObserver integration\n- Error corpus JSON files for tree-sitter state mappings","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-24T21:48:42.779009Z","updated_at":"2025-11-25T23:02:12.497544Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-386","depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-386","depends_on_id":"k-385","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-387","title":"Implement basic template evaluator","description":"Implement the basic template evaluation engine in src/evaluator.rs.\n\nInitial scope (no pipes, no partials):\n- Literal nodes -> output as-is\n- Variable interpolation -> resolve from context, render value\n- Conditionals -> evaluate truthiness, render appropriate branch\n- For loops -> iterate over arrays/maps, render body for each\n- Nesting -> track indentation, apply to multi-line content\n- Breakable spaces -> mark spaces as breakable (for Doc output)\n\nKey functions:\n- evaluate(template: &[TemplateNode], context: &TemplateContext) -> Result\n- resolve_variable(var: &VariableRef, context: &TemplateContext) -> TemplateValue\n- render_value(value: &TemplateValue) -> String\n\nFor loop semantics:\n- Array: iterate over elements, bind to variable name and 'it'\n- Map: single iteration with map as context\n- Other: single iteration with value\n\nReference: Phase 1, Task 7 from claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md","notes":"Implementation plan: claude-notes/plans/pandoc-template-port/2025-11-24-evaluator-implementation-plan.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T21:48:54.292312Z","updated_at":"2025-11-25T15:38:14.035683Z","closed_at":"2025-11-25T15:38:14.035683Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-387","depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-387","depends_on_id":"k-384","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-387","depends_on_id":"k-385","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-388","title":"Write parser and evaluator tests","description":"Write comprehensive tests for the template parser and evaluator.\n\nParser tests:\n- Test each syntax element parses correctly\n- Test error messages for malformed templates\n- Test edge cases (empty templates, nested structures)\n- Use test templates from crates/tree-sitter-doctemplate/test-templates/\n\nEvaluator tests (using simple contexts, NO Pandoc):\n- Variable interpolation (simple, nested paths)\n- Truthiness evaluation for conditionals\n- For loop iteration (arrays, maps, single values)\n- Separator handling in loops\n- Nesting/indentation behavior\n- Breakable space handling\n\nIntegration tests:\n- Parse and evaluate complete templates\n- Compare output against expected results\n- Test the test templates with pandoc and verify matching output\n\nReference: Phase 1, Tasks 8-9 from claude-notes/plans/pandoc-template-port/2025-11-23-initial-analysis.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T21:49:03.952777Z","updated_at":"2025-11-25T19:41:49.942200Z","closed_at":"2025-11-25T19:41:49.942200Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-388","depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-388","depends_on_id":"k-387","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-389","title":"Implement variable interpolation in evaluator","description":"Implement variable resolution and rendering in the template evaluator.\n\nTasks:\n1. Resolve variable path from context (e.g., 'employee.salary')\n2. Handle the 'it' anaphoric keyword for loop iteration\n3. Render values to strings according to Pandoc rules:\n - String: as-is\n - Bool true: 'true', Bool false: ''\n - List: concatenate rendered elements\n - Map: 'true'\n - Null: ''\n4. Handle literal separator syntax $var[, ]$ for array iteration\n\nNote: Pipes are out of scope for this issue - will be added in a separate issue.","notes":"See implementation plan: claude-notes/plans/pandoc-template-port/2025-11-24-evaluator-implementation-plan.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T23:15:18.832Z","updated_at":"2025-11-25T15:26:36.889681Z","closed_at":"2025-11-25T15:26:36.889681Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-389","depends_on_id":"k-387","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-39","title":"Create compatibility module with conversion helpers","description":"Create src/pandoc/source_map_compat.rs with helper functions: node_to_source_info(node, file_id) and node_to_source_info_with_context(node, ctx). These provide a bridge from tree-sitter Node to quarto-source-map::SourceInfo.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T00:28:29.433992Z","updated_at":"2025-10-19T00:31:09.547380Z","closed_at":"2025-10-19T00:31:09.547380Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-39","depends_on_id":"k-27","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-390","title":"Implement conditional evaluation in evaluator","description":"Implement conditional evaluation ($if(var)$...$else$...$endif$) in the template evaluator.\n\nTasks:\n1. Evaluate truthiness of condition variable using existing is_truthy() method\n2. Render the appropriate branch (then or else)\n3. Support elseif chains by iterating through branches\n4. Handle nested conditionals correctly\n\nTruthiness rules (already implemented in TemplateValue::is_truthy):\n- Any non-empty map is truthy\n- Any array containing at least one truthy value is truthy\n- Any non-empty string is truthy (even 'false')\n- Boolean true is truthy\n- Everything else is falsy","notes":"See implementation plan: claude-notes/plans/pandoc-template-port/2025-11-24-evaluator-implementation-plan.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T23:15:27.488553Z","updated_at":"2025-11-25T15:26:38.203878Z","closed_at":"2025-11-25T15:26:38.203878Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-390","depends_on_id":"k-387","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-391","title":"Implement for loop evaluation in evaluator","description":"Implement for loop evaluation ($for(var)$...$sep$...$endfor$) in the template evaluator.\n\nTasks:\n1. Resolve the iteration variable from context\n2. Handle different iteration modes:\n - Array: iterate over elements, bind to variable name AND 'it'\n - Map: single iteration with map as context\n - Other: single iteration with value\n3. Create child context for each iteration with proper variable bindings\n4. Render loop body for each iteration\n5. Insert separator between iterations (not after last)\n6. Handle nested loops correctly via context scoping\n\nPer Pandoc semantics:\n- Inside loop, can use either $variable$ or $it$ to refer to current element\n- For nested access: $variable.field$ or $it.field$","notes":"See implementation plan: claude-notes/plans/pandoc-template-port/2025-11-24-evaluator-implementation-plan.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-24T23:15:37.411702Z","updated_at":"2025-11-25T15:26:39.100972Z","closed_at":"2025-11-25T15:26:39.100972Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-391","depends_on_id":"k-387","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-392","title":"Implement nesting/indentation in evaluator","description":"Implement nesting directive ($^$) for multi-line indentation in the template evaluator.\n\nThe nesting directive ensures subsequent lines are indented to line up with the first line.\n\nExample:\n $item.number$ $^$$item.description$\nproduces:\n 00123 A fine bottle of 18-year old\n Oban whiskey.\n\nTasks:\n1. Track current column position during rendering\n2. When encountering $^$, record current column as indentation level\n3. For content after $^$, indent subsequent lines to this level\n4. Handle nested nesting directives\n\nDesign consideration: The Haskell implementation uses Doc type with DL.nest for this. Our initial implementation can use a simpler approach by:\n- Tracking indentation level as state\n- Post-processing multi-line strings to add indentation\n\nNote: Full fidelity with Pandoc's Doc-based approach may require future refactoring.","notes":"See implementation plan: claude-notes/plans/pandoc-template-port/2025-11-24-evaluator-implementation-plan.md","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-24T23:15:49.733066Z","updated_at":"2025-12-02T16:17:19.603977Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-392","depends_on_id":"k-387","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-392","depends_on_id":"k-395","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-393","title":"Implement breakable spaces in evaluator","description":"Implement breakable space blocks ($~$...$~$) in the template evaluator.\n\nPer Pandoc documentation:\n'When rendering to a Doc, a distinction can be made between breakable and unbreakable spaces. Normally, spaces in the template itself are not breakable, but they can be made breakable in part of the template by using the ~ keyword.'\n\n'The ~ keyword has no effect when rendering to Text or String.'\n\nTasks:\n1. For String output (current approach): Simply render content as-is (spaces are not breakable)\n2. If/when we implement Doc output: Mark spaces as breakable using DL.space equivalent\n\nDesign note: This feature is only meaningful when templates produce Doc output that can be reflowed. For simple String rendering, this is a no-op that just passes through content.\n\nPriority: Lower than other evaluator tasks since it's effectively a no-op for String output.","notes":"See implementation plan: claude-notes/plans/pandoc-template-port/2025-11-24-evaluator-implementation-plan.md","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-24T23:16:00.824294Z","updated_at":"2025-11-25T15:26:40.878582Z","closed_at":"2025-11-25T15:26:40.878582Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-393","depends_on_id":"k-387","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-394","title":"Implement template partials","description":"Implement partial (subtemplate) loading and evaluation for the template system.\n\nPartials are subtemplates stored in different files that can be included via:\n- Bare partial: $boilerplate()$\n- Applied to variable: $date:fancy()$\n- With separator: $articles:bibentry()[; ]$\n- With pipes: $employee:name()/uppercase$\n\nKey implementation requirements:\n1. PartialResolver trait for abstracting file loading\n2. Compile-time partial resolution (following Pandoc/doctemplates)\n3. Path resolution (inherit template extension, same directory)\n4. Recursion protection (max depth 50, return '(loop)')\n5. Final newline stripping from partials\n6. Array iteration for applied partials\n\nReference: jgm/doctemplates (Haskell implementation)","notes":"Implementation plan: claude-notes/plans/pandoc-template-port/2025-11-25-partials-implementation-plan.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T15:33:38.810866Z","updated_at":"2025-11-25T16:38:24.233547Z","closed_at":"2025-11-25T16:38:24.233547Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-394","depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-394","depends_on_id":"k-387","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-394","depends_on_id":"k-396","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-395","title":"Advanced template evaluator features","description":"Implement advanced template evaluator features that go beyond the basic evaluator.\n\nThis includes features that require more sophisticated handling:\n- Nesting/indentation tracking (Doc-based approach)\n- Pipes (value transformations)\n- Other advanced features as identified\n\nThese are lower priority than the core evaluator and partials.","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-25T15:38:02.166977Z","updated_at":"2025-12-02T16:17:37.633828Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-396","title":"Add diagnostic context to template evaluator","description":"Thread an EvalContext through the template evaluator to support:\n\n1. **Warnings**: Non-fatal issues (e.g., undefined variables)\n2. **Multiple diagnostics**: Accumulate multiple errors/warnings before failing\n3. **Rich source locations**: File/line/column for IDE integration\n4. **Structured messages**: Tidyverse-style errors (problem, details, hints)\n\nKey changes:\n- Create EvalContext struct (variables + DiagnosticCollector + state)\n- Update all evaluate_* functions to take &mut EvalContext\n- Add render_with_diagnostics() API\n- Use Q-9-* error codes for template subsystem\n\nThis should be completed before implementing partials (k-394) since partials need good error reporting for:\n- Partial not found (Q-9-001)\n- Partial parse errors (Q-9-002)\n- Recursion limit exceeded (Q-9-003)\n\nPattern reference: quarto-markdown-pandoc DiagnosticCollector","notes":"Implementation plan: claude-notes/plans/pandoc-template-port/2025-11-25-evaluator-diagnostics-plan.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T15:51:10.250069Z","updated_at":"2025-11-25T16:03:30.508450Z","closed_at":"2025-11-25T16:03:30.508450Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-396","depends_on_id":"k-379","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-397","title":"Integrate HTML templates into pico-quarto-render","description":"Extend pico-quarto-render to produce complete HTML documents using quarto-doctemplate and embedded templates. Plan: claude-notes/plans/2025-11-25-pico-quarto-render-template-integration.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-25T17:22:11.123347Z","updated_at":"2025-11-25T19:11:51.200536Z","closed_at":"2025-11-25T19:11:51.200536Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-398","title":"Add quarto-doctemplate and include_dir dependencies to pico-quarto-render","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T17:22:21.086089Z","updated_at":"2025-11-25T19:11:51.074435Z","closed_at":"2025-11-25T19:11:51.074435Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-398","depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-399","title":"Implement EmbeddedResolver for loading templates from include_dir","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T17:22:22.615943Z","updated_at":"2025-11-25T19:11:51.094042Z","closed_at":"2025-11-25T19:11:51.094042Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-399","depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-3ge6","title":"Improve coverage: quarto-core/src/format.rs","description":"Session baseline: 73.45% line coverage. File at 58.65%. Focus on FormatIdentifier and Format methods.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T16:34:52.978749Z","updated_at":"2026-01-02T16:37:59.220906Z","closed_at":"2026-01-02T16:37:59.220906Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-3ge6","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-3n95","title":"Investigate feasibility of 'kyoto' as project codename","description":"The Rust port of Quarto needs a distinct name to avoid confusion with Pandoc, especially since the port will still use Pandoc in some codepaths. Consider 'kyoto' and 'pampa' as codenames and investigate their feasibility from trademark, namespace, and discoverability perspectives.\n\nPlan document: claude-notes/plans/2025-12-06-project-naming.md","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-06T19:25:25.267234Z","updated_at":"2025-12-06T20:11:18.440069Z","closed_at":"2025-12-06T20:11:18.440069Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-4","title":"Phase C: Switch to DiagnosticCollector","description":"Replace TextErrorCollector and JsonErrorCollector with DiagnosticCollector in readers.\n\nFiles to modify:\n- crates/quarto-markdown-pandoc/src/readers/qmd.rs\n\nMust verify all tests pass with no regressions.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T19:41:45.466234Z","updated_at":"2025-10-18T21:20:01.983787Z","closed_at":"2025-10-18T21:20:01.983787Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-4","depends_on_id":"k-1","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-4","depends_on_id":"k-3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-40","title":"Add source_info_qsm fields alongside existing source_info","description":"Pick 2-3 representative AST structs (e.g., HorizontalRule, Str). Add 'source_info_qsm: Option' field alongside existing source_info. Populate both during parsing. Verify tests pass. This allows gradual migration.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T00:28:36.642124Z","updated_at":"2025-10-19T00:38:50.085409Z","closed_at":"2025-10-19T00:38:50.085409Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-40","depends_on_id":"k-27","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-40","depends_on_id":"k-39","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-400","title":"Expose write_inlines and write_blocks as public API in html.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T17:22:23.959077Z","updated_at":"2025-11-25T19:11:51.113212Z","closed_at":"2025-11-25T19:11:51.113212Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-400","depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-401","title":"Implement MetaValueWithSourceInfo to TemplateValue conversion with HTML and plain-text paths","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T17:22:25.969462Z","updated_at":"2025-11-25T19:11:51.130469Z","closed_at":"2025-11-25T19:11:51.130469Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-401","depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-402","title":"Implement build_template_context with derived values","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T17:22:27.077722Z","updated_at":"2025-11-25T19:11:51.147737Z","closed_at":"2025-11-25T19:11:51.147737Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-402","depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-403","title":"Update pico-quarto-render main to use template rendering","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T17:22:28.323671Z","updated_at":"2025-11-25T19:11:51.165301Z","closed_at":"2025-11-25T19:11:51.165301Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-403","depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-404","title":"Add tests for pico-quarto-render template output","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-25T17:22:30.145875Z","updated_at":"2025-11-25T19:15:37.665909Z","closed_at":"2025-11-25T19:15:37.665909Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-404","depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-405","title":"Add plain-text writer module to quarto-markdown-pandoc","description":"Create writers/plaintext.rs that renders Pandoc AST (Inlines, Blocks) to pure plain text without HTML escaping. This is needed for deriving template values like pagetitle, author-meta, date-meta from MetaInlines. Unlike write_inlines_as_text in html.rs, this should NOT escape HTML entities. Plan: claude-notes/analysis/2025-11-25-plain-text-writer-design.md","design":"## RawInline/RawBlock\n- Echo contents if format is 'plaintext', otherwise drop with warning\n\n## PlainTextWriterContext\n- Thread error diagnostics through all write functions\n- Convenience functions return (String, Vec)\n\n## Inlines - Strip structure, keep content:\n- Str, Space, SoftBreak, LineBreak: output directly\n- Emph, Strong, Underline, Strikeout, Superscript, Subscript, SmallCaps, Span: recurse (no markers)\n- Quoted: use actual quote characters\n- Code: mimic markdown (backticks)\n- Math: output raw TeX\n- Link, Image: recurse into content only (no \\![], [])\n- Cite: recurse into content\n- Insert, Delete, Highlight, EditComment: recurse\n- Note: skip (no warning)\n- RawInline: echo if 'plaintext', else drop with warning\n- Shortcode, NoteReference, Attr: drop with warning\n\n## Blocks - Mimic markdown writer:\n- Plain, Paragraph, Header: write inlines\n- CodeBlock: fenced with backticks\n- BlockQuote: > prefix\n- LineBlock: | prefix\n- OrderedList: 1. 2. 3.\n- BulletList: - prefix\n- HorizontalRule: ---\n- Div, Figure: write contents only\n- RawBlock: echo if 'plaintext', else drop with warning\n\n## Blocks - Drop with warning:\n- DefinitionList, Table: complex structure\n- BlockMetadata, NoteDefinitionPara, NoteDefinitionFencedBlock, CaptionBlock: Quarto extensions","notes":"Design decisions:\n1. RawInline/RawBlock: echo contents if format is 'plaintext', otherwise drop with warning\n2. Add PlainTextWriterContext for threading error diagnostics\n3. Issue diagnostic warnings on dropped nodes:\n - RawInline/RawBlock with mismatched formats (not 'plaintext')\n - Unsupported Quarto extensions: Shortcode, NoteReference, Attr (inlines), BlockMetadata, NoteDefinitionPara, NoteDefinitionFencedBlock, CaptionBlock (blocks)\n4. No HTML escaping (unlike write_inlines_as_text in html.rs)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-25T17:47:43.028154Z","updated_at":"2025-11-25T18:08:35.769022Z","closed_at":"2025-11-25T18:08:35.769022Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-405","depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-406","title":"Implement template-based rendering in pico-quarto-render","description":"Implement template rendering pipeline: prepare_template_metadata() to derive pagetitle from title, meta_to_template_value() with format-specific writers, render_with_template() to produce final output. See plan: claude-notes/plans/2025-11-25-pico-quarto-render-template-rendering.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-25T18:24:48.921665Z","updated_at":"2025-11-25T19:11:51.183021Z","closed_at":"2025-11-25T19:11:51.183021Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-406","depends_on_id":"k-397","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-407","title":"Extensible filters for quarto-markdown-pandoc","description":"Implement extensible filter infrastructure allowing third-party filters to transform the Pandoc AST. This epic covers:\n\n1. JSON filters - External processes that read/write JSON AST (Pandoc-compatible protocol)\n2. Lua filters - Embedded Lua interpreter with direct AST access (mlua-based)\n\nThis provides compatibility with Pandoc's filter ecosystem while enabling performant Lua filters.\n\nDesign plans:\n- JSON filters: claude-notes/plans/2025-11-26-json-filters-design.md\n- Lua filters: claude-notes/plans/2025-11-26-lua-filters-design.md","status":"open","priority":2,"issue_type":"epic","created_at":"2025-11-26T15:21:24.129138Z","updated_at":"2025-11-26T15:21:24.129138Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-408","title":"JSON filter support for quarto-markdown-pandoc","description":"Implement JSON filter support following Pandoc's protocol:\n\n**Protocol:**\n- Stdin: Pandoc AST as JSON (using existing JSON writer)\n- Stdout: Modified Pandoc AST as JSON (using existing JSON reader)\n- Args: [target_format, ...]\n- Environment: PANDOC_VERSION, PANDOC_READER_OPTIONS\n\n**Implementation Tasks:**\n1. Add --filter CLI argument to accept filter paths\n2. Create filter execution infrastructure (spawn subprocess, pipe JSON)\n3. Implement interpreter detection for .py, .hs, .pl, .rb, .php, .js, .r files\n4. Add filter discovery (direct path, data dir, PATH)\n5. Support multiple filters with sequential composition\n6. Error handling (filter not found, non-zero exit, JSON parse errors)\n\n**Files to modify:**\n- crates/quarto-markdown-pandoc/src/main.rs (CLI args)\n- crates/quarto-markdown-pandoc/src/filters/ (new module)\n\n**Design plan:** claude-notes/plans/2025-11-26-json-filters-design.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-26T15:21:36.574582Z","updated_at":"2025-12-02T14:11:40.923141Z","closed_at":"2025-12-02T14:11:40.923141Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-408","depends_on_id":"k-407","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-409","title":"Lua filter support for quarto-markdown-pandoc","description":"Implement embedded Lua filter support using mlua:\n\n**Architecture:**\n- Use mlua crate for Rust-Lua integration\n- Expose Pandoc AST types as Lua UserData\n- Support both 'typewise' and 'topdown' traversal modes\n- Provide pandoc.* namespace for element constructors\n\n**Implementation Tasks:**\n1. Add mlua dependency to Cargo.toml\n2. Create Lua marshaling layer (Rust AST <-> Lua)\n - Pushers: Block, Inline, Meta types -> Lua tables/userdata\n - Peekers: Lua values -> Rust AST types\n3. Implement element constructors (Str, Para, Header, etc.)\n4. Create filter execution engine\n - Load filter script\n - Detect filter structure (explicit return vs global functions)\n - Apply traversal (typewise or topdown)\n5. Add --lua-filter CLI argument\n6. Implement return value semantics (nil=unchanged, element=replace, list=splice)\n7. Expose global variables (FORMAT, PANDOC_VERSION, etc.)\n\n**Key Design Decisions:**\n- Start with minimal pandoc.* namespace (constructors only)\n- Defer pandoc.utils, pandoc.text, etc. to later phases\n- Use UserData for complex types vs tables for simple ones\n\n**Files to create/modify:**\n- crates/quarto-markdown-pandoc/Cargo.toml (add mlua)\n- crates/quarto-markdown-pandoc/src/lua/ (new module)\n- crates/quarto-markdown-pandoc/src/main.rs (CLI)\n\n**Design plan:** claude-notes/plans/2025-11-26-lua-filters-design.md","notes":"Analysis and plan documents:\n- mlua implementation analysis: claude-notes/plans/2025-12-02-mlua-analysis.md\n- Filter diagnostics analysis: claude-notes/plans/2025-12-02-filter-diagnostics-analysis.md\n- FilterContext refactoring: claude-notes/plans/2025-12-02-filter-context-refactoring.md\n- Original design: claude-notes/plans/2025-11-26-lua-filters-design.md\n- Lua globals reference: claude-notes/lua-globals-report.md\n\nImplementation phases (all required):\n- k-469: Phase 1 - Core types and infrastructure\n- k-470: Phase 2 - Complete element coverage\n- k-471: Phase 3 - Methods and traversal (includes walk())\n- k-472: Phase 4 - Diagnostics and utilities (includes provenance tracking)\n\nKey decisions (2025-12-02):\n- Pandoc uses userdata (not tables) for AST elements\n- Feature flag: `lua-filter` (optional, for WASM compatibility)\n- No `send` feature initially (can add later if needed)\n- Attr must have special access patterns (not simplified)","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-26T15:21:51.214593Z","updated_at":"2025-12-02T19:35:48.602062Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-409","depends_on_id":"k-407","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-41","title":"Update one complete parsing module as proof of concept","description":"Choose a simple module (e.g., thematic_break.rs). Use new node_to_source_info_with_context helpers. Populate source_info_qsm field. Verify tests pass and location info is preserved. This validates the migration approach before wider rollout.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T00:28:43.290726Z","updated_at":"2025-10-19T00:39:10.753194Z","closed_at":"2025-10-19T00:39:10.753194Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-41","depends_on_id":"k-27","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-41","depends_on_id":"k-40","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-410","title":"Rust port of citeproc with source-tracked CSL parsing","description":"Port the citeproc Haskell library to Rust, with a key enhancement: CSL style files should be parsed with source location tracking (similar to quarto-yaml's approach for YAML).\n\n**Goals:**\n1. Rust implementation of CSL 1.0.2 citation processing\n2. Source-tracked CSL parsing using quick-xml's event API\n3. Integration with quarto-markdown-pandoc's Pandoc AST\n4. Good error messages pointing to exact CSL locations\n\n**Key Components:**\n- CSL XML parser with SourceInfo annotations (like quarto-yaml)\n- Core citation processing algorithm (Eval module equivalent)\n- Integration with quarto-source-map for position tracking\n- Output to Pandoc Inlines (CiteprocOutput trait equivalent)\n\n**Design Report:** claude-notes/plans/2025-11-26-citeproc-rust-port-design.md\n\n**References:**\n- Haskell citeproc: external-sources/citeproc/\n- quick-xml: external-sources/quick-xml/\n- quarto-yaml patterns: crates/quarto-yaml/","status":"open","priority":4,"issue_type":"epic","created_at":"2025-11-26T15:54:26.380552Z","updated_at":"2025-12-02T00:39:55.842344Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-411","title":"quarto-xml: Generic XML parser with source tracking","description":"Create quarto-xml crate that provides source-tracked XML parsing, analogous to quarto-yaml.\n\n**Scope:**\n- Thin wrapper around quick-xml\n- Produces XmlWithSourceInfo, XmlElement, XmlAttribute types\n- Tracks element positions (start, end, full span)\n- Tracks attribute positions (name, value)\n- Handles text content and mixed content with positions\n- General-purpose: can parse any XML (CSL, JATS, DocBook, etc.)\n\n**Key Types:**\n- XmlWithSourceInfo (analogous to YamlWithSourceInfo)\n- XmlElement (name, attributes, children, source_info)\n- XmlAttribute (name, value, with positions for both)\n- XmlChildren (Elements, Text, Mixed, Empty)\n\n**Design:** claude-notes/plans/2025-11-26-citeproc-rust-port-design.md (see 'quarto-xml' section)\n\n**Dependencies:**\n- quick-xml\n- quarto-source-map","design":"- claude-notes/plans/2025-11-26-citeproc-rust-port-design.md (architecture overview)\n- claude-notes/research/2025-11-27-quarto-source-map-xml-compatibility.md (compatibility analysis, confirms no quarto-source-map changes needed)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-27T16:33:54.783340Z","updated_at":"2025-11-27T17:04:55.611804Z","closed_at":"2025-11-27T17:04:55.611804Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-411","depends_on_id":"k-410","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-412","title":"quarto-csl: CSL parsing with semantic types","description":"Create quarto-csl crate that parses CSL (Citation Style Language) files into semantic Rust types.\n\n**Scope:**\n- Takes XmlWithSourceInfo from quarto-xml as input\n- Produces semantic CSL types: Style, Element, Macro, Locale, etc.\n- Preserves source location information for error reporting\n- Validates CSL structure (macro references, circular dependencies)\n\n**Key Types:**\n- Style (version, options, macros, citation layout, bibliography layout)\n- Element (text, names, date, number, label, group, choose)\n- Macro (name with source info, elements)\n- Formatting (font-style, text-case, prefix, suffix, etc.)\n- Locale (terms, date formats)\n\n**Validation:**\n- Undefined macro detection with suggestions\n- Circular macro dependency detection\n- Invalid variable/term names\n\n**Design:** claude-notes/plans/2025-11-26-citeproc-rust-port-design.md (see 'quarto-csl' section)\n\n**Dependencies:**\n- quarto-xml (for XmlWithSourceInfo input)\n- quarto-source-map\n- quarto-error-reporting (for diagnostics)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-27T16:34:05.752803Z","updated_at":"2025-11-27T19:21:10.731725Z","closed_at":"2025-11-27T19:21:10.731725Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-412","depends_on_id":"k-410","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-412","depends_on_id":"k-411","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-413","title":"quarto-xml: Crate scaffolding and core types","description":"Create the quarto-xml crate structure with:\n- Cargo.toml with quick-xml and quarto-source-map dependencies\n- Core type definitions (XmlWithSourceInfo, XmlElement, XmlAttribute, XmlChildren)\n- Module structure (lib.rs, types.rs, parser.rs, error.rs)\n\nThis is foundational work before implementing the parser.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T16:56:31.264678Z","updated_at":"2025-11-27T17:01:45.534141Z","closed_at":"2025-11-27T17:01:45.534141Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-413","depends_on_id":"k-411","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-414","title":"quarto-xml: Basic element parsing with position tracking","description":"Implement the core parser:\n- Stack-based XML parsing using quick-xml events\n- Track element start positions (from error_position())\n- Compute element end positions (from buffer_position())\n- Build XmlElement tree with source_info for each element\n\nFocus on elements first, attributes and text content handled separately.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T16:56:43.229663Z","updated_at":"2025-11-27T17:02:06.043105Z","closed_at":"2025-11-27T17:02:06.043105Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-414","depends_on_id":"k-411","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-414","depends_on_id":"k-413","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-415","title":"quarto-xml: Attribute position tracking","description":"Add attribute position tracking:\n- Parse attributes from start/empty elements\n- Compute absolute positions from tag start + relative offset\n- Track both attribute name and value positions\n- Handle namespace prefixes correctly","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T16:56:44.351084Z","updated_at":"2025-11-27T17:04:15.346252Z","closed_at":"2025-11-27T17:04:15.346252Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-415","depends_on_id":"k-411","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-415","depends_on_id":"k-413","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-416","title":"quarto-xml: Text and mixed content handling","description":"Handle text content:\n- Track text content positions\n- Support mixed content (text + elements)\n- Handle CDATA sections\n- Normalize whitespace-only text (configurable)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T16:56:45.349193Z","updated_at":"2025-11-27T17:02:20.701548Z","closed_at":"2025-11-27T17:02:20.701548Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-416","depends_on_id":"k-411","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-416","depends_on_id":"k-413","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-417","title":"quarto-xml: Test suite","description":"Comprehensive tests for quarto-xml:\n- Simple element parsing\n- Nested elements\n- Attributes with positions\n- Text content\n- Mixed content\n- Empty elements\n- CSL-specific patterns (macros, choose, names)\n- Error cases (malformed XML)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-27T16:56:46.670336Z","updated_at":"2025-11-27T17:04:37.326057Z","closed_at":"2025-11-27T17:04:37.326057Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-417","depends_on_id":"k-411","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-417","depends_on_id":"k-413","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-418","title":"quarto-xml: Add README.md","description":"Create a minimalistic README.md describing:\n- Purpose of the crate (source-tracked XML parsing)\n- Core types (XmlWithSourceInfo, XmlElement, XmlAttribute)\n- Basic usage example\n- Relationship to quarto-yaml pattern","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-27T17:31:01.691666Z","updated_at":"2025-11-27T17:31:41.294011Z","closed_at":"2025-11-27T17:31:41.294011Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-418","depends_on_id":"k-411","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-419","title":"quarto-xml: Add Q-9-* error catalog entries","description":"Add XML processing errors to quarto-error-reporting/error_catalog.json:\n- Use subsystem number 9 (XML processing) per README.md\n- Add entries for existing error types: XmlSyntax, UnexpectedEof, MismatchedEndTag, InvalidStructure, EmptyDocument, MultipleRoots\n- Follow the existing catalog format and conventions","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T17:31:02.707909Z","updated_at":"2025-11-27T17:33:26.358626Z","closed_at":"2025-11-27T17:33:26.358626Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-419","depends_on_id":"k-411","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-42","title":"Investigate ASTContext serialization for JSON readers/writers","description":"Currently ASTContext.with_filename() stores filename in both 'filenames' Vec and 'source_context', requiring a clone. This duplication exists during the migration period. Investigate how to serialize ASTContext properly in JSON readers/writers so we can eventually remove one of these storage locations and eliminate the clone.","notes":"IMPORTANT: This is related to broader SourceInfo serialization concerns. When we serialize SourceInfo structures with Rc parent chains, the serialization duplicates the entire parent chain for each nested element (serde doesn't deduplicate Rc references). This creates significant JSON size blowup with deeply nested structures.\n\nAfter completing k-49 and k-50 (which will let us observe the serialization blowup in practice), we should investigate:\n1. Whether ASTContext serialization has similar issues\n2. If we need a custom serialization strategy for SourceInfo to avoid duplication\n3. Whether we can use some form of reference/ID system in the JSON format\n\nSee claude-notes/rc-serialization-caveat-analysis.md for background.","status":"open","priority":4,"issue_type":"task","created_at":"2025-10-19T13:22:18.415067Z","updated_at":"2025-11-23T21:31:08.197492Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-42","depends_on_id":"k-27","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-42","depends_on_id":"k-49","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-42","depends_on_id":"k-50","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-420","title":"quarto-xml: Integrate DiagnosticMessage with XmlParseContext","description":"Refactor quarto-xml to use DiagnosticMessage from quarto-error-reporting:\n- Create XmlParseContext struct to collect diagnostics during parsing\n- Thread mut XmlParseContext through parsing calls (like QMD writer pattern in quarto-markdown-pandoc/src/writers/qmd.rs)\n- Return diagnostics alongside results (valid parse can still have warnings/lints)\n- Convert existing Error types to produce DiagnosticMessage objects with Q-9-* codes\n\nThis enables future warnings and lints, not just errors.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T17:31:03.922449Z","updated_at":"2025-11-27T17:35:50.881377Z","closed_at":"2025-11-27T17:35:50.881377Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-420","depends_on_id":"k-411","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-420","depends_on_id":"k-419","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-421","title":"quarto-xml: Add error behavior tests","description":"Add tests verifying error behavior:\n- Test that specific error types are returned for malformed XML\n- Verify error messages contain useful information\n- Test DiagnosticMessage codes after integration\n- Don't need full snapshot testing (errors are rarer than markdown parse errors)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-27T17:31:05.499516Z","updated_at":"2025-11-27T17:36:41.069830Z","closed_at":"2025-11-27T17:36:41.069830Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-421","depends_on_id":"k-411","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-421","depends_on_id":"k-420","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-422","title":"quarto-citeproc: Citation processing engine","description":"Create quarto-citeproc crate that processes citations using CSL styles.\n\n**Scope:**\n- Takes Style from quarto-csl, References (CSL-JSON), and Citations\n- Produces formatted Pandoc Inlines for citations and bibliography\n- Handles locale/term lookup with fallback chain\n- Implements CSL evaluation algorithm\n\n**Key Types:**\n- Reference (bibliographic data from CSL-JSON)\n- Citation, CitationItem (citation requests)\n- EvalContext (evaluation state)\n\n**Core Features (Phase 3):**\n- Basic text/variable rendering\n- Group elements with delimiters\n- Formatting application (font-style, text-case, prefix/suffix)\n- Simple names rendering\n- Basic date rendering\n- Locale term lookup\n\n**Design:** claude-notes/plans/2025-11-26-citeproc-rust-port-design.md (see Phase 3+)\n\n**Dependencies:**\n- quarto-csl (for Style, Element types)\n- quarto-source-map\n- serde/serde_json (for CSL-JSON parsing)\n\n**Resources:**\n- 60 locale files in locales/\n- 858 CSL conformance tests in test-data/csl-suite/","status":"in_progress","priority":4,"issue_type":"task","created_at":"2025-11-27T19:42:35.144070Z","updated_at":"2025-12-02T00:39:26.789258Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-422","depends_on_id":"k-412","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-423","title":"Refactor Output to tagged AST architecture","description":"Introduce intermediate Output enum with Tag support for disambiguation, suppress-author, year suffixes, and hyperlinking. See plan: claude-notes/plans/2025-11-27-citeproc-output-architecture-refactor.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T21:02:34.928484Z","updated_at":"2025-11-27T21:09:46.829119Z","closed_at":"2025-11-27T21:09:46.829119Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-423","depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-424","title":"Name formatting edge cases (et-al-use-last, delimiter-precedes-last)","description":"Implement missing name formatting features to unlock 20-30 tests. See plan: claude-notes/plans/2025-11-27-csl-conformance-roadmap.md#phase-1","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-27T21:23:07.844132Z","updated_at":"2025-11-27T21:42:22.993502Z","closed_at":"2025-11-27T21:42:22.993502Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-424","depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-425","title":"Bibliography sorting","description":"Implement bibliography sorting with sort keys, multi-level sorting, and collation. Foundational for 62+ tests. See plan: claude-notes/plans/2025-11-27-csl-conformance-roadmap.md#phase-2","status":"in_progress","priority":4,"issue_type":"task","created_at":"2025-11-27T21:23:13.229157Z","updated_at":"2025-12-02T00:38:49.665867Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-425","depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-425","depends_on_id":"k-424","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-426","title":"Citation collapsing","description":"Implement citation collapsing (year, year-suffix, citation-number). Uses Output AST tags. 21 tests. See plan: claude-notes/plans/2025-11-27-csl-conformance-roadmap.md#phase-3","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-27T21:23:19.772540Z","updated_at":"2025-12-02T00:39:05.064799Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-426","depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-426","depends_on_id":"k-425","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-427","title":"Full disambiguation algorithm","description":"Implement complete disambiguation: add-givenname, add-year-suffix, givenname-disambiguation-rule. 67 tests. See plan: claude-notes/plans/2025-11-27-csl-conformance-roadmap.md#phase-4","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-27T21:23:24.560520Z","updated_at":"2025-12-02T00:38:56.733561Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-427","depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-427","depends_on_id":"k-426","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-428","title":"Phase 1 remaining: name formatting edge cases","description":"Optional/deferred name formatting features: HTML entity escaping, complex initialize=false variants, name-part elements, apostrophe handling. See plan: claude-notes/plans/2025-11-27-phase1-remaining-name-features.md","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-27T22:05:32.498847Z","updated_at":"2025-12-02T00:38:43.145568Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-428","depends_on_id":"k-422","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-429","title":"Extract Pandoc AST types to quarto-pandoc-types crate","description":"Create quarto-pandoc-types crate with full Pandoc AST, enabling quarto-citeproc to produce Pandoc Inlines output. See plan: claude-notes/plans/2025-11-27-quarto-pandoc-types-extraction.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-28T00:54:10.464197Z","updated_at":"2025-11-28T01:08:34.290502Z","closed_at":"2025-11-28T01:08:34.290502Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-429","depends_on_id":"k-422","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-43","title":"Performance: Optimize SourceMapping to use Rc/Arc instead of Box","description":"SourceMapping currently uses Box for parent references, causing expensive deep clones every time make_source_info() is called during YAML parsing (hundreds of times per document). Consider changing to Rc or Arc to make cloning cheap (reference counting). Need to study: serialization implications, thread-safety requirements, and performance benchmarks.","notes":"RECOMMENDATION: Use Rc instead of Box.\n\nAnalysis in claude-notes/sourcemapping-rc-arc-analysis.md\n\nKey findings:\n- Serde supports Rc with 'rc' feature flag\n- Serialization doesn't preserve sharing (acceptable)\n- Rc preferred over Arc (no threading, faster)\n- Expected 10-50x speedup for nested documents\n- Easy migration to Arc if needed later\n\nImplementation:\n1. Add serde rc feature to Cargo.toml\n2. Box → Rc\n3. Box::new → Rc::new\n4. Verify serialization tests pass","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T13:22:29.607980Z","updated_at":"2025-10-19T13:37:10.883135Z","closed_at":"2025-10-19T13:37:10.883135Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-43","depends_on_id":"k-27","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-430","title":"Fix prefix/suffix ordering for layout formatting","description":"CSL spec puts prefix/suffix INSIDE formatting for layout elements. Currently we apply formatting first, then add prefix/suffix - should be reversed. See claude-notes/plans/2025-11-27-csl-failing-test-analysis.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-28T01:36:18.517666Z","updated_at":"2025-11-28T01:41:14.539423Z","closed_at":"2025-11-28T01:41:14.539423Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-430","depends_on_id":"k-422","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-431","title":"Preserve HTML markup in CSL-JSON text fields","description":"CSL-JSON allows HTML markup in text fields like title. We escape it instead of preserving. Example: 'Title' becomes '<i>Title</i>'. See claude-notes/plans/2025-11-27-csl-failing-test-analysis.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-28T01:36:24.387607Z","updated_at":"2025-11-28T01:48:43.349730Z","closed_at":"2025-11-28T01:48:43.349730Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-431","depends_on_id":"k-422","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-432","title":"Implement flip-flop formatting","description":"When italic is applied to content already containing , nested italics should flip to normal using . Affects 19 flipflop_* tests. See claude-notes/plans/2025-11-27-csl-failing-test-analysis.md","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-11-28T01:36:30.656639Z","updated_at":"2025-11-28T02:09:50.056754Z","closed_at":"2025-11-28T02:09:50.056754Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-432","depends_on_id":"k-422","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-433","title":"Text case edge cases (quotes, stop words)","description":"Text case transformations have issues: content inside quotes being lowercased, quote chars escaped as ", stop words not handled. See claude-notes/plans/2025-11-27-csl-failing-test-analysis.md","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-11-28T01:36:36.000213Z","updated_at":"2025-11-28T01:59:06.682741Z","closed_at":"2025-11-28T01:59:06.682741Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-433","depends_on_id":"k-422","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-434","title":"Date era formatting (BC/AD for negative years)","description":"Negative years should display with era suffix: '100BC' not '-100'. See claude-notes/plans/2025-11-27-csl-failing-test-analysis.md","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-11-28T01:36:41.485027Z","updated_at":"2025-11-28T02:27:32.265412Z","closed_at":"2025-11-28T02:27:32.265412Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-434","depends_on_id":"k-422","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-435","title":"Title case stop words not implemented","description":"Title case transformation should lowercase stop words (to, and, for, the, a, an, etc.) except at the start of a sentence. Currently all words are capitalized. Example: 'from \"distance\" to \"friction\"' should become 'From \"Distance\" to \"Friction\"' but we produce 'From \"Distance\" To \"Friction\"'. See textcase_InQuotes test.","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-11-28T02:00:30.129650Z","updated_at":"2025-11-29T20:03:36.943769Z","closed_at":"2025-11-29T20:03:36.943769Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-435","depends_on_id":"k-433","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-436","title":"Title case should preserve content inside quotes","description":"Title case transformation should not modify text inside quotation marks. Currently quoted content is being lowercased then capitalized like other words. Example: 'from \"distance\"' with title case should preserve the quoted word's original case or capitalize it as a unit, not lowercase it. See textcase_InQuotes test.","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-11-28T02:00:30.947039Z","updated_at":"2025-11-29T20:03:41.974135Z","closed_at":"2025-11-29T20:03:41.974135Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-436","depends_on_id":"k-433","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-437","title":"Implement CSL disambiguation","description":"Implement disambiguation for CSL citations. Plan: claude-notes/plans/2025-11-28-disambiguation-study.md","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-11-28T15:59:20.720541Z","updated_at":"2025-11-28T18:07:43.402073Z","closed_at":"2025-11-28T18:07:43.402073Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-438","title":"Phase 1: Disambiguation infrastructure","description":"Parse disambiguation attributes, add DisambiguationData to Reference, implement year-suffix variable","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-28T15:59:25.417403Z","updated_at":"2025-11-28T16:03:39.592859Z","closed_at":"2025-11-28T16:03:39.592859Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-438","depends_on_id":"k-437","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-439","title":"Phase 2: Ambiguity detection","description":"Implement DisambData structure and find_ambiguities function","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-28T15:59:35.739829Z","updated_at":"2025-11-28T16:09:07.167129Z","closed_at":"2025-11-28T16:09:07.167129Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-439","depends_on_id":"k-437","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-439","depends_on_id":"k-438","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-44","title":"Investigate and optimize SourceInfo JSON serialization size","description":"SourceInfo serialization duplicates parent chains in JSON. For a document with 100 YAML nodes sharing a parent, JSON contains ~100 full copies of the parent chain.\n\nProblem: When shipping SourceInfo across WASM/TypeScript boundaries, large documents may produce bloated JSON.\n\nInvestigation needed:\n1. Benchmark actual serialization sizes on real documents\n2. Measure impact of gzip/brotli compression\n3. Consider custom serialization with ID-based references\n4. Evaluate flattening parent chains to original positions\n\nSee claude-notes/rc-serialization-caveat-analysis.md for detailed analysis.\n\nNote: This is separate from the Rc optimization (k-43). Rc improves memory during parsing. This issue is about JSON size for process boundaries.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T13:36:59.796906Z","updated_at":"2025-10-20T20:09:12.027921Z","closed_at":"2025-10-20T20:09:12.027921Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-44","depends_on_id":"k-34","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-44","depends_on_id":"k-43","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-440","title":"Phase 3: Year suffix assignment","description":"Implement addYearSuffixes following bibliography sort order","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-28T15:59:35.760239Z","updated_at":"2025-11-28T16:09:07.187101Z","closed_at":"2025-11-28T16:09:07.187101Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-440","depends_on_id":"k-437","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-440","depends_on_id":"k-438","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-441","title":"Phase 4: Name disambiguation","description":"Implement tryAddNames, tryAddGivenNames, apply name hints in rendering","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-28T15:59:35.780279Z","updated_at":"2025-11-28T16:15:26.022830Z","closed_at":"2025-11-28T16:15:26.022830Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-441","depends_on_id":"k-437","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-441","depends_on_id":"k-438","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-442","title":"Phase 5: Disambiguation condition","description":"Implement tryDisambiguateCondition, fix ConditionType::Disambiguate","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-28T15:59:35.799581Z","updated_at":"2025-11-28T17:56:18.167906Z","closed_at":"2025-11-28T17:56:18.167906Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-442","depends_on_id":"k-437","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-442","depends_on_id":"k-438","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-443","title":"Phase 6: Integration","description":"Two-pass rendering, bibliography coordination","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-28T15:59:35.819937Z","updated_at":"2025-11-28T18:07:32.662010Z","closed_at":"2025-11-28T18:07:32.662010Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-443","depends_on_id":"k-437","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-443","depends_on_id":"k-438","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-444","title":"Multi-pass rendering architecture for quarto-citeproc","description":"Refactor quarto-citeproc to use a multi-pass rendering architecture similar to Pandoc's citeproc. This enables proper delimiter handling, substitute inheritance, and multi-pass disambiguation.\n\nKey changes:\n1. Add delimiter to Formatting struct (apply at render time, not evaluation)\n2. Implement CslRenderer trait for format-agnostic rendering\n3. Add substitute context inheritance in EvalContext\n4. Refactor disambiguation to use iterative re-rendering\n\nExpected impact: Unlock 80-150 additional CSL tests.\n\nSee detailed design: claude-notes/plans/2025-11-28-multi-pass-rendering-architecture.md","status":"in_progress","priority":4,"issue_type":"feature","created_at":"2025-11-28T17:16:56.366848Z","updated_at":"2025-12-02T00:38:32.516951Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-445","title":"Refactor EvalContext for unified variable lookup","description":"Add locator/label fields to EvalContext and create unified get_variable() method. This centralizes variable resolution and prepares for citation item support. See claude-notes/plans/2025-11-27-csl-conformance-roadmap.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-28T20:09:46.466267Z","updated_at":"2025-11-28T20:12:59.745492Z","closed_at":"2025-11-28T20:12:59.745492Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-446","title":"Implement citation item variable support (locator, label)","description":"Support citation item variables: locator, label. Required for ~50+ tests including label plural detection, position tracking. Depends on k-445 (EvalContext refactoring).","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-28T20:09:52.846487Z","updated_at":"2025-11-28T20:15:43.161183Z","closed_at":"2025-11-28T20:15:43.161183Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-446","depends_on_id":"k-445","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-447","title":"Implement citation position tracking (ibid, subsequent, near-note)","description":"Track citation history to detect position conditions: ibid (same as previous), ibid-with-locator, subsequent, near-note. Required for note-style citations. Unlocks ~26 position tests plus many bugreports. Architecture: add citation history to Processor, track previous citation ID and note number.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-28T20:21:53.586937Z","updated_at":"2025-11-28T20:31:25.900914Z","closed_at":"2025-11-28T20:31:25.900914Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-448","title":"Implement correct fixPunct behavior matching Pandoc citeproc","description":"Current fix_punct_inlines is applied as global post-process which is incorrect. Need to apply at sibling boundaries during rendering, matching Pandoc's approach. See claude-notes/plans/2025-11-28-fixpunct-correct-implementation.md","status":"in_progress","priority":4,"issue_type":"task","created_at":"2025-11-28T22:11:52.534598Z","updated_at":"2025-12-02T00:38:22.468703Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-449","title":"Implement CSL disambiguation re-rendering loop","description":"Core disambiguation algorithm needs iterative re-rendering after applying fixes. See claude-notes/plans/2025-11-28-disambiguation-fixes.md for full analysis. Phase 1: Re-rendering loop. Phase 2: Add-names logic. Phase 3: Year suffix edge cases. Phase 4: Citation-label.","status":"in_progress","priority":4,"issue_type":"feature","created_at":"2025-11-29T00:14:59.713645Z","updated_at":"2025-12-02T00:38:15.598805Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-45","title":"Phase 4: Design and implement MetaWithSourceInfo structure","description":"Replace Meta (LinkedHashMap) with MetaWithSourceInfo that preserves source location tracking from YamlWithSourceInfo through the YAML→Meta transformation. This enables proper error reporting and validates serialization approach before Phase 3 migration.\n\nKey insight: Pandoc's Meta is not YAML - it's an interpreted structure where strings are parsed as Markdown. We need source tracking at every level: keys, values, and nested structures.\n\nSee claude-notes/phase4-metawithsourceinfo-design.md for detailed design.","status":"closed","priority":1,"issue_type":"epic","created_at":"2025-10-19T14:07:12.810111Z","updated_at":"2025-10-20T20:04:31.593778Z","closed_at":"2025-10-20T20:04:31.593778Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-45","depends_on_id":"k-27","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-450","title":"quarto-citeproc: Name handling architecture fixes","description":"Fix architectural issues in name handling that prevent ~56 CSL conformance tests from passing.\n\n**Plan:** claude-notes/plans/2025-11-28-name-handling-architecture.md\n\n**Key Issues:**\n1. Name formatting returns String instead of Output (blocks all other fixes)\n2. Missing `` element support for per-part formatting\n3. Missing `comma_suffix` and `static_ordering` fields on Name struct\n4. Missing Byzantine (non-Western) name detection\n5. Missing `demote-non-dropping-particle` style option\n\n**Implementation Order:**\n1. Refactor format_names/format_single_name to return Output\n2. Add name-part formatting to CSL parser\n3. Add missing Name fields\n4. Add Byzantine name detection\n5. Add demote-non-dropping-particle support\n\n**Impact:** ~56 failing tests in name_* category","notes":"All 5 phases implemented:\n- Phase 1: format_single_name returns Output (complete)\n- Phase 2: name-part formatting works (complete)\n- Phase 3: comma_suffix and static_ordering fields added (complete)\n- Phase 4: is_byzantine() method implemented (complete)\n- Phase 5: demote_non_dropping_particle support (complete)\n\nRemaining issues are edge case bugs, not architectural. 42 unknown name tests remain (47 fail when run). Key bugs identified:\n1. Dropping particle not wrapped in separate formatting element\n2. initialize=false period handling strips trailing periods\n3. initialize=false space normalization not working\n\nThese bugs should be tracked as separate focused issues.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-29T01:29:23.312079Z","updated_at":"2025-11-29T20:08:00.894711Z","closed_at":"2025-11-29T20:08:00.894711Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-450","depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-451","title":"Dropping particle not wrapped in separate formatting element","description":"When dropping particles appear after the given name in inverted order, they should be wrapped in their own formatting element.\n\nExpected: `Givenname al`\nActual: `Givenname al`\n\nThis affects name_ParticlesDemoteNonDroppingNever and similar tests. The Output AST structure is correct but formatting application needs refinement.\n\nDiscovered from: k-450","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-29T17:49:36.962740Z","updated_at":"2025-11-29T19:39:53.245554Z","closed_at":"2025-11-29T19:39:53.245554Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-451","depends_on_id":"k-450","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-452","title":"initialize=false strips trailing periods from initials","description":"When initialize=\"false\" is set, existing periods in given names should be preserved but our implementation strips trailing periods.\n\nExpected: `M.E` → `M.E.` (adds period per initialize-with)\nActual: `M.E` → `M.E` (no trailing period)\n\nAlso affects space normalization:\nExpected: `M E` → `M.E.`\nActual: `M E` → `M E`\n\nAffects name_InitialsInitializeFalsePeriod and similar tests.\n\nDiscovered from: k-450","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-29T17:49:43.886941Z","updated_at":"2025-11-29T18:46:32.542137Z","closed_at":"2025-11-29T18:46:32.542137Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-452","depends_on_id":"k-450","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-453","title":"Hyphenated given names produce extra initials","description":"When a given name is hyphenated (e.g., Guo-Ping), our implementation produces initials for each part (G-P) but some tests expect only the first initial (G).\n\nExpected: `Guo-Ping Chen` → `G Chen`\nActual: `Guo-Ping Chen` → `G-P Chen`\n\nAffects name_LowercaseSurnameSuffix and similar tests.\n\nDiscovered from: k-450","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-29T17:49:49.513744Z","updated_at":"2025-11-29T18:46:31.396474Z","closed_at":"2025-11-29T18:46:31.396474Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-453","depends_on_id":"k-450","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-454","title":"Implement citation-label variable generation","description":"The `citation-label` variable is a special auto-generated variable used in Harvard-style citations. It produces labels like 'Doe65', 'RoNo78a' from author names + year.\n\n**Impact:** 5 test files use this feature, causing 4 tests to produce empty output (critical for MVP).\n\n**Tests affected:**\n- disambiguate_CitationLabelDefault\n- disambiguate_Trigraph\n- disambiguate_CitationLabelInData\n- magic_CitationLabelInCitation\n- magic_CitationLabelInBibliography\n\n**Reference:** Pandoc citeproc implementation in external-sources/citeproc/","notes":"Plan: claude-notes/plans/2025-11-29-citation-label-implementation.md\n\nImplementation approach: Compute on demand (Option A)\n- Add generate_citation_label() to Reference\n- Modify get_variable() to handle citation-label specially\n- Add year suffix integration in evaluate_text()\n\nKey algorithm:\n- 1 author: first 4 chars of family name\n- 2-3 authors: first 2 chars each\n- 4+ authors: first 1 char each (up to 4)\n- Plus 2-digit year\n\nEdge cases handled:\n- Particle stripping (von Dipheria -> Dipheria -> D)\n- Data override (use citation-label from CSL-JSON if present)\n- Year suffix appended during rendering","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-29T18:05:29.974234Z","updated_at":"2025-11-29T18:18:00.913473Z","closed_at":"2025-11-29T18:18:00.913473Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-455","title":"Em-dash incorrectly forces title case capitalization","description":"In title case, em-dash and en-dash should be word breaks but NOT force capitalization of the next word. Currently treating them like sentence-ending punctuation. Test: textcase_titlewithemdash","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-11-29T20:03:57.410819Z","updated_at":"2025-11-29T20:12:02.663648Z","closed_at":"2025-11-29T20:12:02.663648Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-455","depends_on_id":"k-436","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-456","title":"Curly apostrophe breaks words in title case","description":"Curly apostrophe (U+2019) incorrectly breaks words. 'Shafi'i' becomes 'Shafi'I' instead of 'Shafi'i'. The apostrophe should be treated as part of the word. Test: textcase_nospacebeforeapostrophe","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-11-29T20:04:03.620477Z","updated_at":"2025-11-29T20:12:03.427389Z","closed_at":"2025-11-29T20:12:03.427389Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-456","depends_on_id":"k-436","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-457","title":"Fix page range en-dash formatting","description":"Page ranges should use en-dash (–) not hyphen (-). Affects 4 bugreports tests: contextualpluralwithmainitemfields, ieeepunctuation, numberinmacrowithverticalalign, parenthesis. See claude-notes/plans/2025-11-29-bugreports-analysis.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-29T21:01:34.223648Z","updated_at":"2025-11-29T21:11:31.817796Z","closed_at":"2025-11-29T21:11:31.817796Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-457","depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-458","title":"Fix punctuation-in-quote handling","description":"Punctuation should move inside quotes when punctuation-in-quote is enabled. Affects 8 bugreports tests. See claude-notes/plans/2025-11-29-bugreports-analysis.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-29T21:01:38.740865Z","updated_at":"2025-11-29T21:27:52.875388Z","closed_at":"2025-11-29T21:27:52.875388Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-458","depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-459","title":"Fix year-suffix disambiguation","description":"Year suffixes (a, b, c) not being assigned when disambiguating works by same author in same year. Affects 5 bugreports tests. See claude-notes/plans/2025-11-29-bugreports-analysis.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-29T21:01:43.329470Z","updated_at":"2025-11-29T23:22:58.185735Z","closed_at":"2025-11-29T23:22:58.185735Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-459","depends_on_id":"k-422","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-46","title":"Define MetaValueWithSourceInfo enum and supporting types","description":"Create new types in pandoc/meta.rs:\n- MetaValueWithSourceInfo enum (replacing MetaValue)\n- Each variant stores value + SourceInfo\n- MetaMap stores (key, key_source, value) tuples\n- Preserve all existing variant types (String, Bool, Inlines, Blocks, List, Map)\n\nAdd Serialize/Deserialize derives.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T14:07:35.507557Z","updated_at":"2025-10-19T14:13:21.642330Z","closed_at":"2025-10-19T14:13:21.642330Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-46","depends_on_id":"k-45","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-460","title":"Session handoff notes for year-suffix disambiguation work","description":"See claude-notes/plans/2025-11-29-session-handoff-notes.md for context on completed work (k-457, k-458) and preparation for k-459 (year-suffix disambiguation). Contains technical notes, affected tests, recommended approach, and useful commands.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-11-29T22:40:38.931936Z","updated_at":"2025-11-30T00:24:58.065969Z","closed_at":"2025-11-30T00:24:58.065969Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-460","depends_on_id":"k-459","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-461","title":"Design subsequent-author-substitute for bibliography","description":"Design and implement subsequent-author-substitute feature for CSL bibliography rendering.\n\n**Current State:**\n- Tests failing: name_SubsequentAuthorSubstituteSingleField, name_SubsequentAuthorSubstituteMultipleNames\n- Feature replaces repeated author names with substitute string (typically '———')\n- Requires tracking state across bibliography entries\n\n**CSL Specification:**\n- subsequent-author-substitute attribute on bibliography element\n- subsequent-author-substitute-rule (complete-all, complete-each, partial-first, partial-each)\n- Only applies to bibliography, not citations\n\n**Required Investigation:**\n1. Read Pandoc's implementation in external-sources/citeproc/src/Citeproc/Eval.hs\n2. Understand how author identity is determined for substitution\n3. Design state management for cross-entry tracking\n4. Consider integration with existing bibliography rendering\n\n**Design Output:**\nCreate plan in claude-notes/plans/YYYY-MM-DD-subsequent-author-substitute-design.md\n\n**Parent:** k-410 (citeproc epic)","notes":"Design plan: claude-notes/plans/2025-12-01-subsequent-author-substitute-design.md","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-30T00:53:20.582841Z","updated_at":"2025-12-02T00:39:48.849997Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-461","depends_on_id":"k-410","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-462","title":"Design citation collapsing feature","description":"Design and implement citation collapsing features for CSL citation rendering.\n\n**Current State:**\n- Tests failing: name_CiteGroupDelimiterWithYearSuffixCollapse, name_CiteGroupDelimiterWithYearSuffixCollapse3, name_CollapseRoleLabels\n- Multiple collapse modes: year, year-suffix, year-suffix-ranged, citation-number\n- Requires post-processing of rendered citations\n\n**CSL Specification:**\n- collapse attribute on citation element\n- cite-group-delimiter for separator between collapsed cites\n- Interacts with year-suffix disambiguation\n\n**Required Investigation:**\n1. Read Pandoc's implementation of collapse in external-sources/citeproc/src/Citeproc/Eval.hs\n2. Understand how citation groups are identified for collapse\n3. Design the post-processing phase for collapse\n4. Consider year-suffix-ranged mode (1998a-c)\n\n**Design Output:**\nCreate plan in claude-notes/plans/YYYY-MM-DD-citation-collapsing-design.md\n\n**Parent:** k-410 (citeproc epic)","status":"open","priority":4,"issue_type":"task","created_at":"2025-11-30T00:53:29.078041Z","updated_at":"2025-12-02T00:39:39.256509Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-462","depends_on_id":"k-410","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-463","title":"Investigate and fix substitute mechanism","description":"Investigate the substitute mechanism implementation - multiple tests fail due to substitute behavior.\n\n**Failing Tests (5+):**\n- name_LabelFormatBug - label not rendering with substitute\n- name_SubstituteInheritLabel - label inheritance in substitute\n- name_QuashOrdinaryVariableRenderedViaSubstitute - variable suppression\n- name_SubstituteOnNamesSpanGroupSpanFail - group span interaction\n- name_SubstitutePartialEach - partial substitution\n\n**Symptoms:**\n- Labels not rendered when substitute activates\n- Label formatting not inherited properly\n- Variable suppression not working correctly\n\n**Required Investigation:**\n1. Read Pandoc's substitute implementation in external-sources/citeproc/src/Citeproc/Eval.hs\n2. Compare our substitute handling in evaluate_names()\n3. Understand label inheritance rules in substitute context\n4. Identify gaps in current implementation\n\n**Priority:** High - this blocks multiple tests and is a core CSL feature\n\n**Parent:** k-410 (citeproc epic)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-30T00:53:39.692983Z","updated_at":"2025-11-30T15:28:19.259304Z","closed_at":"2025-11-30T15:28:19.259304Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-463","depends_on_id":"k-410","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-464","title":"Enhance particle extraction for punctuation-connected particles","description":"Enhance the extract_particles() function in reference.rs to handle particles connected by punctuation (apostrophes, hyphens, en-dashes).\n\n**Plan document:** claude-notes/plans/2025-11-30-particle-extraction-enhancement.md\n\n**Failing tests to unblock:**\n- name_ParsedDroppingParticleWithApostrophe\n- name_ParsedNonDroppingParticleWithApostrophe \n- name_HyphenatedNonDroppingParticle1\n- name_HyphenatedNonDroppingParticle2\n\n**Current behavior:** Only space-separated particles are extracted\n**Required:** Extract punctuation-connected particles like \"d'\" from \"d'Aubignac\" and \"al-\" from \"al-One\"\n\n**Reference:** Haskell citeproc Types.hs:1241-1281 (extractParticles function)\n\n**Parent:** k-410 (citeproc epic)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-30T17:12:31.104088Z","updated_at":"2025-11-30T17:30:20.907173Z","closed_at":"2025-11-30T17:30:20.907173Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-464","depends_on_id":"k-410","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-465","title":"CSL: Implement affixesInside flag for proper suffix placement","description":"Suffixes appear inside formatting instead of outside. Need to implement formatAffixesInside flag like Pandoc citeproc. Blocks flipflop_ItalicsWithOk, flipflop_ItalicsWithOkAndTextcase. See claude-notes/plans/2025-11-30-flipflop-remaining-blockers.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-30T18:26:59.762236Z","updated_at":"2025-11-30T19:05:57.671644Z","closed_at":"2025-11-30T19:05:57.671644Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-465","depends_on_id":"k-432","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-466","title":"CSL: Parse HTML entities as markup in text values","description":"HTML entities in should be unescaped and interpreted as markup. Currently <b> is output literally instead of being parsed as . Blocks flipflop_BoldfaceNodeLevelMarkup. See claude-notes/plans/2025-11-30-flipflop-remaining-blockers.md","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-11-30T18:27:09.575920Z","updated_at":"2025-11-30T18:37:17.862362Z","closed_at":"2025-11-30T18:37:17.862362Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-466","depends_on_id":"k-432","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-467","title":"CSL: Smart quote and apostrophe handling in rich text","description":"Quote and apostrophe handling isn't working correctly inside markup tags. Need smart quote conversion, locale-aware quote styles, and apostrophe vs single quote distinction. Blocks flipflop_ApostropheInsideTag, flipflop_QuotesNodeLevelMarkup, flipflop_QuotesInFieldNotOnNode, flipflop_OrphanQuote, flipflop_SingleBeforeColon. See claude-notes/plans/2025-11-30-flipflop-remaining-blockers.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-11-30T18:27:20.024461Z","updated_at":"2025-11-30T18:50:15.848404Z","closed_at":"2025-11-30T18:50:15.848404Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-467","depends_on_id":"k-432","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-468","title":"CSL: text-case transformation should not affect nodecor content","description":"In flipflop_ItalicsWithOkAndTextcase, content inside a nodecor span (font-variant:normal) is incorrectly affected by the outer text-case=capitalize-all transformation. Expected: 'v.' (lowercase), Actual: 'V.' (uppercase). The nodecor mechanism should protect content from text-case transformations.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-11-30T19:06:06.034219Z","updated_at":"2025-11-30T19:45:15.789582Z","closed_at":"2025-11-30T19:45:15.789582Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-468","depends_on_id":"k-465","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-469","title":"Phase 1: Core Lua filter types and infrastructure","description":"Foundation for Lua filter support. See claude-notes/plans/2025-12-02-mlua-analysis.md\n\nTasks:\n- Add mlua optional dependency to Cargo.toml with `lua-filter` feature\n- Create `src/lua/mod.rs` module structure (behind `#[cfg(feature = \"lua-filter\")]`)\n- Implement `LuaInline` wrapper with basic fields\n- Implement `LuaBlock` wrapper with basic fields\n- Support common types: Str, Para, Header, Link, Emph, Strong\n- Implement constructors: `pandoc.Str()`, `pandoc.Para()`, etc.\n- Basic typewise traversal\n- Add `--lua-filter` CLI argument (behind feature flag)\n- Test with simple filter (uppercase Str elements)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-02T17:53:17.350115Z","updated_at":"2025-12-02T18:12:17.896290Z","closed_at":"2025-12-02T18:12:17.896290Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-469","depends_on_id":"k-409","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-47","title":"Implement yaml_to_meta_with_source_info transformation","description":"Implement transformation function in pandoc/meta.rs:\n- Takes YamlWithSourceInfo → returns MetaValueWithSourceInfo\n- Parse YAML strings as Markdown (creating Substring SourceInfos)\n- Handle all YAML types (String, Bool, Hash, Array)\n- Recognize special YAML tags\n- Preserve source tracking through nested structures\n\nThis is the core logic that enriches YAML with Markdown parsing while maintaining source locations.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T14:07:37.662896Z","updated_at":"2025-10-19T14:17:44.723311Z","closed_at":"2025-10-19T14:17:44.723311Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-47","depends_on_id":"k-45","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-47","depends_on_id":"k-46","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-470","title":"Phase 2: Complete Lua filter element coverage","description":"Complete element field coverage for Lua filters. See claude-notes/plans/2025-12-02-mlua-analysis.md\n\nTasks:\n- All inline element fields\n- All block element fields\n- Meta value handling\n- Attr (attributes) with special access patterns (userdata, not simplified tables)\n - `attr.identifier` - string\n - `attr.classes` - list of strings\n - `attr.attributes` - key-value pairs\n - Positional access: `attr[1]`, `attr[2]`, `attr[3]`\n - Constructor: `pandoc.Attr(id, classes, attrs)`\n- List splicing semantics","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-02T17:53:25.362528Z","updated_at":"2025-12-02T18:32:20.722738Z","closed_at":"2025-12-02T18:32:20.722738Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-470","depends_on_id":"k-469","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-471","title":"Phase 3: Lua filter methods and traversal","description":"Methods and traversal modes for Lua filters. See claude-notes/plans/2025-12-02-mlua-analysis.md\n\nTasks:\n- `clone()` method on elements\n- `walk()` method (REQUIRED - too important for practical filters)\n - Must support AST traversal with Lua callback functions\n - Used extensively in real-world filters\n- `pairs()` iteration\n- Topdown traversal mode\n- Global variables (FORMAT, PANDOC_VERSION, etc.)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-02T17:53:31.360707Z","updated_at":"2025-12-02T18:56:21.923872Z","closed_at":"2025-12-02T18:56:21.923872Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-471","depends_on_id":"k-470","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-472","title":"Phase 4: Lua filter diagnostics and utilities","description":"Diagnostics and utility functions for Lua filters. See claude-notes/plans/2025-12-02-mlua-analysis.md\n\nTasks:\n- Filter provenance tracking (REQUIRED for diagnostic messages)\n - Capture source file and line from Lua `debug.getinfo()`\n - Store in wrapper types as `SourceInfo::FilterProvenance`\n - Report in error messages when filter-created elements cause issues\n- `pandoc.utils.stringify()`\n- Additional `pandoc.utils.*` functions as needed\n- Performance optimization","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-02T17:53:37.972187Z","updated_at":"2025-12-02T21:05:14.135869Z","closed_at":"2025-12-02T21:05:14.135869Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-472","depends_on_id":"k-471","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-473","title":"Lua API Port: Design and implement Pandoc Lua API for quarto-markdown-pandoc","description":"Design and implement the Pandoc Lua API for our Rust-based Lua filter subsystem. This includes element constructors, utility modules (pandoc.utils, pandoc.text, pandoc.path, pandoc.system, etc.), List type, and related infrastructure. See plan: claude-notes/plans/2025-12-02-lua-api-port-plan.md","status":"open","priority":1,"issue_type":"epic","created_at":"2025-12-02T22:14:30.672190Z","updated_at":"2025-12-02T22:14:30.672190Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-473","depends_on_id":"k-409","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-474","title":"Lua API: Implement List/Blocks/Inlines metatable system","description":"Implement the pandoc.List type and specialized Blocks/Inlines metatables. Lists are regular Lua tables with metatables providing methods like clone(), extend(), filter(), find(), map(), etc. Inlines/Blocks extend List with walk() and serialization. See plan: claude-notes/plans/2025-12-02-lua-api-port-plan.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-02T22:33:28.276144Z","updated_at":"2025-12-02T22:53:10.573147Z","closed_at":"2025-12-02T22:53:10.573147Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-474","depends_on_id":"k-409","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-475","title":"Lua API: Design and implement LuaRuntime abstraction layer","description":"Design dependency injection pattern for runtime operations (file I/O, network, environment) to support native, WASM/Emscripten, and sandboxed execution contexts. Trait-based design allows different implementations per target. See plan: claude-notes/plans/2025-12-02-lua-api-port-plan.md","notes":"Design document: claude-notes/plans/2025-12-03-lua-runtime-abstraction-layer.md\n\n## Key Design Decisions\n\nModeled after Deno's permission system (https://docs.deno.com/runtime/fundamentals/security/):\n\n### SecurityPolicy Structure (Deno-aligned)\n- `allow_read` / `deny_read` - File read paths (like --allow-read)\n- `allow_write` / `deny_write` - File write paths (like --allow-write)\n- `allow_net` / `deny_net` - Network hosts (like --allow-net)\n- `allow_run` / `deny_run` - Programs to execute (like --allow-run)\n- `allow_env` / `deny_env` - Environment variables (like --allow-env)\n- `allow_cwd` - CWD operations (grouped with env, like Deno's chdir)\n- `allow_sys` - System info APIs (like --allow-sys)\n\n### Resolved Design Questions\n1. **CWD handling**: Part of 'env' category; allow in native, deny in WASM, flag in sandboxed\n2. **Async network**: Design for blocking now, note async as future consideration\n3. **Module loading**: `require()` subject to file read permissions\n4. **Error messages**: Detailed, actionable messages (Deno pattern)\n\n### Key Patterns\n- Deny takes precedence over allow (Deno pattern)\n- Path wildcards supported (like `/home/user/*`)\n- Env var suffix wildcards (like `AWS_*`)\n- Replace Lua io/os modules with runtime-controlled versions\n\n### Industry Research\n- Deno: Mature model, full adoption of their patterns\n- Node.js: Permission model in v23.5+, simpler than Deno\n- Bun: No permission model yet (open issue #6617)","status":"open","priority":4,"issue_type":"feature","created_at":"2025-12-02T22:33:29.275099Z","updated_at":"2025-12-04T14:29:40.472449Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-475","depends_on_id":"k-409","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-476","title":"Lua API: Integrate quarto-citeproc with pandoc.utils.citeproc","description":"Connect quarto-citeproc Processor to Lua API via pandoc.utils.citeproc(doc). Needs to extract references/CSL from metadata, process citations, replace Cite elements, and add bibliography. See plan: claude-notes/plans/2025-12-02-lua-api-port-plan.md","status":"open","priority":1,"issue_type":"feature","created_at":"2025-12-02T22:33:30.243699Z","updated_at":"2025-12-02T22:33:30.243699Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-476","depends_on_id":"k-409","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-476","depends_on_id":"k-490","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-477","title":"Investigate Lua filter traversal order (typewise multi-pass)","description":"Our current Lua filter implementation uses a single bottom-up pass, but Pandoc's typewise traversal does multiple passes:\n\n1. First pass: ALL inline elements (Str, Emph, etc. + Inline fallback)\n2. Then: Inlines list filter\n3. Second pass: ALL block elements (Para, Header, etc. + Block fallback)\n4. Then: Blocks list filter\n5. Finally: Meta, then Pandoc\n\n**Current behavior (filter.rs):**\n- For each block, we process its inline children, then the block itself\n- This is bottom-up within a single traversal\n\n**Pandoc behavior (documented):**\n- \"Lua filter functions are run in the order: Inlines → Blocks → Meta → Pandoc\"\n- This suggests multiple passes over the document\n\n**Tasks:**\n1. Study Pandoc's Haskell source to understand exact traversal semantics\n2. Write test cases comparing our output to Pandoc's for filters that depend on traversal order\n3. Determine if the difference matters in practice\n4. If needed, implement multi-pass traversal to match Pandoc\n\n**Key files:**\n- crates/quarto-markdown-pandoc/src/lua/filter.rs (apply_filter_to_block, apply_filter_to_inlines)\n- crates/quarto-markdown-pandoc/src/lua/types.rs (walk_blocks_with_filter, walk_inlines_with_filter)\n\n**Also verify:**\n- Generic Inline/Block fallback priority (type-specific should win)\n- Add tests for these behaviors","notes":"Plan document: claude-notes/plans/2025-12-02-lua-filter-traversal-fix.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-02T23:42:18.469344Z","updated_at":"2025-12-03T15:18:30.243945Z","closed_at":"2025-12-03T15:18:30.243945Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-477","depends_on_id":"k-409","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-478","title":"Implement topdown traversal with stop signal for Lua filters","description":"Implement topdown traversal mode for Lua filters. When a filter sets traverse='topdown', the filter should process parents before children in a depth-first manner. Additionally, filters can return (element, false) to stop descent into children. This matches Pandoc's WalkTopdown behavior.","notes":"Plan: claude-notes/plans/2025-12-02-topdown-traversal.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-03T01:31:50.336579Z","updated_at":"2025-12-03T01:48:57.671782Z","closed_at":"2025-12-03T01:48:57.671782Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-478","depends_on_id":"k-477","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-479","title":"Update elem:walk{} to use correct four-pass traversal","description":"The walk methods in types.rs (walk_inlines_with_filter, walk_blocks_with_filter) used by elem:walk{} should use the same four-pass traversal as document-level filtering. Currently they interleave passes incorrectly. They should also support topdown traversal with stop signal when traverse='topdown' is set.","notes":"Plan: claude-notes/plans/2025-12-02-elem-walk-fix.md\n\nDepends on: k-478 (topdown traversal implementation)","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-03T01:31:57.855494Z","updated_at":"2025-12-03T15:18:31.006010Z","closed_at":"2025-12-03T15:18:31.006010Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-479","depends_on_id":"k-477","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-479","depends_on_id":"k-478","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-48","title":"Update rawblock_to_meta to use quarto-yaml","description":"Replace yaml-rust2 usage with quarto_yaml in rawblock_to_meta():\n- Use quarto_yaml::parse_with_parent() instead of yaml-rust2 Parser\n- Create parent SourceInfo from RawBlock\n- Create Substring SourceInfo for YAML content within frontmatter\n- Call yaml_to_meta_with_source_info() to get MetaValueWithSourceInfo\n- Return the new type\n\nThis integrates quarto-yaml into the metadata parsing pipeline.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T14:07:39.959315Z","updated_at":"2025-10-19T14:24:09.733868Z","closed_at":"2025-10-19T14:24:09.733868Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-48","depends_on_id":"k-45","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-48","depends_on_id":"k-47","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-480","title":"Implement quarto.warn() and quarto.error() Lua functions","description":"Implement Lua functions that allow filter authors to emit diagnostic messages (warnings and errors) during filter execution.\n\n**Summary:**\n- Add `quarto.warn(message [, element])` function\n- Add `quarto.error(message [, element])` function\n- Diagnostics are stored in a hidden Lua table during execution\n- After filter execution, diagnostics are extracted and returned to Rust\n- Source locations captured automatically from Lua stack or from AST element\n\n**Key Files to Create/Modify:**\n- Create: `src/lua/diagnostics.rs` - Core diagnostic functions\n- Modify: `src/lua/mod.rs` - Add module export\n- Modify: `src/lua/constructors.rs` - Register functions\n- Modify: `src/lua/filter.rs` - Update return types, extract diagnostics\n- Create: Test files for the new functionality\n\n**Design plan:** claude-notes/plans/2025-12-03-lua-filter-diagnostics-implementation.md\n\n**Related analysis:** claude-notes/plans/2025-12-02-filter-diagnostics-analysis.md","notes":"Updated plan to include Phase 4: LuaLS Documentation. See claude-notes/plans/2025-12-03-lua-filter-diagnostics-implementation.md for full details including LuaLS annotation format reference.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-03T15:27:21.250737Z","updated_at":"2025-12-03T15:53:30.532131Z","closed_at":"2025-12-03T15:53:30.532131Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-480","depends_on_id":"k-409","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-481","title":"quarto.warn/error element location doesn't work for original document elements","description":"## Problem\n\nThe `quarto.warn(msg, elem)` and `quarto.error(msg, elem)` functions accept an optional AST element to attach source location information. However, this only works for elements **created by filters** (which have `FilterProvenance` source info), not elements **from the original document** (which have `SourceInfo::Original`).\n\nThis is a significant limitation because user-provided filters that want to act as linters cannot report warnings/errors about specific locations in the source document - they can only report the filter's own location.\n\n## Root Cause\n\nIn `src/lua/diagnostics.rs`, the `source_info_to_path_line` function (lines 208-218) only handles `FilterProvenance`:\n\n```rust\nfn source_info_to_path_line(source_info: &SourceInfo) -> Option<(String, i64)> {\n match source_info {\n SourceInfo::FilterProvenance { filter_path, line } => {\n Some((filter_path.clone(), *line as i64))\n }\n // For Original source info, we don't have easy access to the filename\n // without a SourceContext. For now, return None to fall back to stack.\n _ => None,\n }\n}\n```\n\nFor `SourceInfo::Original`, we need access to `SourceContext` to:\n1. Look up the `FileId` to get the filename\n2. Map byte offsets to line/column numbers\n\nThe `SourceContext` is available in `ASTContext` but is not currently passed to the Lua diagnostic functions.\n\n## How to Test\n\nCreate a test filter `linter.lua`:\n```lua\nfunction Str(elem)\n if elem.text:match('TODO') then\n quarto.warn('Found TODO in document', elem)\n end\n return elem\nend\n```\n\nCreate a test document `test.qmd`:\n```markdown\nThis has a TODO item.\n```\n\nRun:\n```bash\ncargo run -- -L linter.lua -i test.qmd -t native\n```\n\n**Expected**: Warning shows location in `test.qmd` (line 1, around column 12)\n**Actual**: Warning shows location in `linter.lua` (line 3, the quarto.warn call)\n\n## Potential Solutions\n\n1. **Pass ASTContext to Lua state**: Store `ASTContext` (or at least `SourceContext`) in the Lua registry so diagnostic functions can access it\n2. **Thread-local context**: Use a thread-local to store context during filter execution\n3. **Closure capture**: Capture context in the Lua function closures created in `register_quarto_namespace`\n\nOption 1 or 3 seems cleanest. The context would need to be set before filter execution and cleared after.\n\n## Related\n\n- Parent issue: k-480 (Implement quarto.warn/error Lua functions)\n- Plan: claude-notes/plans/2025-12-03-lua-filter-diagnostics-implementation.md\n- Discussion: Element location extraction was identified as incomplete during implementation review","notes":"Plan document: claude-notes/plans/2025-12-03-k481-source-location-resolution.md\n\nFINAL APPROACH: Store SourceInfo as Lua table (not userdata)\n\nWhy not userdata?\n- In Pandoc, userdata = AST nodes. Filters may use type(x)=='userdata' to identify elements.\n- Using userdata for non-AST data could cause Pandoc compatibility issues.\n\nWhy not thread-local IDs? \n- If diagnostic entries are serialized, IDs become meaningless.\n\nSolution: Serialize SourceInfo to plain Lua table, deserialize on extraction.\n\nLua table format:\n { t = 'Original', file_id = 0, start_offset = 42, end_offset = 55 }\n { t = 'Substring', parent = {...}, start_offset = 10, end_offset = 20 }\n { t = 'FilterProvenance', filter_path = '...', line = 42 }\n\nChanges needed in diagnostics.rs:\n1. Add source_info_to_lua_table() and source_info_from_lua_table()\n2. Update add_diagnostic() to store serialized SourceInfo\n3. Update extract_lua_diagnostics() to deserialize and pass to builder\n4. Remove obsolete resolution functions\n\nBenefits:\n- No SourceContext needed in Lua\n- Pure Lua tables (Pandoc-compatible)\n- Serialization-safe\n- Resolution stays in Rust","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-03T15:58:47.930405Z","updated_at":"2025-12-03T16:57:39.450950Z","closed_at":"2025-12-03T16:57:39.450950Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-481","depends_on_id":"k-480","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-482","title":"LuaRuntime trait definition and module structure","description":"Create the runtime abstraction layer module structure and trait definition:\n- Create lua/runtime/ module with mod.rs, traits.rs\n- Define LuaRuntime trait with all methods from design doc\n- Define supporting types (RuntimeResult, RuntimeError, PathKind, PathMetadata, CommandOutput, XdgDirKind, TempDir)\n- Re-export from lua/runtime/mod.rs\n\nDesign doc: claude-notes/plans/2025-12-03-lua-runtime-abstraction-layer.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-03T19:15:56.414019Z","updated_at":"2025-12-03T19:25:57.044049Z","closed_at":"2025-12-03T19:25:57.044049Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-482","depends_on_id":"k-475","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-483","title":"Implement NativeRuntime for Lua filters","description":"Implement NativeRuntime in lua/runtime/native.rs:\n- Use std::fs for file operations\n- Use std::process for command execution\n- Use std::env for environment access\n- Implement all LuaRuntime trait methods\n- Add comprehensive tests\n\nThis is the default runtime for native targets with full system access.\n\nDesign doc: claude-notes/plans/2025-12-03-lua-runtime-abstraction-layer.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-03T19:16:03.509818Z","updated_at":"2025-12-03T19:25:58.186288Z","closed_at":"2025-12-03T19:25:58.186288Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-483","depends_on_id":"k-482","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-484","title":"Implement WasmRuntime for browser execution","description":"Implement WasmRuntime in lua/runtime/wasm.rs:\n- Use VirtualFileSystem for file operations (mediabag + in-memory)\n- Return NotSupported for process execution\n- Use fetch() API for network (blocking wrapper)\n- Return empty/None for environment access\n- Return NotSupported for CWD operations\n- Conditional compilation: #[cfg(target_arch = \"wasm32\")]\n\nThis runtime enables Lua filter execution in browser environments.\n\nDesign doc: claude-notes/plans/2025-12-03-lua-runtime-abstraction-layer.md","status":"open","priority":4,"issue_type":"task","created_at":"2025-12-03T19:16:10.892738Z","updated_at":"2025-12-04T14:29:23.938869Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-484","depends_on_id":"k-482","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-485","title":"Implement SandboxedRuntime for untrusted filters","description":"Implement SandboxedRuntime in lua/runtime/sandbox.rs:\n- Decorator pattern wrapping any LuaRuntime\n- SecurityPolicy with Deno-style permission model:\n - allow_read/deny_read with PathPattern\n - allow_write/deny_write with PathPattern\n - allow_net/deny_net for network hosts\n - allow_run/deny_run for programs\n - allow_env/deny_env for environment variables\n - allow_cwd for CWD operations\n - allow_sys for system info\n- Deny takes precedence over allow\n- Detailed error messages (PermissionError)\n- PathPattern with wildcard support\n\nDesign doc: claude-notes/plans/2025-12-03-lua-runtime-abstraction-layer.md","status":"open","priority":4,"issue_type":"task","created_at":"2025-12-03T19:16:21.570538Z","updated_at":"2025-12-04T14:29:29.166127Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-485","depends_on_id":"k-482","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-486","title":"Phase 1: List Infrastructure & Missing Constructors","description":"Complete the element type system:\n- Missing constructors: Cite, Table, TableHead, TableBody, TableFoot, Row, Cell, DefinitionList, LineBlock, Figure, Caption, ListAttributes, Citation\n- List metatable enhancements if needed\n\nPlan: claude-notes/plans/2025-12-02-lua-api-port-plan.md (Phase 1)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-03T19:48:18.855571Z","updated_at":"2025-12-03T20:04:08.541192Z","closed_at":"2025-12-03T20:04:08.541192Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-486","depends_on_id":"k-473","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-487","title":"Phase 2: Core Utility Modules","description":"Essential utilities for most filters:\n- pandoc.utils expansion: blocks_to_inlines, equals, type, sha1, normalize_date\n- pandoc.text: lower, upper, len, sub (Unicode-aware)\n- pandoc.json: decode, encode\n\nPlan: claude-notes/plans/2025-12-02-lua-api-port-plan.md (Phase 2)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-03T19:48:33.315556Z","updated_at":"2025-12-03T22:19:54.038912Z","closed_at":"2025-12-03T22:19:54.038912Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-487","depends_on_id":"k-486","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-488","title":"Phase 3: Runtime Abstraction & System Modules","description":"Cross-platform runtime support:\n- pandoc.path: all path manipulation functions via LuaRuntime\n- pandoc.system: file operations, process execution, environment via LuaRuntime\n- Integration with existing LuaRuntime infrastructure\n\nPlan: claude-notes/plans/2025-12-02-lua-api-port-plan.md (Phase 3)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-03T19:48:34.329264Z","updated_at":"2025-12-03T22:36:56.224766Z","closed_at":"2025-12-03T22:36:56.224766Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-488","depends_on_id":"k-487","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-489","title":"Phase 4: MediaBag & Network","description":"Media and network handling:\n- pandoc.mediabag: all functions (delete, empty, fetch, fill, insert, items, list, lookup, make_data_uri, write)\n- WasmRuntime implementation (conditional)\n\nPlan: claude-notes/plans/2025-12-02-lua-api-port-plan.md (Phase 4)","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-03T19:48:35.834169Z","updated_at":"2025-12-03T22:52:45.423477Z","closed_at":"2025-12-03T22:52:45.423477Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-489","depends_on_id":"k-488","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-49","title":"Update PandocAST to use MetaWithSourceInfo","description":"Update Pandoc struct and related code:\n- Change Pandoc.meta from Meta to MetaWithSourceInfo\n- Update all code that constructs Pandoc instances\n- Update filters that traverse/modify metadata\n- Ensure backward compatibility where possible\n\nThis may touch multiple files (readers, writers, filters).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T14:07:42.175901Z","updated_at":"2025-10-19T16:04:06.866105Z","closed_at":"2025-10-19T16:04:06.866105Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-49","depends_on_id":"k-45","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-49","depends_on_id":"k-48","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-490","title":"Phase 5: Citeproc Integration","description":"Citation processing:\n- pandoc.utils.citeproc: Full document processing\n- pandoc.utils.references: Extract references from doc\n- Integration with quarto-citeproc crate\n\nPlan: claude-notes/plans/2025-12-02-lua-api-port-plan.md (Phase 5)","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-03T19:48:36.751574Z","updated_at":"2025-12-03T19:48:36.751574Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-490","depends_on_id":"k-489","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-491","title":"Phase 6: Reader/Writer","description":"Full API parity:\n- pandoc.read: Format parsing\n- pandoc.write: Format rendering\n- pandoc.template: Template processing\n- pandoc.layout: Custom writer support\n- pandoc.zip: Archive handling\n\nPlan: claude-notes/plans/2025-12-02-lua-api-port-plan.md (Phase 6)","notes":"Design plan: claude-notes/plans/2025-12-03-reader-writer-options-design.md\n\nKey decisions to discuss:\n1. Which reader/writer options to implement initially (recommend minimal set)\n2. How to handle format-specific options (store all, implement as needed)\n3. Whether extensions should affect parsing (recommend: no, for now)\n4. Which formats pandoc.read/write should support (qmd, json, html initially)","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-03T19:48:38.265989Z","updated_at":"2025-12-03T23:07:51.384615Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-491","depends_on_id":"k-490","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-492","title":"Phase 7: Template, Layout & Zip","description":"Advanced utilities:\n- pandoc.template: Template processing\n- pandoc.layout: Custom writer support\n- pandoc.zip: Archive handling\n\nPlan: claude-notes/plans/2025-12-02-lua-api-port-plan.md","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-03T22:59:12.611465Z","updated_at":"2025-12-03T22:59:12.611465Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-492","depends_on_id":"k-491","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-4csc","title":"Plan: Lua filter integration tests for types.rs coverage","description":"Plan document: claude-notes/plans/2026-01-02-lua-types-integration-tests.md\n\nSession baseline: 75.81% overall, lua/types.rs at 44.56%\n\nPlan covers 7 phases of integration tests targeting ~680 lines, estimated to improve types.rs coverage to ~78%.","status":"in_progress","priority":2,"issue_type":"task","created_at":"2026-01-02T20:26:38.023302Z","updated_at":"2026-01-02T20:33:29.866817Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-4csc","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-4wex","title":"quarto-hub MVP: automerge-based collaborative infrastructure","description":"Create a new crate 'quarto-hub' that produces a binary called 'hub' with library exports. Implements automerge-based collaborative editing infrastructure with shared state web server, directory management with lockfiles, and file persistence.","status":"in_progress","priority":1,"issue_type":"feature","created_at":"2025-12-08T19:06:57.634484Z","updated_at":"2025-12-08T20:02:35.709646Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-4xqi","title":"Phase 6: Non-Native Formats (Pandoc Integration)","description":"REVISED: Support formats requiring Pandoc. Pandoc invocation layer (emit JSON, call with --from json), Lua filter integration, PDF recipe with latexmk, DOCX/EPUB via Pandoc. Part of k-xlko.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-12-20T17:42:27.680303Z","updated_at":"2025-12-20T18:10:00.065583Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-4xqi","depends_on_id":"k-b1x1","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-4xqi","depends_on_id":"k-xlko","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-5","title":"Replace ErrorCollector usage in src/readers/qmd.rs with DiagnosticCollector","description":"Update qmd.rs to use DiagnosticCollector instead of TextErrorCollector and JsonErrorCollector. The logic needs to change: instead of creating different collectors for JSON vs text, use single DiagnosticCollector and call to_json() or to_text() based on format.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:29:00.576583Z","updated_at":"2025-10-18T20:29:40.921902Z","closed_at":"2025-10-18T20:29:40.921902Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-50","title":"Add deeply nested YAML serialization roundtrip test","description":"Create test to observe serialization behavior:\n1. Create .qmd with deeply nested YAML (5+ levels)\n2. Parse to PandocAST with MetaWithSourceInfo\n3. Serialize to JSON\n4. Measure JSON size and analyze duplication\n5. Deserialize back to PandocAST\n6. Verify SourceInfo functionality (offsets, file resolution)\n7. Document findings\n\nThis validates the approach and observes the serialization blowup problem in real usage.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T14:07:44.439461Z","updated_at":"2025-10-19T18:35:07.223867Z","closed_at":"2025-10-19T18:35:07.223867Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-50","depends_on_id":"k-45","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-50","depends_on_id":"k-49","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-50","depends_on_id":"k-51","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-51","title":"Add Serialize/Deserialize to Inline and Block types","description":"Add #[derive(Serialize, Deserialize)] to:\\n- Inline enum in pandoc/inline.rs\\n- Block enum in pandoc/block.rs\\n- All their nested struct types\\n\\nThis is needed for:\\n- k-50 (serialization roundtrip test)\\n- Full JSON serialization of MetaValueWithSourceInfo\\n\\nThis is part of Phase 3 work (systematic migration).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T14:13:31.211553Z","updated_at":"2025-10-19T14:30:13.120375Z","closed_at":"2025-10-19T14:30:13.120375Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-52","title":"Add consuming methods to YamlWithSourceInfo","description":"Add methods to YamlWithSourceInfo that consume self and return owned values:\n- into_array() -> Option<(Vec, SourceInfo)>\n- into_hash() -> Option<(Vec, SourceInfo)>\n\nThis eliminates unnecessary clones when transforming YamlWithSourceInfo to other types.\n\nFile: crates/quarto-yaml/src/yaml_with_source_info.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T15:26:19.988076Z","updated_at":"2025-10-19T15:27:03.395761Z","closed_at":"2025-10-19T15:27:03.395761Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-53","title":"Refactor yaml_to_meta_with_source_info to take ownership","description":"Change yaml_to_meta_with_source_info to take YamlWithSourceInfo by value instead of reference:\n- Change signature: yaml: YamlWithSourceInfo (not &YamlWithSourceInfo)\n- Use destructuring and pattern matching on owned values\n- Use into_array() and into_hash() consuming methods\n- Eliminate all unnecessary clone() calls\n- Update caller in rawblock_to_meta_with_source_info to pass by value\n\nFile: crates/quarto-markdown-pandoc/src/pandoc/meta.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T15:26:27.817775Z","updated_at":"2025-10-19T15:28:28.405622Z","closed_at":"2025-10-19T15:28:28.405622Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-53","depends_on_id":"k-52","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-54","title":"Unify 'l' and 's' source tracking keys in JSON format","description":"Currently JSON output uses 'l' for old SourceInfo (Blocks/Inlines) and 's' for new quarto_source_map::SourceInfo (Metadata). These should be unified once we fix the serialization storage problems. Both serve the same purpose - tracking source location.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-19T16:02:07.609948Z","updated_at":"2025-10-20T20:32:57.307896Z","closed_at":"2025-10-20T20:32:57.307896Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-54","depends_on_id":"k-35","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-54","depends_on_id":"k-49","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-55","title":"Fix incorrect source tracking in JSON 's' metadata fields","description":"The 's' field in JSON metadata output shows all-zero ranges (offset:0, row:0, col:0) instead of actual source locations. Test case: tests/snapshots/json/002.qmd where title:'metadata1' should point to line 2, offset 7-16, but shows 0-0. Root cause investigation needed: check if quarto-yaml is producing correct SourceInfo, or if yaml_to_meta_with_source_info is losing it.","notes":"ROOT CAUSE FOUND:\nIn qmd.rs lines 190-242, the metadata flow loses source info:\n1. rawblock_to_meta_with_source_info() gets correct SourceInfo from quarto-yaml ✓\n2. Line 190: .to_meta() converts to old Meta type, LOSING all source info ✗ \n3. parse_metadata_strings() parses markdown (works on old Meta type)\n4. Lines 212/240: meta_from_legacy() converts back using SourceInfo::default() ✗\n\nFIX PLAN:\nCreate parse_metadata_strings_with_source_info() that:\n- Takes MetaValueWithSourceInfo instead of MetaValue\n- Preserves SourceInfo when parsing strings as markdown\n- When parsing 'title: metadata1' as markdown, creates Substring SourceInfo for the inline content\n- Returns MetaValueWithSourceInfo\n\nThis requires updating the markdown parsing to accept a parent SourceInfo parameter.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-19T16:03:16.819879Z","updated_at":"2025-10-19T16:11:33.697790Z","closed_at":"2025-10-19T16:11:33.697790Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-55","depends_on_id":"k-49","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-56","title":"quarto-yaml: Fix key_span tracking to use Substring instead of Original","description":"quarto-yaml currently returns key_span as an Original SourceInfo with offset 0, when it should return a Substring SourceInfo pointing to the actual location of the key in the file.\n\nTest: test_metadata_source_tracking_002_qmd now fails with:\n assertion failed: Key 'title' should start at file offset 4\n left: 0\n right: 4\n\nThe key 'title' in 002.qmd should have offset 4 (start of frontmatter content), not 0.\n\nThis affects metadata key source tracking in PandocAST.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-19T16:52:12.408812Z","updated_at":"2025-10-19T17:53:13.554596Z","closed_at":"2025-10-19T17:53:13.554596Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-57","title":"Implement SourceInfo pool serialization (writer)","description":"Implement the writer side of pool-based SourceInfo serialization.\n\nTasks:\n- Create SerializableSourceInfo and SerializableSourceMapping types\n- Implement SourceInfoSerializer with intern() method\n- Update all write_* functions to use serializer\n- Update write_pandoc to build pool and add to astContext\n\nFiles: crates/quarto-markdown-pandoc/src/writers/json.rs\n\nSee: claude-notes/plans/2025-10-19-sourceinfo-pool-serialization.md Phase 1","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T19:08:00.063620Z","updated_at":"2025-10-19T19:15:45.496951Z","closed_at":"2025-10-19T19:15:45.496951Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-57","depends_on_id":"k-44","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-58","title":"Implement SourceInfo pool deserialization (reader)","description":"Implement the reader side of pool-based SourceInfo deserialization.\n\nTasks:\n- Create SourceInfoDeserializer that builds pool from JSON\n- Implement from_json_ref() to resolve $ref IDs\n- Update all read_* functions to use deserializer\n- Update read_pandoc to extract pool and create deserializer\n\nFiles: crates/quarto-markdown-pandoc/src/readers/json.rs\n\nSee: claude-notes/plans/2025-10-19-sourceinfo-pool-serialization.md Phase 2","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T19:08:05.886463Z","updated_at":"2025-11-21T21:18:15.209080Z","closed_at":"2025-11-21T21:18:15.209080Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-58","depends_on_id":"k-57","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-59","title":"Add error handling for SourceInfo pool serialization","description":"Add error types and handling for pool-based serialization.\n\nTasks:\n- Add InvalidSourceInfoRef error variant\n- Add ExpectedSourceInfoRef error variant\n- Add MalformedSourceInfoPool error variant\n- Add CircularSourceInfoReference error variant\n\nFiles: crates/quarto-markdown-pandoc/src/readers/json.rs\n\nSee: claude-notes/plans/2025-10-19-sourceinfo-pool-serialization.md Phase 3","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T19:08:11.499185Z","updated_at":"2025-11-21T22:50:54.809108Z","closed_at":"2025-11-21T22:50:54.809108Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-59","depends_on_id":"k-58","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-5a26","title":"Phase 3: Materialization and error handling","description":"Implement MaterializeOptions, materialize(), depth-limited materialization. Implement merge_with_diagnostics() for layer validation. Q-1-27 for nesting too deep. Tests for depth limits and error collection. Plan: claude-notes/plans/2025-12-07-config-merging-design.md Phase 3","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T20:03:50.953029Z","updated_at":"2025-12-07T20:25:57.601925Z","closed_at":"2025-12-07T20:25:57.601925Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-5a26","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-5hu5","title":"Fix cargo clippy warnings","description":"Pre-existing clippy warnings to clean up: collapsed if statements, write! with newlines, Option.and_then patterns","status":"open","priority":3,"issue_type":"chore","created_at":"2025-12-31T23:25:12.290518Z","updated_at":"2025-12-31T23:25:12.290518Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-5u7d","title":"Phase 3: Library API for template rendering","description":"Expose clean public API: render_with_bundle (always available), render_with_template_file (feature-gated behind template-fs), and render_with_resolver (generic over PartialResolver).","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T17:44:23.422676Z","updated_at":"2025-12-05T17:54:10.567791Z","closed_at":"2025-12-05T17:54:10.567791Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-5u7d","depends_on_id":"k-u1iy","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-5u7d","depends_on_id":"k-y2f3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-5ywq","title":"Unify filter CLI: single --filter option with citeproc support","description":"Replace separate --json-filter and --lua-filter options with a single -F/--filter option that supports ordering across filter types. Add citeproc as a built-in filter.\n\nPlan: claude-notes/plans/2025-12-05-unified-filter-cli.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-05T21:44:16.194801Z","updated_at":"2025-12-05T22:12:23.959817Z","closed_at":"2025-12-05T22:12:23.959817Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-5zv5","title":"Template diagnostics have incorrect file_id attribution","description":"Template warnings (e.g., undefined variable warnings from built-in HTML template) are incorrectly attributed to the .qmd file instead of the template file. The root cause is that quarto-doctemplate creates its own independent SourceContext during parsing, assigning file_id 0 to the template file. When these diagnostics are reported, the main program interprets file_id 0 using its own SourceContext where file_id 0 is the .qmd file.\n\nPlan document: claude-notes/plans/2025-12-06-template-file-id-bug.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-06T16:52:05.264739Z","updated_at":"2025-12-06T17:31:05.489645Z","closed_at":"2025-12-06T17:31:05.489645Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-6","title":"Update treesitter_to_pandoc signature to use DiagnosticCollector","description":"Change function signature from generic ErrorCollector trait to concrete DiagnosticCollector type in src/pandoc/treesitter.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:29:01.548909Z","updated_at":"2025-10-18T20:30:15.033025Z","closed_at":"2025-10-18T20:30:15.033025Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-6","depends_on_id":"k-12","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-6","depends_on_id":"k-2","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-6","depends_on_id":"k-3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-6","depends_on_id":"k-4","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-60","title":"Test and validate SourceInfo pool serialization","description":"Add comprehensive tests for pool-based serialization.\n\nTasks:\n- Add unit tests for SourceInfoSerializer (6 tests)\n- Add unit tests for SourceInfoDeserializer (4 tests)\n- Verify existing roundtrip tests pass\n- Update metadata source tracking test\n- Update nested YAML serialization tests with pool verification\n- Update all JSON snapshots\n\nFiles: \n- crates/quarto-markdown-pandoc/src/writers/json.rs (tests)\n- crates/quarto-markdown-pandoc/src/readers/json.rs (tests)\n- crates/quarto-markdown-pandoc/tests/test_json_roundtrip.rs\n- crates/quarto-markdown-pandoc/tests/test_metadata_source_tracking.rs\n- crates/quarto-markdown-pandoc/tests/test_nested_yaml_serialization.rs\n- crates/quarto-markdown-pandoc/tests/snapshots/json/*.snapshot\n\nSee: claude-notes/plans/2025-10-19-sourceinfo-pool-serialization.md Phase 4","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T19:08:19.728117Z","updated_at":"2025-11-21T22:58:27.168763Z","closed_at":"2025-11-21T22:58:27.168763Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-60","depends_on_id":"k-59","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-61","title":"Document SourceInfo pool serialization implementation","description":"Add documentation for the pool-based serialization approach.\n\nTasks:\n- Add comprehensive code comments to SourceInfoSerializer\n- Add comprehensive code comments to SourceInfoDeserializer\n- Update design doc with implementation notes and learnings\n- Document the JSON format in both writer and reader\n\nFiles:\n- crates/quarto-markdown-pandoc/src/writers/json.rs\n- crates/quarto-markdown-pandoc/src/readers/json.rs\n- claude-notes/sourceinfo-serialization-optimization-design.md\n\nSee: claude-notes/plans/2025-10-19-sourceinfo-pool-serialization.md Phase 5","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-19T19:08:26.866955Z","updated_at":"2025-11-21T23:30:14.960862Z","closed_at":"2025-11-21T23:30:14.960862Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-61","depends_on_id":"k-60","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-62","title":"YAML tag information lost in new API with source tracking","description":"The old rawblock_to_meta API preserves YAML tag information (\\!path, \\!glob, \\!str) and wraps tagged strings in Spans with class 'yaml-tagged-string'. The new rawblock_to_meta_with_source_info API loses this information because quarto-yaml doesn't track tags. This prevents removal of the legacy API and causes test_yaml_tagged_strings to fail when migrated to new API.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-20T14:19:18.041940Z","updated_at":"2025-10-20T14:35:15.084731Z","closed_at":"2025-10-20T14:35:15.084731Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-63","title":"Phase 3: Complete systematic migration of all AST types to use quarto-source-map","description":"Complete the systematic migration from pandoc::location::SourceInfo to quarto_source_map::SourceInfo across all AST types.\n\nCurrent state:\n- Infrastructure completed (Phase 1, 2)\n- A few structs have source_info_qsm fields (Str, HorizontalRule from proof-of-concept)\n- Most AST types still use old pandoc::location::SourceInfo\n\nTasks:\n1. Audit all AST struct definitions to find which have source_info fields\n2. Add source_info_qsm: Option to all remaining structs\n3. Update all parsing code to populate both fields during transition\n4. Add Span struct to have source_info_qsm field (discovered during k-62)\n5. Once all populated, rename source_info_qsm -> source_info and remove old fields\n6. Remove pandoc::location module entirely\n7. Update all imports and type references\n8. Run full test suite\n\nSee: claude-notes/quarto-source-map-integration-plan.md Phase 3","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T14:59:34.894007Z","updated_at":"2025-10-20T18:08:15.349955Z","closed_at":"2025-10-20T18:08:15.349955Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-63","depends_on_id":"k-27","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-64","title":"Audit all AST structs and create migration checklist","description":"Identify all structs that need source_info_qsm field added. Create comprehensive list of:\n- All Inline types in inline.rs that need migration\n- All Block types in block.rs that need migration\n- Any other types with source_info fields\n\nDocument current state: 2/42 structs have source_info_qsm (Str, HorizontalRule)","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T15:03:40.111289Z","updated_at":"2025-10-20T15:15:58.737432Z","closed_at":"2025-10-20T15:15:58.737432Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-64","depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-65","title":"Add source_info_qsm to all Inline types in inline.rs","description":"Add 'pub source_info_qsm: Option' field to all Inline types that don't have it yet.\n\nInline types to update (based on grep results):\n- Emph, Underline, Strong, Strikeout, Superscript, Subscript\n- SmallCaps, Quoted, Cite, Code, Space, SoftBreak, LineBreak\n- Math, RawInline, Link, Image, Note, Span, Shortcode\n- (Str already has it)\n\nEnsure all types have the field added with Option<> wrapper.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T15:03:48.030737Z","updated_at":"2025-10-20T15:33:20.994543Z","closed_at":"2025-10-20T15:33:20.994543Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-65","depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-65","depends_on_id":"k-64","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-66","title":"Add source_info_qsm to all Block types in block.rs","description":"Add 'pub source_info_qsm: Option' field to all Block types that don't have it yet.\n\nBlock types to update (based on grep results):\n- Plain, Para, LineBlock, CodeBlock, RawBlock, BlockQuote\n- OrderedList, BulletList, DefinitionList, Header, Div, Table\n- Figure, Caption, TableHead, TableBody, TableFoot, Row, Cell\n- (HorizontalRule already has it)\n\nEnsure all types have the field added with Option<> wrapper.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T15:03:55.330281Z","updated_at":"2025-10-20T15:33:21.009695Z","closed_at":"2025-10-20T15:33:21.009695Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-66","depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-66","depends_on_id":"k-64","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-67","title":"Update all parsing code to populate both source_info fields","description":"Update all parsing code across all modules to populate both source_info and source_info_qsm fields.\n\nFor each struct construction:\n- Keep existing source_info using pandoc::location::SourceInfo\n- Add source_info_qsm using node_to_source_info_with_context() from source_map_compat.rs\n\nThis ensures gradual migration without breaking existing code.\n\nFiles to update: All readers/treesitter/*.rs parsing modules","notes":"Current: 141 missing field errors. Sub-tasks created: k-72 through k-77. See phase3-sourceinfo-migration-guide.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T15:04:03.558959Z","updated_at":"2025-10-20T16:21:55.811406Z","closed_at":"2025-10-20T16:21:55.811406Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-67","depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-67","depends_on_id":"k-65","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-67","depends_on_id":"k-66","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-68","title":"Test that all source locations are preserved","description":"Verify that source location tracking works correctly after migration.\n\nTests:\n- Run existing test suite (all should pass)\n- Verify source_info_qsm fields are populated correctly\n- Spot check a few parsing modules to ensure locations match\n- Test inline location tracking\n- Test block location tracking\n\nThis validates the dual-field approach before switchover.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T15:04:10.636767Z","updated_at":"2025-10-20T16:26:25.717196Z","closed_at":"2025-10-20T16:26:25.717196Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-68","depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-68","depends_on_id":"k-67","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-684e","title":"Jupyter engine: Production readiness","description":"Bring Jupyter engine from MVP to production readiness. MVP is complete with kernelspec discovery, kernel lifecycle, execute/reply, output conversion, AST transform, daemon persistence, and inline expressions. Remaining work includes: chunk options, language setup code, timeout/interrupt, error recovery, figure improvements, pipeline integration. See plan: claude-notes/plans/2026-01-07-jupyter-engine-remaining-work.md","status":"open","priority":2,"issue_type":"feature","created_at":"2026-01-07T19:26:49.679024272Z","updated_at":"2026-01-07T19:26:49.679024272Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-69","title":"Replace source_info with source_info_qsm throughout","description":"Final switchover from old to new SourceInfo type.\n\nTasks:\n- Remove 'pub source_info: SourceInfo' (pandoc::location) from all structs\n- Rename 'pub source_info_qsm' to 'pub source_info' everywhere\n- Update all field access from .source_info_qsm to .source_info\n- Update serialization derives if needed\n- This is the breaking change that completes the migration","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T15:04:18.157380Z","updated_at":"2025-10-20T17:52:21.024388Z","closed_at":"2025-10-20T17:52:21.024388Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-69","depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-69","depends_on_id":"k-68","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-6cza","title":"Add 'import' subcommand to quarto-hub binary","description":"Add an 'import' subcommand to the hub binary that allows users to clone a collaborative Quarto project from a sync server. Given an index document ID and sync server URL, this command should:\n\n1. Create the target directory (if needed)\n2. Set up the .quarto/hub/ infrastructure\n3. Connect to the sync server\n4. Fetch the index document\n5. Fetch all file documents referenced in the index\n6. Write file contents to disk\n7. Configure hub.json with the index ID and peer URL\n8. Initialize sync state\n\n**Design decisions (approved)**:\n- No partial imports: fail entirely if any document fails\n- No timeout: wait indefinitely with interactive progress feedback\n- Separate commands: users run 'hub import' then 'hub serve'\n\nSee plan: claude-notes/plans/2025-01-05-hub-import-subcommand.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-01-05T23:23:15.193952Z","updated_at":"2026-01-05T23:34:49.291138Z","closed_at":"2026-01-05T23:34:49.291138Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-6daf","title":"Good source location tracking of document after engine outputs","description":"After engine execution (Jupyter, knitr, etc), the pipeline has two PandocAST structs: the pre-engine AST with source locations pointing to the original qmd, and the post-engine AST with locations pointing to intermediate engine output files. We need a tree-diffing algorithm to reconcile these ASTs, transferring original source locations to unchanged elements while keeping new locations for elements that changed (code execution outputs).\n\nPlan: claude-notes/plans/2025-12-15-engine-output-source-location-reconciliation.md\nRelated: claude-notes/plans/2025-12-15-source-info-for-structured-formats.md","status":"open","priority":1,"issue_type":"feature","created_at":"2025-12-15T21:53:21.187508Z","updated_at":"2025-12-15T21:54:35.598252Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-6qau","title":"Phase 1: Foundation MVP - Single document HTML rendering","description":"REVISED: Render single .qmd to HTML without calling Pandoc. Uses pampa for parsing and quarto-doctemplate for HTML output. Includes: ProjectContext detection, DependencyCollector skeleton, basic file copying. Deliverable: 'cargo run -- render simple.qmd' produces basic HTML. Part of k-xlko.","status":"in_progress","priority":1,"issue_type":"feature","created_at":"2025-12-20T17:42:21.793580Z","updated_at":"2025-12-21T16:30:54.707146Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-6qau","depends_on_id":"k-xlko","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-6wjz","title":"Improve coverage for quarto-yaml-validation/validator.rs","description":"Session baseline: 69.62% line coverage, validator.rs: 42.18%. Working on improving coverage.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-31T16:02:09.631523Z","updated_at":"2025-12-31T17:57:18.729364Z","closed_at":"2025-12-31T17:57:18.729364Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-6wjz","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-6zaq","title":"Rename LuaRuntime to SystemRuntime and unify runtime abstraction","description":"Rename the LuaRuntime trait to SystemRuntime and move it to a shared location so it can be used by both pampa (for Lua filters) and quarto-core (for filesystem abstraction). This eliminates the need for a separate QuartoRuntime trait.\n\nPlan: claude-notes/plans/2025-12-22-system-runtime-unification.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-22T23:20:10.017439Z","updated_at":"2025-12-23T00:52:26.137510Z","closed_at":"2025-12-23T00:52:26.137510Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-6zaq","depends_on_id":"k-nkhl","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-7","title":"Update postprocess function to use DiagnosticCollector","description":"Change postprocess function signature from generic ErrorCollector trait to concrete DiagnosticCollector type in src/pandoc/treesitter_utils/postprocess.rs","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:29:02.832735Z","updated_at":"2025-10-18T20:30:37.920982Z","closed_at":"2025-10-18T20:30:37.920982Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-7","depends_on_id":"k-12","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-70","title":"Remove pandoc::location module","description":"Delete the old pandoc::location module after migration is complete.\n\nTasks:\n- Remove src/pandoc/location.rs file\n- Remove 'pub mod location;' from src/pandoc/mod.rs\n- Remove any remaining imports of pandoc::location types\n- Remove source_map_compat.rs (temporary bridge module)\n- Verify no references remain to old Location, Range, SourceInfo types\n- Run cargo check to ensure clean compilation","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T15:04:26.832490Z","updated_at":"2025-10-20T18:25:36.442096Z","closed_at":"2025-10-20T18:25:36.442096Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-70","depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-70","depends_on_id":"k-69","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-71","title":"Run full test suite after migration complete","description":"Final validation that migration is complete and correct.\n\nTasks:\n- cargo test --package quarto-markdown-pandoc (all tests must pass)\n- cargo test --workspace (verify no breakage in other crates)\n- Verify all source location tracking still works\n- Check that error messages show correct locations\n- Document any remaining work or known issues\n\nSuccess criteria: All tests pass, no compilation errors, source tracking functional.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T15:04:34.574239Z","updated_at":"2025-10-20T20:01:18.681793Z","closed_at":"2025-10-20T20:01:18.681793Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-71","depends_on_id":"k-63","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-71","depends_on_id":"k-70","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-72","title":"Step 2.1: Fix filters.rs struct constructions","description":"Add source_info_qsm: None to all struct initializers in filters.rs.\n\nCommon patterns:\n- Inline::Note(pandoc::Note { content, source_info: self.source_info })\n- Inline::Cite(pandoc::Cite { citations, content, source_info: self.source_info })\n- Block::BlockMetadata(MetaBlock { meta, source_info })\n\nEstimated: 20-30 struct constructions","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T15:37:46.202350Z","updated_at":"2025-10-20T15:43:44.018029Z","closed_at":"2025-10-20T15:43:44.018029Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-72","depends_on_id":"k-65","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-72","depends_on_id":"k-66","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-72","depends_on_id":"k-67","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-73","title":"Step 2.2: Fix pandoc/treesitter.rs struct constructions","description":"Add source_info_qsm: None to all Str, Space, LineBreak, SoftBreak, RawInline constructions in pandoc/treesitter.rs.\n\nPattern: Inline::Str(Str { text, source_info: node_source_info(node) })\n\nEstimated: 10-15 struct constructions","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T15:37:53.022731Z","updated_at":"2025-10-20T15:45:41.347372Z","closed_at":"2025-10-20T15:45:41.347372Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-73","depends_on_id":"k-67","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-73","depends_on_id":"k-72","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-74","title":"Step 2.3: Fix treesitter_utils/ parsing files (Priority 1)","description":"Add source_info_qsm: None to struct constructions in core parsing files.\n\nFiles to fix (in order):\n1. atx_heading.rs - Header\n2. setext_heading.rs - Header\n3. code_span.rs - Code\n4. fenced_code_block.rs - CodeBlock\n5. indented_code_block.rs - CodeBlock\n6. block_quote.rs - BlockQuote\n7. quoted_span.rs - Quoted\n8. inline_link.rs - Link\n9. image.rs - Image, Link\n10. citation.rs - Cite\n\nEstimated: 30-40 struct constructions total","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T15:38:01.113205Z","updated_at":"2025-10-20T16:21:57.363200Z","closed_at":"2025-10-20T16:21:57.363200Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-74","depends_on_id":"k-67","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-74","depends_on_id":"k-72","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-75","title":"Step 2.4: Fix treesitter_utils/ remaining files (Priority 2)","description":"Add source_info_qsm: None to struct constructions in remaining treesitter_utils files.\n\nFiles:\n- note_definition_para.rs - NoteDefinitionPara\n- note_definition_fenced_block.rs - NoteDefinitionFencedBlock\n- fenced_div_block.rs - Div\n- editorial_marks.rs - Insert, Delete, Highlight, EditComment\n- latex_span.rs - Math, RawInline\n- caption.rs - CaptionBlock\n- pipe_table.rs - Table\n- document.rs - various\n\nEstimated: 30-40 constructions","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T15:38:09.595489Z","updated_at":"2025-10-20T16:21:58.983699Z","closed_at":"2025-10-20T16:21:58.983699Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-75","depends_on_id":"k-67","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-75","depends_on_id":"k-74","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-76","title":"Step 2.5: Fix pandoc/meta.rs and other pandoc/ files","description":"Add source_info_qsm: None to struct constructions in meta.rs and other pandoc core files.\n\nFiles:\n- pandoc/meta.rs - MetaBlock constructions\n- pandoc/inline.rs - helper functions (make_span_inline, make_cite_inline, etc)\n- pandoc/block.rs - helper functions (make_block_leftover, etc)\n- pandoc/shortcode.rs - if any\n\nEstimated: 20-30 constructions","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T15:38:18.965689Z","updated_at":"2025-10-20T16:22:00.516003Z","closed_at":"2025-10-20T16:22:00.516003Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-76","depends_on_id":"k-67","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-76","depends_on_id":"k-73","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-77","title":"Step 2.6: Fix readers/ and writers/ files","description":"Add source_info_qsm: None to struct constructions in readers and writers.\n\nFiles:\n- readers/json.rs - Deserialization (many structs)\n- readers/qmd.rs - if any\n- writers/qmd.rs - if any\n- writers/json.rs - may already be correct (uses serialization)\n\nEstimated: 20-30 constructions\n\nAfter this, run: cargo check --package quarto-markdown-pandoc\nShould see 0 errors.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T15:38:26.830653Z","updated_at":"2025-10-20T16:22:02.172140Z","closed_at":"2025-10-20T16:22:02.172140Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-77","depends_on_id":"k-67","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-77","depends_on_id":"k-75","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-77","depends_on_id":"k-76","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-78","title":"Implement SourceLocation trait for new quarto_source_map::SourceInfo","description":"The old SourceLocation trait (filename_index(), range()) is incompatible with new quarto_source_map::SourceInfo structure. Need to either: 1) Update trait to work with new type, 2) Remove trait and update JSON writer, or 3) Create compat layer. Blocking k-69 completion.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-20T16:40:28.023905Z","updated_at":"2025-10-20T19:32:35.332457Z","closed_at":"2025-10-20T19:32:35.332457Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-78","depends_on_id":"k-69","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-79","title":"k-69 Part 2: Update function signatures to use quarto_source_map::SourceInfo","description":"Update helper function signatures that currently take old location::SourceInfo parameter (e.g., make_span_inline, etc.). Convert between old/new types at boundaries where needed. Fix ~126 type mismatch errors.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-20T16:44:32.928647Z","updated_at":"2025-10-20T17:44:48.351038Z","closed_at":"2025-10-20T17:44:48.351038Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-79","depends_on_id":"k-69","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-7bty","title":"Implement metadata-level reconciliation for YAML front matter","description":"Currently, AST reconciliation uses a simple rule: if metadata changes, the executed metadata wins entirely. A future enhancement would reconcile metadata at the mapping level, preserving source locations for unchanged fields while updating changed ones. This would involve: (1) For MetaMap: reconcile each key-value pair; (2) For MetaList: align items similar to block alignment; (3) For scalar values: exact match or replace. Related to structural hash reconciliation design.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-12-18T00:09:59.702600Z","updated_at":"2025-12-18T00:09:59.702600Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-7bty","depends_on_id":"k-xvte","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-7r7z","title":"Improve coverage: quarto-core/src/template.rs","description":"Session baseline: 73.73% line coverage. File at 60.04%. Focus on render functions, metadata conversion, inlines/blocks to text.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T17:06:44.093672Z","updated_at":"2026-01-02T17:15:32.791569Z","closed_at":"2026-01-02T17:15:32.791569Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-7r7z","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-7srl","title":"Improve coverage: pampa/src/pandoc/shortcode.rs","description":"Session baseline: 72.69% line coverage. Target: beat baseline by adding tests for shortcode_to_span function branches.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T15:31:01.650013Z","updated_at":"2026-01-02T15:35:57.964195Z","closed_at":"2026-01-02T15:35:57.964195Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-7srl","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-7y5r","title":"Improve coverage for quarto-pandoc-types/reconcile module","description":"Session baseline: 70.44% line coverage. hash.rs: 36.48%, types.rs: 32.00%, apply.rs: 48.27%, compute.rs: 60.79%.","status":"in_progress","priority":2,"issue_type":"task","created_at":"2025-12-31T16:02:10.572005Z","updated_at":"2025-12-31T18:04:56.711244Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-7y5r","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-8","title":"Update test files to use DiagnosticCollector","description":"Update tests/test.rs and tests/test_inline_locations.rs to use DiagnosticCollector instead of TextErrorCollector","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:29:04.145707Z","updated_at":"2025-10-18T20:31:12.689417Z","closed_at":"2025-10-18T20:31:12.689417Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-80","title":"k-69 Part 3: Update imports to use new SourceInfo type","description":"Replace 'use crate::pandoc::location::SourceInfo' imports with new type. Remove unused imports of old location types (node_source_info_with_context, etc.).","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-20T16:44:34.645643Z","updated_at":"2025-10-20T17:44:56.135319Z","closed_at":"2025-10-20T17:44:56.135319Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-80","depends_on_id":"k-69","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-81","title":"k-69 Part 4: Verify compilation and tests","description":"Run cargo check (0 errors), run cargo test (all passing). Fix any remaining issues.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-20T16:44:36.260697Z","updated_at":"2025-10-20T17:51:06.884202Z","closed_at":"2025-10-20T17:51:06.884202Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-81","depends_on_id":"k-69","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-82","title":"Implement combine() method for quarto_source_map::SourceInfo","description":"The merge_strs function in postprocess.rs needs a combine() method to merge source info when concatenating strings. Currently commented out at line 755-758. This method should combine two SourceInfo objects, similar to how location::SourceInfo::combine() worked.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-20T17:38:55.993474Z","updated_at":"2025-10-20T19:40:01.368890Z","closed_at":"2025-10-20T19:40:01.368890Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-82","depends_on_id":"k-69","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-83","title":"k-70 Step 1: Remove SourceLocation trait and update JSON writer","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-20T18:09:16.465787Z","updated_at":"2025-10-20T18:13:23.311889Z","closed_at":"2025-10-20T18:13:23.311889Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-83","depends_on_id":"k-70","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-84","title":"k-70 Step 2: Replace old Range/Location types with quarto_source_map types","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-20T18:09:21.933957Z","updated_at":"2025-10-20T18:21:48.289778Z","closed_at":"2025-10-20T18:21:48.289778Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-84","depends_on_id":"k-70","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-85","title":"k-70 Step 3: Move helper functions and delete location module","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-20T18:09:28.863617Z","updated_at":"2025-10-20T18:25:31.169093Z","closed_at":"2025-10-20T18:25:31.169093Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-85","depends_on_id":"k-70","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-85","depends_on_id":"k-83","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-85","depends_on_id":"k-84","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-86","title":"Fix FileId handling - both branches of context.filenames.is_empty() return FileId(0)","description":"During k-84 migration, introduced a bug where if statements check context.filenames.is_empty() but both branches return FileId(0). The else branch should use the actual filename index from context.\n\nAffected files:\n- src/pandoc/location.rs (node_source_info_with_context)\n- src/pandoc/treesitter.rs (multiple locations)\n- src/pandoc/treesitter_utils/editorial_marks.rs (multiple locations)\n\nThe pattern should be:\nif context.filenames.is_empty() {\n quarto_source_map::FileId(0)\n} else {\n quarto_source_map::FileId(context.current_filename_index or similar)\n}\n\nTasks:\n1. Study how filename indices are tracked in ASTContext\n2. Determine the correct way to get the current filename index\n3. Create test cases that verify filename information is preserved\n4. Fix all instances of this pattern\n5. Verify tests pass and filename information is correct","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-20T18:29:53.798883Z","updated_at":"2025-10-20T18:36:27.383592Z","closed_at":"2025-10-20T18:36:27.383592Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-86","depends_on_id":"k-84","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-87","title":"Audit and fix SourceInfo::default() instances - ensure proper source tracking","description":"There are 43 instances of SourceInfo::default() across the codebase where we're not tracking source locations. Many of these could and should track actual source information from tree-sitter nodes or other sources.\n\nAffected files:\n- src/readers/json.rs\n- src/readers/qmd.rs \n- src/pandoc/treesitter.rs (3 instances)\n- src/pandoc/treesitter_utils/document.rs\n- src/pandoc/treesitter_utils/postprocess.rs\n- src/pandoc/block.rs\n- src/pandoc/inline.rs\n- src/pandoc/meta.rs\n\nTasks:\n1. Audit each SourceInfo::default() instance to determine:\n - Is source location information available from tree-sitter node?\n - Is this data derived from existing AST with source info?\n - Is this a legitimate case where no source info exists (e.g., synthetic nodes)?\n\n2. Categorize instances:\n - Can be fixed: node available, should track location\n - Should propagate: derived from existing AST, should copy/combine source info\n - Legitimate default: synthetic/generated content with no source\n\n3. Create systematic plan to fix trackable instances\n\n4. Fix instances file by file, verifying with tests\n\n5. Document remaining legitimate default() uses with comments explaining why\n\nExpected outcome:\n- Maximum source location tracking throughout AST\n- Better error messages and diagnostics\n- Clear documentation for cases where default() is appropriate","notes":"**2025-11-21 Comprehensive Documentation Audit Complete**\n\nTotal instances: 109 (up from original 43)\n\n**Breakdown:**\n- 55 instances in test files (legitimate)\n- 19 in json.rs (backward compatibility - documented)\n- 19 in meta.rs (legacy conversion + error recovery - documented)\n- 7 in yaml_with_source_info.rs (test code - legitimate)\n- 4 in validation schema (structure errors - documented)\n- 2 in validator.rs (test code - legitimate)\n- 2 in postprocess.rs (1 blocked by k-82, 1 synthetic - documented)\n- 1 in document.rs (legitimate - already documented)\n\n**Documentation Added:**\n1. json.rs: Added module-level comment about backward compatibility\n2. meta.rs: Added inline comments for error recovery spans and legacy conversion\n3. schema/merge.rs: Documented 3 schema structure errors\n4. schema/mod.rs: Documented 1 schema structure error\n\n**Status:**\n- All production code instances are either:\n - Already had documentation (1 instance)\n - Now have documentation (14 instances)\n - Blocked by other work - k-82 (1 instance)\n - Legitimate test code (64 instances)\n\n**Remaining Work:**\n- postprocess.rs:667 - Math+Attr wrapper (blocked by k-82 combine() implementation)\n- meta.rs:449 - yaml-tagged-string Span (TODO added to propagate source info)\n\nAll cargo check and cargo test pass.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-20T18:39:29.142757Z","updated_at":"2025-11-21T21:40:17.413701Z","closed_at":"2025-11-21T21:40:17.413701Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-88","title":"Migrate NoteReference to use SourceInfo instead of Range","description":"NoteReference currently uses the old Range field instead of SourceInfo, which means postprocess.rs can't properly track source info when converting NoteReference -> Span.\n\nCurrent state:\n- NoteReference struct has 'range: Range' field\n- Should have 'source_info: SourceInfo' field instead\n- postprocess.rs:389 has to use default() because no SourceInfo available\n\nFix needed:\n1. Update NoteReference struct to use SourceInfo\n2. Update note_reference.rs parser to set source_info from node\n3. Update postprocess.rs to use note_ref.source_info\n4. Add test to verify NoteReference source tracking\n\nThis is a larger structural migration discovered during k-87 audit.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-20T19:18:26.315377Z","updated_at":"2025-10-20T19:26:24.079640Z","closed_at":"2025-10-20T19:26:24.079640Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-88","depends_on_id":"k-87","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-89","title":"Add UPDATE_SNAPSHOTS environment variable support for snapshot tests","description":"Currently snapshot tests in test.rs require manual updating by regenerating each .snapshot file individually. Add support for UPDATE_SNAPSHOTS=1 environment variable (like insta and other snapshot testing libraries) to automatically update all snapshot files when tests fail.\n\nImplementation:\n- Check for UPDATE_SNAPSHOTS env var in test_snapshots_for_format()\n- When set, write output to snapshot_path instead of comparing\n- Print message indicating snapshots were updated\n\nThis would make it much easier to update snapshots after intentional changes to output format.","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-10-20T19:40:19.374671Z","updated_at":"2025-10-20T19:44:18.877845Z","closed_at":"2025-10-20T19:44:18.877845Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-9","title":"Remove old ErrorCollector trait and implementations","description":"Delete ErrorCollector trait, TextErrorCollector, JsonErrorCollector, and SourceInfo from src/utils/error_collector.rs. Keep the file if needed or remove from mod.rs.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-18T20:29:05.724675Z","updated_at":"2025-10-18T20:31:40.941416Z","closed_at":"2025-10-18T20:31:40.941416Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-9","depends_on_id":"k-8","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-90","title":"Implement tag-based YAML metadata markdown parsing behavior","description":"Change metadata string markdown parsing behavior based on YAML tags: !str/!path emit plain Str nodes, !md fails with error on parse failure, untagged values emit warnings on parse failure. See claude-notes/plans/2025-10-21-yaml-tag-markdown-warning.md for full plan.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-21T13:40:49.635916Z","updated_at":"2025-10-21T18:46:14.689557Z","closed_at":"2025-10-21T18:46:14.689557Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-90","depends_on_id":"k-8","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-91","title":"Thread diagnostic collector through metadata parsing functions","description":"Add diagnostics parameter to yaml_to_meta_with_source_info, parse_metadata_strings_with_source_info, and their callers to enable warning/error emission during metadata parsing","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T13:40:56.989763Z","updated_at":"2025-10-21T13:45:34.411580Z","closed_at":"2025-10-21T13:45:34.411580Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-91","depends_on_id":"k-90","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-92","title":"Implement !str and !path tag behavior (plain Str nodes)","description":"Modify yaml_to_meta_with_source_info to emit plain Str nodes for !str and !path tags without yaml-tagged-string wrapper","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T13:41:03.071741Z","updated_at":"2025-10-21T13:46:54.514894Z","closed_at":"2025-10-21T13:46:54.514894Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-92","depends_on_id":"k-90","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-93","title":"Implement !md tag error on parse failure","description":"When !md tag is present and markdown parsing fails, emit error (not warning) with helpful message","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T13:41:09.383717Z","updated_at":"2025-10-21T13:48:43.584432Z","closed_at":"2025-10-21T13:48:43.584432Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-93","depends_on_id":"k-90","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-94","title":"Emit warning for untagged metadata parse failures","description":"When metadata string fails to parse as markdown and has no tag, emit warning suggesting use of !str or !path tags","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T13:41:18.779796Z","updated_at":"2025-10-21T13:48:43.599576Z","closed_at":"2025-10-21T13:48:43.599576Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-94","depends_on_id":"k-90","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-95","title":"Add tests for tag-based metadata parsing behavior","description":"Create tests for !str/!path plain Str nodes, !md error, and untagged warnings. Update existing tests as needed.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T13:41:27.024546Z","updated_at":"2025-10-21T18:46:17.688561Z","closed_at":"2025-10-21T18:46:17.688561Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-95","depends_on_id":"k-90","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-96","title":"Consolidate qmd::read error reporting to DiagnosticMessage","description":"Refactor qmd::read to return Result> instead of Result<(Pandoc, ASTContext), Vec>. Unify all error/warning types. See claude-notes/plans/2025-10-21-consolidate-to-diagnosticmessage.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-21T14:24:59.380974Z","updated_at":"2025-11-23T13:22:48.147789Z","closed_at":"2025-11-23T13:22:49.147789Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-97","title":"Create produce_diagnostic_messages() function","description":"Add produce_diagnostic_messages() to qmd_error_messages.rs to convert tree-sitter parse errors to Vec instead of Vec","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:25:08.296798Z","updated_at":"2025-10-21T15:38:21.894018Z","closed_at":"2025-10-21T15:38:21.894018Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-97","depends_on_id":"k-96","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-98","title":"Define ParseResult struct and update qmd::read signature","description":"Add ParseResult struct with pandoc, context, diagnostics. Update qmd::read to return Result>","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:25:16.000177Z","updated_at":"2025-10-21T15:29:13.893568Z","closed_at":"2025-10-21T15:29:13.893568Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-98","depends_on_id":"k-96","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-99","title":"Convert all error returns in qmd::read to DiagnosticMessage","description":"Update tree-sitter errors, deep nesting errors, manual parse errors, AST conversion errors to all return DiagnosticMessage","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-21T14:25:23.062813Z","updated_at":"2025-10-21T15:29:21.878964Z","closed_at":"2025-10-21T15:29:21.878964Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-99","depends_on_id":"k-96","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-9aj6","title":"Phase 3: AST Transformation Layer","description":"REVISED: Port critical Lua filters to Rust. Includes: Normalization transforms (Pandoc AST → Quarto extended AST), custom node parsing, figure/table handling, callout rendering, cross-reference system. Part of k-xlko.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-20T17:42:24.636072Z","updated_at":"2025-12-20T18:09:56.561644Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-9aj6","depends_on_id":"k-bk15","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-9aj6","depends_on_id":"k-xlko","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-9jt4","title":"Improve coverage: schema/helpers.rs","description":"Session baseline: 74.35% line coverage. Target: beat baseline by adding tests to quarto-yaml-validation/src/schema/helpers.rs (currently 62.42% coverage).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T17:46:41.606040Z","updated_at":"2026-01-02T17:53:25.290075Z","closed_at":"2026-01-02T17:53:25.290075Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-9jt4","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-9zwe","title":"Phase 1.2: Jupyter notebook conversion","description":"Phase 2: Execute request/reply - implement execute(), collect outputs from iopub","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-07T15:42:33.881706697Z","updated_at":"2026-01-07T19:24:55.234213344Z","closed_at":"2026-01-07T19:24:55.234213344Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-9zwe","depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-a2nw","title":"quarto render should produce ariadne-style errors like pampa","description":"The quarto-core crate has its own QuartoError type that wraps strings, completely ignoring the rich DiagnosticMessage infrastructure from quarto-error-reporting.\n\n**Current state:**\n- `QuartoError::Parse(String)` - loses all structured error info\n- Diagnostics are converted to strings too early (in pipeline.rs)\n- SourceContext is discarded, so ariadne can't render source snippets\n- Tests can't check DiagnosticMessage structure\n\n**Expected behavior (what pampa does):**\n- Keep `Vec` with full source locations\n- Only convert to string at CLI output time\n- Pass SourceContext for ariadne rendering\n\n**Required changes:**\n1. Refactor `QuartoError` to hold `Vec` + source info\n2. Update `parse_qmd()` to return structured errors\n3. Update CLI to render diagnostics with SourceContext\n4. Write tests that check DiagnosticMessage structure directly\n\nPlan: claude-notes/plans/2025-12-28-quarto-core-error-infrastructure.md","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-28T21:23:49.171149Z","updated_at":"2025-12-28T21:59:15.646353Z","closed_at":"2025-12-28T21:59:15.646353Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-a2nw","depends_on_id":"k-i5nw","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-b1x1","title":"Phase 5: Engine Infrastructure","description":"REVISED (was Phase 5 HTML Postprocessing): Prepare for code execution. Define ExecutionEngine trait and registry, implement MarkdownEngine (passthrough), engine selection algorithm, freeze/thaw support, Jupyter engine placeholder. Part of k-xlko.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-20T17:42:26.563508Z","updated_at":"2025-12-20T18:09:58.811967Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-b1x1","depends_on_id":"k-xlko","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-b1x1","depends_on_id":"k-yd14","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-bfp2","title":"Improve coverage: CSL/citeproc error modules","description":"Session baseline: 71.55% line coverage. Target: beat baseline. Testing error.rs modules in quarto-csl and quarto-citeproc crates (both at 0% coverage).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T17:33:43.799815Z","updated_at":"2026-01-01T17:41:53.887269Z","closed_at":"2026-01-01T17:41:53.887269Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-bfp2","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-bk15","title":"Phase 2: Dependency System (CSS, JS, Resources)","description":"REVISED: Support CSS, JS, and resource dependencies. Includes: SASS compilation via dart-sass, dependency injection (copy to lib/, inject script/link tags), resource discovery for images/data files. Part of k-xlko.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-20T17:42:23.055014Z","updated_at":"2025-12-20T18:09:54.697347Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-bk15","depends_on_id":"k-6qau","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-bk15","depends_on_id":"k-xlko","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-btfo","title":"Remove dead treesitter_utils modules","description":"8 dead code files found in pampa/src/pandoc/treesitter_utils/: code_span.rs, inline_link.rs, image.rs, indented_code_block.rs, latex_span.rs, quoted_span.rs, raw_attribute.rs, raw_specifier.rs, setext_heading.rs. See report: claude-notes/reports/2026-01-01-dead-code-treesitter-utils.md","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T18:07:09.024728Z","updated_at":"2026-01-01T18:12:22.787341Z","closed_at":"2026-01-01T18:12:22.787341Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-c1sk","title":"Improve coverage: pampa/src/utils/text.rs","description":"Current baseline: 71.87% line coverage. Target: pampa/src/utils/text.rs at 0% coverage (32 lines).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T17:45:51.717066Z","updated_at":"2026-01-01T17:49:51.261619Z","closed_at":"2026-01-01T17:49:51.261619Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-c1sk","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-c6uj","title":"Phase 1.1: Jupyter core infrastructure","description":"Phase 1: Kernel lifecycle - add deps, create module structure, implement kernelspec discovery, kernel start/stop","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-07T15:42:32.875326323Z","updated_at":"2026-01-07T18:15:30.555039724Z","closed_at":"2026-01-07T18:15:30.555039724Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-c6uj","depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-ct7i","title":"Improve coverage: citeproc_filter.rs","description":"Session baseline: 74.78% line coverage. Target: beat baseline. citeproc_filter.rs currently at 2.65% coverage (1101 of 1131 lines uncovered).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T19:01:37.747325Z","updated_at":"2026-01-02T19:12:09.524301Z","closed_at":"2026-01-02T19:12:09.524301Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-ct7i","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-d4r0","title":"quarto-yaml: Capture tags on compound types (arrays/maps)","description":"The quarto-yaml crate currently only captures YAML tags on scalar values, not on compound types (arrays and maps).\n\n**Current behavior:**\n```yaml\nitems: !prefer [a, b] # Tag is NOT captured on the array\nconfig: !prefer {key: value} # Tag is NOT captured on the map\n```\n\n**Impact:**\n- `!prefer` tags on arrays/maps are silently ignored\n- This prevents proper merge semantics for compound types in config merging\n- Documented in pampa test: test_prefer_on_inline_array, test_prefer_on_inline_map\n\n**Files:**\n- crates/quarto-yaml/src/parser.rs (tag capture logic)\n- crates/quarto-yaml/src/yaml_with_source_info.rs (YamlWithSourceInfo struct)\n\n**Test documenting current behavior:**\ncrates/quarto-yaml/src/parser.rs:1249 - 'The tag is currently only captured for scalars, not sequences'","status":"open","priority":2,"issue_type":"bug","created_at":"2025-12-29T18:53:14.549566Z","updated_at":"2025-12-29T18:53:14.549566Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-d4r0","depends_on_id":"k-2tu9","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-dnfd","title":"Expose unified render pipeline for quarto crate and WASM","description":"The wasm-quarto-hub-client currently bypasses the quarto-core transform pipeline (callouts, metadata normalization, etc.) by calling pampa directly. We need to expose a unified render function from the quarto crate that both the CLI and WASM client can use, ensuring feature parity.\n\nPlan: claude-notes/plans/2025-12-27-unified-render-pipeline.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-27T16:50:10.528283Z","updated_at":"2025-12-27T17:43:49.771037Z","closed_at":"2025-12-27T17:43:49.771037Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-dp9r","title":"Improve coverage: unified_filter.rs","description":"Session baseline: 74.68% line coverage. Target: beat baseline by adding tests for error Display implementations in unified_filter.rs (currently at 40.65% coverage).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T18:34:05.717593Z","updated_at":"2026-01-02T18:38:51.272709Z","closed_at":"2026-01-02T18:38:51.272709Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-dp9r","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-dqce","title":"Phase 4: CLI integration for templates","description":"Add CLI options (--template, --template-bundle, --body-format), embed built-in templates, add export-template subcommand, update main.rs routing.","status":"in_progress","priority":1,"issue_type":"task","created_at":"2025-12-05T17:44:28.727559Z","updated_at":"2025-12-05T17:54:27.284787Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-dqce","depends_on_id":"k-5u7d","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-dqce","depends_on_id":"k-y2f3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-enqe","title":"Phase 1.4: JupyterEngine trait implementation","description":"Phase 4: AST integration - JupyterEngine as AstTransform, CodeBlock extraction and replacement","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-07T15:42:37.102402981Z","updated_at":"2026-01-07T19:25:00.147917236Z","closed_at":"2026-01-07T19:25:00.147917236Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-enqe","depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-evpj","title":"Add presence features (cursors, selections) to quarto-hub","description":"Implement collaborative presence features showing other users' cursors and selections in real-time. Leverage Monaco's decoration/cursor APIs and Automerge's ephemeral messaging for presence state.\n\nPlan: claude-notes/plans/2025-12-28-presence-features.md","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2025-12-28T17:15:53.016124Z","updated_at":"2025-12-28T18:12:25.636523Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-fgyv","title":"Design Python filter integration for quarto-markdown-pandoc","description":"Explore feasibility and design architecture for native Python filters that can run in-process, similar to Lua filters. Goals: (1) leverage existing Python interpreter or embed libpython, (2) build Python package with entry points to quarto-markdown-pandoc, (3) provide comparable dev experience to Lua filters with walk() methods and AST node constructors.\n\n**Plan document:** claude-notes/plans/2025-12-06-python-filter-integration.md","status":"open","priority":1,"issue_type":"feature","created_at":"2025-12-06T18:46:57.081157Z","updated_at":"2025-12-06T18:52:28.741554Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-g9uc","title":"Property testing framework for CommonMark subset validation","description":"Design and implement a property testing framework using proptest to verify that generated Pandoc ASTs roundtrip correctly through qmd writer → qmd reader and comrak parser. This provides stronger coverage than hand-written differential tests by generating arbitrary valid inputs.","notes":"See claude-notes/plans/2025-12-16-property-testing-commonmark-subset.md for full design.\n\nAPPROACH: Feature set-based generators that progressively add complexity.\n\nFEATURE SET DESIGN:\n- Generator takes a set of enabled features (InlineFeatures, BlockFeatures)\n- When using a feature (e.g., Emph), recurse with that feature removed\n- Elegantly prevents Emph-inside-Emph and naturally limits nesting depth\n- Enables progressive complexity testing\n\nINLINE PROGRESSION (L0-L7):\nL0: Plain text (Str, Space, SoftBreak)\nL1: + Emph\nL2: + Strong\nL3: + Code\nL4: + Link\nL5: + Image\nL6: + Autolink\nL7: + LineBreak\n\nBLOCK PROGRESSION (B0-B6):\nB0: Paragraph only\nB1: + Header\nB2: + CodeBlock\nB3: + HorizontalRule\nB4: + BlockQuote (recursive)\nB5: + BulletList (recursive)\nB6: + OrderedList\n\nIMPLEMENTATION: 7 phases with checkpoints after each level\n- Each phase adds features and verifies tests pass before proceeding\n- Progressive approach helps isolate which features cause failures\n\nNORMALIZATION:\n- Strip heading IDs\n- Figure → Paragraph(Image)\n- Strip autolink uri class\n- Strip extra code block attributes","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-16T22:46:33.219368Z","updated_at":"2025-12-16T22:59:48.737986Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-g9uc","depends_on_id":"k-333","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-giyy","title":"Investigate style differences between WASM and CLI rendering","description":"Implement artifact system for WASM rendering to match CLI styling.\n\n**Plan:** claude-notes/plans/2025-12-27-wasm-css-styling.md\n\n**Architecture:**\n1. Render pipeline stores CSS/resources as artifacts with paths under /.quarto/project-artifacts/\n2. WASM populates VFS with artifacts after render\n3. React post-processor replaces artifact links with data URIs on iframe load\n4. Same pattern handles .qmd link navigation\n\n**Status:** Plan approved, ready for implementation","status":"in_progress","priority":1,"issue_type":"task","created_at":"2025-12-27T18:09:24.254333Z","updated_at":"2025-12-27T18:32:51.150423Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-gv05","title":"Fix nondeterministic sourceInfoPool IDs in JSON writer","description":"The yaml-tags snapshot test fails intermittently on Linux CI but passes on macOS. Root cause: pointer-based cache in SourceInfoSerializer returns stale IDs when memory addresses are reused. See plan: claude-notes/plans/2026-01-02-yaml-tags-nondeterminism-analysis.md","status":"open","priority":1,"issue_type":"bug","created_at":"2026-01-02T23:34:50.502156Z","updated_at":"2026-01-02T23:35:41.415120Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-h66w","title":"Phase 2.2: Jupyter daemon integration","description":"Implement daemon client, kernel session reuse, daemon options","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-07T15:42:59.945361516Z","updated_at":"2026-01-07T19:25:02.064190971Z","closed_at":"2026-01-07T19:25:02.064190971Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-h66w","depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-hb9f","title":"Remove dead code: treesitter_utils helper files","description":"Six treesitter_utils helper files are declared in mod.rs but never imported or used:\n\n1. attribute.rs (16 lines) - superseded by inline handling in treesitter.rs\n2. backslash_escape.rs (15 lines) - handled by process_backslash_escapes in text_helpers\n3. html_comment.rs (12 lines) - 'comment' case returns IntermediateUnknown\n4. key_value_specifier.rs (22 lines) - handled inline at line 928 in treesitter.rs\n5. link_title.rs (12 lines) - 'title' case handled inline at line 1013\n6. note_reference.rs (20 lines) - 'inline_note_reference' handled inline at line 784\n\nTotal: ~97 lines of dead code that inflate uncovered line counts.\nEvidence: grep -r 'module::' finds no imports for these modules.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-01-02T15:36:23.945641Z","updated_at":"2026-01-02T15:41:52.744353Z","closed_at":"2026-01-02T15:41:52.744353Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-hqyf","title":"Add convenience accessors (identifier, classes, attributes) for inline elements with attr","description":"Inline elements with attr (Span, Code, Link, Image, Insert, Delete, Highlight, EditComment) are missing convenience getters/setters for identifier, classes, and attributes fields. Block elements (CodeBlock, Header, Div) have these, and LuaAttr has them, but inline elements don't. This breaks Pandoc Lua API compatibility.","status":"closed","priority":2,"issue_type":"bug","created_at":"2026-01-02T21:00:41.989146Z","updated_at":"2026-01-02T21:05:17.263951Z","closed_at":"2026-01-02T21:05:17.263951Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-i5nw","title":"Monaco editor diagnostic squiggles from QMD parse errors","description":"Surface structured DiagnosticMessage errors from WASM rendering to Monaco editor as inline squiggles/markers, replacing the current plain text error display.\n\nPlan: claude-notes/plans/2025-12-28-monaco-diagnostics.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-28T21:17:48.343533Z","updated_at":"2025-12-28T23:05:27.665775Z","closed_at":"2025-12-28T23:05:27.665775Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-ic1o","title":"Integrate ConfigValue into ProjectConfig and render pipeline","description":"Implement the configuration merging infrastructure needed for matched scrolling and future features.\n\nThis is a prerequisite for k-suww (matched scrolling).\n\nKey changes:\n1. Create quarto-config crate with ConfigValue and MergedConfig types (subset of design in 2025-12-07-config-merging-design.md)\n2. Replace ProjectConfig.raw: serde_json::Value with ConfigValue\n3. Update render_qmd_to_html to merge project config with document metadata\n4. Allow WASM renderer to inject config into ProjectContext\n\nThis enables:\n- Source location tracking controlled via project config (not document metadata injection)\n- Future format-specific settings controlled at project level\n- Clean separation between project defaults and document overrides\n\nPlan: claude-notes/plans/2025-12-29-config-integration-pipeline.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-29T16:25:44.563423Z","updated_at":"2025-12-30T04:08:59.618876Z","closed_at":"2025-12-30T04:08:59.618876Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-ic1o","depends_on_id":"k-suww","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-ifux","title":"Implement IndexedDB schema versioning and migration system","description":"Create a robust schema versioning system for the hub-client IndexedDB storage. Support both structural changes (new stores/indexes) via IndexedDB native upgrade and data transformations via application-level migrations. This is a prerequisite for adding user identity storage for presence features.\n\nParent issue: k-evpj (presence features)\nPlan: claude-notes/plans/2025-12-28-indexeddb-schema-versioning.md","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-28T17:37:57.936839Z","updated_at":"2025-12-28T18:01:12.646463Z","closed_at":"2025-12-28T18:01:12.646463Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-ifux","depends_on_id":"k-evpj","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-igxc","title":"Improve coverage: citeproc_filter.rs (continued)","description":"Session baseline: 75.16% line coverage. Target: beat baseline. citeproc_filter.rs currently at 42.23% coverage. Focus on extract_references, extract_names, extract_date, collect_citations, and insert_bibliography.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T19:58:55.445255Z","updated_at":"2026-01-02T20:06:51.694953Z","closed_at":"2026-01-02T20:06:51.694953Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-igxc","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-igyi","title":"comrak-to-pandoc: Missing Space inline handling in conversion","description":"Property testing revealed that comrak-to-pandoc conversion produces different ASTs than pampa for input with whitespace before styled text. Comrak produces [Str(\"aA\"), Emph(...)] while pampa produces [Str(\"aA\"), Space, Emph(...)]. Need to investigate whether comrak's AST contains the space and we're losing it in conversion.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-16T23:16:40.121400Z","updated_at":"2025-12-16T23:27:03.039945Z","closed_at":"2025-12-16T23:27:03.039945Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-igyi","depends_on_id":"k-g9uc","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-j7by","title":"Improve coverage: quarto-yaml-validation/src/error.rs","description":"Session baseline: 71.24% line coverage. Target: beat baseline by testing error types in quarto-yaml-validation.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T17:05:24.734762Z","updated_at":"2026-01-01T17:12:44.264491Z","closed_at":"2026-01-01T17:12:44.264491Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-j7by","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-jocn","title":"Phase 1.3: Jupyter subprocess execution","description":"Phase 3: Output conversion - Media → AST blocks (text, images, html)","status":"closed","priority":1,"issue_type":"task","created_at":"2026-01-07T15:42:35.586066838Z","updated_at":"2026-01-07T19:24:57.484988440Z","closed_at":"2026-01-07T19:24:57.484988440Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-jocn","depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-js4l","title":"Remove dead code: code_span.rs","description":"code_span.rs is never imported or used. It was superseded by code_span_helpers.rs. Should be removed to clean up codebase.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-01-01T18:03:29.791259Z","updated_at":"2026-01-01T18:07:15.030512Z","closed_at":"2026-01-01T18:07:15.030512Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-jut5","title":"Improve coverage: html_source.rs source map tests","description":"Session baseline: 76.36% line coverage. Final: 76.72%. Added 34 integration tests for build_source_map exercising various block and inline types.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-03T20:40:25.061265Z","updated_at":"2026-01-03T20:40:30.304193Z","closed_at":"2026-01-03T20:40:30.304193Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-jut5","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-k803","title":"Improve coverage: metadata_normalize.rs","description":"Session baseline: 77.08% line coverage. Target file: quarto-core/src/transforms/metadata_normalize.rs at 51.77%. Goal: beat baseline.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-03T22:04:01.971759Z","updated_at":"2026-01-03T22:13:59.526466Z","closed_at":"2026-01-03T22:13:59.526466Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-k803","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-kaaq","title":"Improve coverage: pandoc/location.rs","description":"Session baseline: 75.05% line coverage. Target: beat baseline. location.rs currently at 63.91% coverage (61 of 169 lines uncovered).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T19:26:43.887842Z","updated_at":"2026-01-02T19:31:48.152479Z","closed_at":"2026-01-02T19:31:48.152479Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-kaaq","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-ke2m","title":"Filesystem synchronization design for quarto-hub","description":"Design the bidirectional synchronization between filesystem (.qmd files) and automerge documents.\n\n## Core Design: Unified Sync Algorithm\n\nA single fork-and-merge algorithm handles ALL sync scenarios (startup, shutdown, periodic, user-triggered):\n\n1. Fork doc at last sync checkpoint\n2. Apply filesystem content to fork via update_text (Myers diff)\n3. Merge fork back into main doc (CRDT merge)\n4. Write merged result to filesystem\n5. Update checkpoint\n\nThis naturally handles: no changes (no-op), automerge-only changes, filesystem-only changes, and true divergence (three-way merge).\n\n## Key Decisions\n- Automerge update_text handles diffing internally (grapheme-aware Myers)\n- Sync state stored locally in sync-state.json (not synced to peers)\n- Algorithm converges: after sync, fs and automerge match\n\n## Related Issues\n- k-r2t1 (filesystem serialization strategy)\n- k-yvfo (conflict resolution for divergence)\n\nDesign document: claude-notes/plans/2025-12-09-filesystem-sync-design.md","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-09T21:56:36.732287Z","updated_at":"2025-12-09T22:53:24.323101Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-ke2m","depends_on_id":"k-4wex","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-kh5i","title":"Jupyter engine implementation","description":"Implement Jupyter execution engine as AstTransform using pure Rust via runtimelib/jupyter-protocol (no Python subprocess orchestration). Features: in-process daemon with tokio, ZeroMQ kernel communication, inline expression evaluation. See plan: claude-notes/plans/2026-01-07-jupyter-engine-implementation.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-01-07T15:42:15.691802744Z","updated_at":"2026-01-07T19:25:14.619299804Z","closed_at":"2026-01-07T19:25:14.619299804Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-kswp","title":"Phase 4: quarto-yaml integration","description":"Extend quarto-yaml tag parsing to recognize !prefer and !concat. Ensure tags flow through to YamlWithSourceInfo.tag field. Integrate error handling with DiagnosticCollector. Plan: claude-notes/plans/2025-12-07-config-merging-design.md Phase 4","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T20:03:57.230535Z","updated_at":"2025-12-07T20:32:45.993075Z","closed_at":"2025-12-07T20:32:45.993075Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-kswp","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-lckc","title":"Use quarto-error-reporting crate uniformly for render pipeline errors and warnings","description":"The render pipeline (quarto-core, quarto render command) currently uses ad-hoc error handling. Should integrate with quarto-error-reporting crate for consistent, user-friendly error messages and warnings throughout the rendering process.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-21T18:19:34.525509Z","updated_at":"2025-12-21T18:19:34.525509Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-libc","title":"Automerge schema design for quarto-hub","description":"Design the automerge schema for: (1) the project index document mapping file paths to doc-ids, (2) individual .qmd document representation. Consider what data structures work well with CRDTs.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-08T19:24:44.089038Z","updated_at":"2025-12-08T19:24:44.089038Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-libc","depends_on_id":"k-4wex","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-m46n","title":"Design PipelineStage abstraction for full render pipeline","description":"Design explicit PipelineStage struct and variants to represent all stages of Quarto document rendering - from source file conversion through AST transformation to output generation and postprocessing. This enables validation, orchestration, and different stage sequences for different file types.\n\n**Plan**: claude-notes/plans/2026-01-06-pipeline-stage-design.md\n\n**Related analyses**:\n- claude-notes/render-pipeline/single-document/README.md\n- claude-notes/plans/lua-filter-pipeline/00-index.md\n- claude-notes/plans/2025-12-27-unified-render-pipeline.md","status":"open","priority":1,"issue_type":"feature","created_at":"2026-01-06T16:13:42.692768183Z","updated_at":"2026-01-06T16:15:37.258355308Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-mapj","title":"Implement list-table div to Pandoc table desugaring and reverse transformation","description":"Add postprocessing transformation to convert list-table divs to Pandoc table ASTs (reader direction) and add qmd writer transformation to convert complex tables back to list-table divs (writer direction). Only use list-table format when pipe tables are insufficient.\n\nPlan: claude-notes/plans/2025-12-05-list-table-implementation.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-12-05T15:11:18.944162Z","updated_at":"2025-12-05T15:51:02.454702Z","closed_at":"2025-12-05T15:51:02.454702Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-mr16","title":"Improve coverage: schema/parsers/combinators.rs","description":"Session baseline: 74.59% overall. Target: combinators.rs currently at 64.17% coverage. Add tests for error paths in anyOf, allOf, and maybeArrayOf parsers.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T18:07:14.481032Z","updated_at":"2026-01-02T18:11:54.401607Z","closed_at":"2026-01-02T18:11:54.401607Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-mr16","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-muo0","title":"Remove dead code: raw_attribute.rs","description":"File pampa/src/pandoc/treesitter_utils/raw_attribute.rs (26 lines) is never called. The inline grammar produces attribute_specifier containing raw_specifier (not raw_attribute). The raw_specifier is handled directly in treesitter.rs lines 1042-1054.","status":"closed","priority":3,"issue_type":"task","created_at":"2026-01-03T19:42:48.233570Z","updated_at":"2026-01-03T19:45:19.773692Z","closed_at":"2026-01-03T19:45:19.773692Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-n74s","title":"Add CommonMark reader to pampa using comrak-to-pandoc","description":"Add a --from commonmark option to pampa that uses comrak for parsing. This leverages the comrak-to-pandoc crate we built for property testing. Key enhancement: add source location tracking from comrak Sourcepos to quarto-source-map SourceInfo.\n\nPlan: claude-notes/plans/2025-12-17-commonmark-reader-for-pampa.md","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-17T19:13:21.737988Z","updated_at":"2025-12-17T19:14:33.644673Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-nkhl","title":"Abstract filesystem access in quarto-core for WASM compatibility","description":"Introduce a QuartoRuntime trait similar to LuaRuntime that abstracts filesystem access, environment, and binary discovery. This enables quarto render to run in WASM environments with a virtual filesystem.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-22T21:08:47.310583Z","updated_at":"2025-12-23T00:58:52.580617Z","closed_at":"2025-12-23T00:58:52.580617Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-nkhl","depends_on_id":"k-0sdx","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-nwcy","title":"Improve preview pane behavior on markdown syntax errors","description":"Change preview pane to retain last good render when syntax errors occur during editing, showing errors as overlay instead of replacing content. Implements a 4-state machine: START, ERROR_AT_START, GOOD, ERROR_FROM_GOOD.\n\nPlan document: claude-notes/plans/2026-01-08-preview-error-state-machine.md","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-01-08T20:40:30.205021Z","updated_at":"2026-01-08T20:57:44.114865Z","closed_at":"2026-01-08T20:57:44.114865Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-o399","title":"quarto-doctemplate produces extra newlines vs Pandoc's doctemplates","description":"quarto-doctemplate produces extra newlines in template output compared to Pandoc's doctemplates. This affects multiline $if$/$for$ directives where newlines after opening/closing directives should be consumed. See plan: claude-notes/plans/2025-12-06-doctemplate-newline-fix.md","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-06T18:11:43.863481Z","updated_at":"2025-12-06T18:28:32.985751Z","closed_at":"2025-12-06T18:28:32.985751Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-oomv","title":"ExecutionEngine trait and engine detection","description":"Implement ExecutionEngine trait, engine detection from .qmd metadata, and engine execution pipeline stage. Support markdown (default), knitr, and jupyter engines.\n\nPlan: claude-notes/plans/2026-01-06-execution-engine-infrastructure.md\n\n## Progress\n\n### Phase 1 (Core Infrastructure) ✅\n- ExecutionEngine trait implemented\n- Engine detection from metadata (all YAML variants)\n- EngineRegistry with native/WASM gating\n- MarkdownEngine (no-op passthrough)\n- KnitrEngine and JupyterEngine placeholders (native-only)\n- All unit tests passing\n\n### Phase 2 (Pipeline Integration) ✅\n- EngineExecutionStage implemented\n- Stage wired into stages module\n- End-to-end markdown engine works\n- WASM build verified working\n- Fallback behavior with warnings for unknown engines\n\n### Phase 3 (Source Location Reconciliation) ✅\n- reconcile_source_locations function implemented\n- Content equality comparison for blocks and inlines\n- Block/inline matching with limited lookahead alignment\n- ReconciliationReport tracking exact matches, structural matches, additions, deletions\n- All reconciliation tests passing (96 engine tests total)\n\n### Remaining Work\n- Phase 4: Knitr engine implementation (future)\n- Phase 5: Jupyter engine implementation (future)","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-01-06T22:56:20.543548335Z","updated_at":"2026-01-07T19:25:16.261135141Z","closed_at":"2026-01-07T19:25:16.261135141Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-os6h","title":"Define error handling strategy for config merging","description":"Define behavior for error conditions during config merging: 1) YAML parsing failures in individual layers, 2) Syntactically invalid/malformed tags, 3) Memory/stack overflow from deeply nested configs, 4) Boundary documentation for out-of-scope errors (circular includes). Plan file: claude-notes/plans/2025-12-07-config-error-handling.md","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T17:06:46.867359Z","updated_at":"2025-12-07T20:03:11.132977Z","closed_at":"2025-12-07T20:03:11.132977Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-os6h","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-p39g","title":"Non-deterministic test failures due to HashMap usage","description":"Tests test_chicago_author_date_style, test_bibliography_delimiters, and yaml-tags snapshot are failing due to non-deterministic behavior. Likely caused by HashMap usage where LinkedHashMap should be used.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-12-31T22:47:46.526333Z","updated_at":"2025-12-31T23:28:34.047474Z","closed_at":"2025-12-31T23:28:34.047474Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-p4gl","title":"Phase 2.1: Jupyter daemon infrastructure","description":"Design daemon protocol, implement JupyterDaemon struct, transport file management","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-07T15:42:59.036272974Z","updated_at":"2026-01-07T19:25:01.283740946Z","closed_at":"2026-01-07T19:25:01.283740946Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-p4gl","depends_on_id":"k-kh5i","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-p4nu","title":"Audit anyhow::anyhow\\! usages for error structure loss","description":"Several places in the codebase use anyhow::anyhow\\!() in ways that lose structured error information. This issue tracks reviewing and potentially fixing these patterns.\n\n## Problematic Patterns Found\n\n### qmd-syntax-helper crate\n\n1. **syntax_check.rs:89** - Joins error strings and wraps in anyhow:\n ```rust\n let error_msg = errors.join(\"\\n\");\n Err(anyhow::anyhow\\!(\"{}\", error_msg))\n ```\n\n2. **grid_tables.rs:137** - Uses debug format on diagnostics:\n ```rust\n anyhow::anyhow\\!(\"Failed to write markdown output: {:?}\", diagnostics)\n ```\n\n3. **definition_lists.rs:190** - Same issue as grid_tables.rs\n\n### validate-yaml crate\n\n- Uses anyhow for simple CLI errors, likely acceptable for a validation tool.\n\n## Recommended Actions\n\n1. For qmd-syntax-helper: Consider using proper diagnostic rendering with `to_text()` instead of debug format\n2. Review if these tools need the same rich error display as the main CLI\n3. Consider creating a shared error display utility\n\n## Notes\n\n- Simple IO/path errors using anyhow are acceptable\n- The main render.rs:201 issue was fixed separately (handled parse errors specially to avoid duplicate 'Error:' prefix)","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-28T22:38:54.778863Z","updated_at":"2025-12-28T22:38:54.778863Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-p80n","title":"Add type/version field to index document for client validation","description":"When connecting to a sync server, the client currently has no way to verify that a document ID points to an index document vs a file document. Add a 'type' or 'version' field to the index document structure (e.g., {type: 'quarto-hub-index', version: 1, files: {...}}) so clients can validate they're connecting to the correct document and show a helpful error message if not.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-23T02:12:42.733023Z","updated_at":"2025-12-23T02:12:42.733023Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-q4rm","title":"HTML writer source tracking implementation - pointer-based AST annotation","description":"Implement source location tracking in HTML writer using pointer-based AST node identification. Uses JSON writer output + parallel walk to build location map. See plan: claude-notes/plans/2025-12-21-html-source-tracking-implementation.md","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-21T21:57:32.879272Z","updated_at":"2025-12-21T21:57:32.879272Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-q4rm","depends_on_id":"k-02o9","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-r2t1","title":"Filesystem serialization strategy for quarto-hub","description":"Design how/when automerge state is serialized back to .qmd files on disk. Consider: continuous sync, on-demand save, periodic snapshots, conflict with external edits.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-08T19:24:50.277282Z","updated_at":"2025-12-08T19:24:50.277282Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-r2t1","depends_on_id":"k-4wex","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-rem3","title":"Improve coverage: lua/types.rs","description":"Session baseline: 75.59% line coverage. lua/types.rs currently at 23.60% coverage. Focus on tag_name(), field_names(), get_field(), set_field(), and meta value conversion.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T20:10:08.467544Z","updated_at":"2026-01-02T20:20:07.712645Z","closed_at":"2026-01-02T20:20:07.712645Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-rem3","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-riq2","title":"Phase 1: Create quarto-config crate with core types","description":"Create quarto-config crate skeleton with: MergeOp, Interpretation, ConfigValueKind, ConfigValue types. Implement tag parsing with error handling (Q-1-21 through Q-1-28). Implement From and From. Add error codes to error_catalog.json. Write unit tests. Plan: claude-notes/plans/2025-12-07-config-merging-design.md Phase 1","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-07T20:03:24.301377Z","updated_at":"2025-12-07T20:09:59.964477Z","closed_at":"2025-12-07T20:09:59.964477Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-riq2","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-rmdm","title":"Monaco cursor shifts when remote collaborator edits document","description":"In collaborative editing sessions, when a remote collaborator makes changes to the document, the local user's cursor position shifts unexpectedly. This degrades the collaborative editing UX significantly as users lose their place while typing.\n\nPlan document: claude-notes/plans/2025-12-28-fix-monaco-cursor-shift.md\n\nRoot cause: The system passes full document content from Automerge to Monaco on every remote change. Monaco has no knowledge of what changed or where, so it cannot preserve cursor position.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-28T15:32:23.697592Z","updated_at":"2025-12-28T16:05:55.349648Z","closed_at":"2025-12-28T16:05:55.349648Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-rqsx","title":"Improve coverage: quarto-pandoc-types/src/inline.rs","description":"Session baseline: 74.02% line coverage. File at 61.11%. Focus on is_empty_target, make_span_inline branches, AsInline trait.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T17:18:01.085401Z","updated_at":"2026-01-02T17:22:31.779870Z","closed_at":"2026-01-02T17:22:31.779870Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-sc44","title":"Phase 6: Performance and polish","description":"Benchmark against TypeScript mergeConfigs. Profile and optimize hot paths. Consider caching if needed. Documentation. Plan: claude-notes/plans/2025-12-07-config-merging-design.md Phase 6","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-07T20:04:10.627776Z","updated_at":"2025-12-07T20:04:10.627776Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-sc44","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-se1i","title":"Improve coverage: code_span.rs treesitter utils","description":"Current baseline: 71.94% line coverage. Target: pampa/src/pandoc/treesitter_utils/code_span.rs at 0% coverage (107 lines).","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-01T17:51:51.978644Z","updated_at":"2026-01-01T18:03:23.415423Z","closed_at":"2026-01-01T18:03:23.415423Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-se1i","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-suww","title":"Implement matched scrolling between editor and preview in hub-client","description":"Add bidirectional scroll synchronization between Monaco editor and HTML preview pane.\n\nFeatures:\n- Editor cursor movement scrolls preview to show corresponding output (scroll only if not visible)\n- Preview scroll updates editor viewport (without moving cursor)\n- Single UI toggle in toolbar to enable/disable\n- 50ms debounce to prevent jitter\n\nImplementation requires:\n1. WASM pipeline enhancement to inject source-location metadata\n2. New useScrollSync React hook\n3. UI toggle component\n\nPlan: claude-notes/plans/2025-12-29-matched-scrolling-hub-client.md","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-12-29T15:47:48.736879Z","updated_at":"2025-12-30T15:04:55.815946Z","closed_at":"2025-12-30T15:04:55.815946Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-thpl","title":"Port Lua filter infrastructure to Rust","description":"Port quarto-cli's Lua filter infrastructure (customnodes.lua, emulatedfilter.lua, runemulation.lua) to Rust. Includes: CustomNode trait, handler/renderer registries, slot-based storage, format-conditional rendering.\n\nPlans and Analysis:\n- Custom node design: claude-notes/plans/2025-12-20-lua-filter-infrastructure-porting.md\n- Pipeline analysis: claude-notes/plans/lua-filter-pipeline/00-index.md (full stage-by-stage analysis with side effects, Pandoc API usage, WASM compatibility)","status":"open","priority":1,"issue_type":"feature","created_at":"2025-12-20T18:26:52.227604Z","updated_at":"2025-12-20T21:21:06.462048Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-thpl","depends_on_id":"k-xlko","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-tjdc","title":"Set up code coverage infrastructure","description":"Set up tooling to measure and report code coverage for the Rust workspace. Plan: claude-notes/plans/2025-12-31-code-coverage-infrastructure.md","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-31T15:37:16.009471Z","updated_at":"2025-12-31T15:50:38.721023Z","closed_at":"2025-12-31T15:50:38.721023Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-u1iy","title":"Phase 2: Writer integration for templates","description":"Create body rendering helpers (render_body_html, render_body_plaintext) and metadata rendering helpers (render_inlines_html, render_blocks_html, etc.) that wrap existing writers for use in template context building.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-05T17:44:18.098177Z","updated_at":"2025-12-05T17:53:45.539905Z","closed_at":"2025-12-05T17:53:45.539905Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-u1iy","depends_on_id":"k-1c5v","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-u1iy","depends_on_id":"k-y2f3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-u5gt","title":"Phase 6: Template integration tests","description":"Unit tests for bundle.rs (JSON parsing), context.rs (MetaValue conversion), render.rs (full pipeline). Integration tests for end-to-end rendering, bundle vs filesystem modes.","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-05T17:44:39.511340Z","updated_at":"2025-12-05T17:44:39.511340Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-u5gt","depends_on_id":"k-1c5v","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-u5gt","depends_on_id":"k-y2f3","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-u909","title":"Improve coverage: quarto-pandoc-types/src/config_value.rs","description":"Session baseline: 72.93% line coverage. Target: beat baseline. Focus on serialization, constructors, and accessor methods.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T15:58:52.382041Z","updated_at":"2026-01-02T16:05:28.986193Z","closed_at":"2026-01-02T16:05:28.986193Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-u909","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-uoc5","title":"Improve code coverage across workspace","description":"Epic to track code coverage improvement work. Goal: achieve as close to 100% coverage as practical.\n\nCurrent baseline (2025-12-31): 69.62% line coverage, 73.89% function coverage.\n\nWorkflow: claude-notes/workflows/code-coverage-improvement.md\nPlan: claude-notes/plans/2025-12-31-code-coverage-infrastructure.md","status":"open","priority":2,"issue_type":"epic","created_at":"2025-12-31T16:01:53.804686Z","updated_at":"2025-12-31T16:01:53.804686Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-uvvm","title":"Phase 6: Config merging performance & polish","description":"Performance optimization and polish for the quarto-config merging system.\n\n## Context\n\nThis is Phase 6 of the config merging implementation plan documented in:\n- claude-notes/plans/2025-12-07-config-merging-design.md\n\nPhases 1-5 are complete:\n- Phase 1: quarto-config crate with types, tag parsing, conversion\n- Phase 2: Cursor-based navigation (MergedConfig, MergedCursor)\n- Phase 3: Materialization and error handling\n- Phase 4: quarto-yaml integration (underscore-separated tags)\n- Phase 5: pampa integration (template defaults merging)\n\n## Work Items\n\n### Benchmarking\n- [ ] Create benchmarks comparing Rust implementation to TypeScript mergeConfigs\n- [ ] Measure materialization performance for various config sizes\n- [ ] Benchmark cursor navigation vs eager materialization\n\n### Performance Optimization\n- [ ] Profile hot paths in MergedConfig operations\n- [ ] Consider caching for frequently-accessed subtrees\n- [ ] Evaluate lazy vs eager strategies for different use cases\n- [ ] Optimize IndexMap usage patterns\n\n### Polish\n- [ ] Review and improve documentation\n- [ ] Add more examples to module docs\n- [ ] Consider adding convenience methods based on real usage patterns\n- [ ] Ensure error messages are clear and actionable\n\n### Future Consideration\n- [ ] Evaluate changing quarto-doctemplate to operate directly with MergedConfig (avoiding materialization)\n\n## Related Files\n- crates/quarto-config/src/*.rs (core implementation)\n- crates/pampa/src/template/config_merge.rs (pampa integration)\n- crates/pampa/tests/test_template_integration.rs (integration tests)","status":"open","priority":3,"issue_type":"task","created_at":"2025-12-07T21:11:54.315717Z","updated_at":"2025-12-07T21:11:54.315717Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-vku8","title":"Fix bibliography spacing in quarto-citeproc to_blocks() conversion","description":"The to_blocks() method in quarto-citeproc does not correctly apply CSL group delimiters when converting the Output AST to Pandoc blocks. This results in missing spacing/punctuation between elements (e.g., 'Alice2019' instead of 'Alice. 2019.').\\n\\nPlan: claude-notes/plans/2025-12-05-citeproc-output-spacing.md","status":"open","priority":1,"issue_type":"bug","created_at":"2025-12-05T22:42:14.443669Z","updated_at":"2025-12-05T22:42:14.443669Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["citeproc","output"]} +{"id":"k-vmwg","title":"Phase 2: Implement cursor-based navigation","description":"Implement MergedConfig<'a>, MergedCursor<'a>, MergedValue<'a>, MergedScalar<'a>, MergedArray<'a>, MergedMap<'a>. Implement navigation (at, at_path, exists, keys) and resolution (as_value, as_scalar, as_array, as_map). Property-based tests for associativity. Plan: claude-notes/plans/2025-12-07-config-merging-design.md Phase 2","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-07T20:03:44.486774Z","updated_at":"2025-12-07T20:23:53.601939Z","closed_at":"2025-12-07T20:23:53.601939Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-vmwg","depends_on_id":"k-riq2","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-vmwg","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-vpgx","title":"Design MergedConfig<'a> lifetime and navigation API","description":"Detail the lifetime design for MergedConfig<'a>, including: 1) MergedMap<'a> and MergedArray<'a> structure, 2) Nested navigation API (get chaining), 3) MergedValue<'a> enum design, 4) Borrowed vs owned data handling. Parent: k-zvzm","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-07T17:06:35.783411Z","updated_at":"2025-12-07T20:03:04.849222Z","closed_at":"2025-12-07T20:03:04.849222Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-vpgx","depends_on_id":"k-zvzm","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-w6sb","title":"Improve coverage: quarto-core/src/error.rs","description":"Session baseline: 73.58% line coverage. File at 69.57%. Focus on ParseError and QuartoError.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T16:43:14.831595Z","updated_at":"2026-01-02T16:46:18.557357Z","closed_at":"2026-01-02T16:46:18.557357Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-w6sb","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-xlko","title":"Prototype minimal quarto render for Rust port","description":"Implement a minimal, incrementally-improvable 'quarto render' command in the Rust port. Starts with default project type (single documents), progressively adds project system, engine infrastructure, and format support. See plan: claude-notes/plans/2025-12-20-quarto-render-prototype.md","status":"open","priority":1,"issue_type":"epic","created_at":"2025-12-20T17:41:46.424300Z","updated_at":"2025-12-20T17:41:46.424300Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-xol0","title":"HTML postprocessor analysis and Rust DOM API design","description":"Study quarto-cli HTML postprocessors to understand DOM manipulation patterns and design appropriate Rust API. Plan: claude-notes/plans/2025-12-20-html-postprocessor-analysis.md","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-20T22:20:11.652560Z","updated_at":"2025-12-20T22:20:11.652560Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-xol0","depends_on_id":"k-xlko","type":"discovered-from","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-xvte","title":"Design structural hash-based AST reconciliation algorithm","description":"Design a reconciliation algorithm for PandocAST nodes inspired by React 15's reconciliation. Use structural hashes as virtual keys for node identity since we don't have explicit id keys. The hash of a node = hash(type, content, children_hashes), excluding source locations. This enables O(n) reconciliation with efficient subtree skipping when hashes match.\n\nApproach:\n- Compute structural hashes for both pre-engine and post-engine ASTs\n- Hash serves as 'virtual key' for matching nodes across ASTs\n- If hashes match, subtrees are identical - transfer source locations wholesale\n- If hashes differ but types match, recurse into children\n- Use hash-based alignment for children lists (hash -> node multimap)\n\nPlan: claude-notes/plans/2025-12-17-structural-hash-reconciliation-design.md","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-17T22:25:33.504802Z","updated_at":"2025-12-17T22:25:33.504802Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-xvte","depends_on_id":"k-6daf","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-y2f3","title":"Add doctemplate support to quarto-markdown-pandoc","description":"Add document template support to quarto-markdown-pandoc with both bundle-based (for WASM) and filesystem-based (feature-gated) template resolution.\n\nPlan: claude-notes/plans/2025-12-05-doctemplate-integration.md\n\nKey components:\n1. MetaValue to TemplateValue conversion\n2. Template bundle format (JSON with main + partials)\n3. Library API with PartialResolver support \n4. CLI integration (--template, --template-bundle)\n5. WASM entry points","status":"open","priority":1,"issue_type":"feature","created_at":"2025-12-05T17:14:01.283473Z","updated_at":"2025-12-05T17:14:58.723177Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-y30s","title":"Improve coverage: quarto-core/src/render.rs","description":"Session baseline: 73.65% line coverage. File at 71.43%. Focus on BinaryDependencies, RenderOptions, RenderContext methods.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T16:48:50.925594Z","updated_at":"2026-01-02T16:51:52.729268Z","closed_at":"2026-01-02T16:51:52.729268Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-y30s","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-yd14","title":"Phase 4: Project Type System","description":"REVISED (was Phase 4 Engine Infrastructure): Support project-level configuration. Includes: ProjectType registry with DefaultProjectType, multi-file rendering, output directory handling, project.render globs. Part of k-xlko.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-20T17:42:25.768053Z","updated_at":"2025-12-20T18:09:57.538163Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-yd14","depends_on_id":"k-9aj6","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""},{"issue_id":"k-yd14","depends_on_id":"k-xlko","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-ydzc","title":"Implement knitr engine (Phase 4)","description":"Implement the knitr execution engine for R code cells.\n\nPlan: claude-notes/plans/2026-01-07-knitr-engine-implementation.md\n\n## Overview\n\nPort the TypeScript knitr engine to Rust, enabling R code execution in Quarto documents.\n\n## Key Components\n\n1. **R Script Resources**: rmd.R, execute.R, hooks.R, patch.R, ojs*.R\n2. **Subprocess Management**: Spawn Rscript, communicate via stdin/stdout\n3. **JSON Protocol**: Pass parameters as JSON, receive results as JSON\n4. **Supporting Files**: Track figures and other outputs from execution\n\n## Dependencies\n\n- Requires R and knitr/rmarkdown packages installed\n- Blocked by k-oomv (execution engine infrastructure)","status":"closed","priority":1,"issue_type":"feature","created_at":"2026-01-07T00:47:53.280153002Z","updated_at":"2026-01-07T02:29:24.776640699Z","closed_at":"2026-01-07T02:29:24.776640699Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-ydzc","depends_on_id":"k-oomv","type":"blocks","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-yvfo","title":"Conflict resolution for filesystem/automerge divergence","description":"Design what happens when: (1) hub starts and filesystem differs from stored automerge state, (2) external process modifies .qmd file while hub is running. Options: prefer filesystem, prefer automerge, merge, user prompt.","status":"open","priority":2,"issue_type":"task","created_at":"2025-12-08T19:24:58.012901Z","updated_at":"2025-12-08T19:24:58.012901Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-yvfo","depends_on_id":"k-4wex","type":"related","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-z1ji","title":"Rename quarto-markdown-pandoc crate to pampa","description":"Rename the quarto-markdown-pandoc crate to 'pampa' as part of the project naming strategy. This includes renaming the directory, updating all Cargo.toml references, binary names, source imports, and documentation. See claude-notes/plans/2025-12-06-pampa-rename.md for detailed plan.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-12-06T20:44:48.188293Z","updated_at":"2025-12-06T21:01:18.104329Z","closed_at":"2025-12-06T21:01:18.104329Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-z614","title":"Improve coverage: quarto-core/src/project.rs","description":"Session baseline: 73.37% line coverage. File at 47.65%. Focus on ProjectType, ProjectConfig, DocumentInfo, and ProjectContext pure method tests.","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-02T16:28:52.683198Z","updated_at":"2026-01-02T16:32:17.975741Z","closed_at":"2026-01-02T16:32:17.975741Z","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"k-z614","depends_on_id":"k-uoc5","type":"parent-child","created_at":"2026-02-03T15:17:50Z","created_by":"import","metadata":"{}","thread_id":""}]} +{"id":"k-zplu","title":"Set up Emscripten SDK and build wasm-quarto-hub-client","description":"Install Emscripten SDK, configure build environment, and successfully build wasm-quarto-hub-client for wasm32-unknown-emscripten target.","status":"open","priority":1,"issue_type":"task","created_at":"2025-12-23T01:11:05.668441Z","updated_at":"2025-12-23T01:11:05.668441Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-zr88","title":"Source information tracking for multiple surface syntax formats","description":"Design and implement source location tracking for structured input formats (ipynb, percent scripts) so that error messages can use the coordinate system of the original format (e.g., cell IDs + offsets) rather than positions in the converted qmd.\n\nPlan: claude-notes/plans/2025-12-15-source-info-for-structured-formats.md\nRelated design: claude-notes/surface-syntax-converter-design.md","status":"open","priority":2,"issue_type":"feature","created_at":"2025-12-15T19:41:27.074296Z","updated_at":"2025-12-15T20:13:07.621186Z","source_repo":".","compaction_level":0,"original_size":0} +{"id":"k-zvzm","title":"Design configuration merging system for pampa","description":"Design and document the Rust implementation of Quarto's mergeConfigs functionality. This involves studying existing code in quarto-yaml, pampa, and composable-validation, then proposing an architecture that supports !prefer/!concat tags, source location preservation, and efficient lazy/eager evaluation strategies.\n\nPlan file: claude-notes/plans/2025-12-07-config-merging-design.md","status":"in_progress","priority":1,"issue_type":"feature","created_at":"2025-12-07T15:25:04.943389Z","updated_at":"2025-12-07T15:30:16.359027Z","source_repo":".","compaction_level":0,"original_size":0} diff --git a/claude-notes/plans/2026-02-03-shareable-urls.md b/claude-notes/plans/2026-02-03-shareable-urls.md new file mode 100644 index 00000000..9205b377 --- /dev/null +++ b/claude-notes/plans/2026-02-03-shareable-urls.md @@ -0,0 +1,242 @@ +# Shareable Project URLs for hub-client + +**Issue:** bd-8exa +**Status:** Implementation Complete - Awaiting Manual Testing + +## Overview + +Implement shareable URLs that allow users to share Quarto Hub projects with others. Currently, URLs use local IndexedDB UUIDs which are only meaningful on the same browser/device. Shareable URLs will use the automerge index document ID, enabling cross-device/cross-user sharing. + +## Security Context + +Automerge document IDs behave like **bearer tokens** - anyone with the ID can access the project. This creates several security considerations: + +1. **Minimize URL exposure**: The indexDocId should appear in the URL only when copied/shared. After visiting, the URL should be replaced with a local ID-based URL. +2. **No browser history**: Use `replaceState()` to prevent the shareable URL from appearing in browser history/bookmarks. +3. **No logging**: Never log indexDocId values. + +## Current Architecture + +### URL Scheme (routing.ts) +``` +#/ → Project selector +#/project/ → Project with default file +#/project//file/ → Specific file +#/project//file/# → File + anchor +``` + +### Key Components +- **routing.ts**: URL parsing/building, Route types +- **useRouting.ts**: React hook for navigation +- **App.tsx**: Route resolution, project loading on URL change +- **projectStorage.ts**: IndexedDB operations, has `getProjectByIndexDocId()` +- **ProjectSelector.tsx**: "Connect to existing project" flow + +## Proposed URL Scheme + +### Shareable URL Format +``` +#/share/?server=&file= +``` + +- `indexDocId`: bs58-encoded automerge document ID (without `automerge:` prefix for URL brevity) +- `server`: Sync server URL (**always included** for explicitness) +- `file`: Current file path (**always included** when copying from Editor) + +### Why use query parameters? +- Keeps the URL structure simple +- Allows adding optional parameters without complicating the path +- Server URL can contain special characters that are easier to encode as a query param + +## User Flows + +### Flow 1: Copy Shareable Link + +1. User is in a project, clicks "Share" button (new UI element in Editor header) +2. **Share modal dialog opens** with: + - Warning message: "Anyone with this link can access and edit this project permanently." + - Read-only text field showing the shareable URL + - "Copy Link" button + - "Cancel" button +3. User clicks "Copy Link" +4. URL is copied to clipboard +5. Toast notification: "Link copied to clipboard" +6. Modal closes (or user can close manually) + +### Flow 2: Open Shareable Link (Existing Project) + +1. User visits shareable URL +2. App parses indexDocId from URL +3. App looks up project by indexDocId using `getProjectByIndexDocId()` +4. Project found → Redirect to local ID-based URL (using `replaceState`) +5. Connect to project and display + +### Flow 3: Open Shareable Link (New Project) + +1. User visits shareable URL +2. App parses indexDocId from URL +3. `getProjectByIndexDocId()` returns undefined +4. App shows "Connect to shared project" dialog (pre-filled with indexDocId and server) +5. User confirms and provides optional description +6. System creates local project entry with generated UUID +7. Redirect to local ID-based URL (using `replaceState`) +8. Connect to project and display + +### Flow 4: Invalid/Unreachable Shared Project + +1. User visits shareable URL +2. App parses indexDocId from URL +3. Either: + - Project not found locally AND connection fails → Show error, offer retry + - Server unreachable → Show error, stay on project selector + +## Implementation Plan + +### Phase 1: Route Infrastructure + +- [x] Add `ShareRoute` type to routing.ts +- [x] Update `parseHashRoute()` to recognize `#/share/` pattern +- [x] Parse query parameters (server, file) +- [x] Add `buildShareableUrl()` function +- [x] Add tests for new routing functions + +### Phase 2: Share Link Resolution + +- [x] Create `useShareLinkResolver` hook (or integrate into App.tsx) +- [x] On detecting ShareRoute: + - Extract indexDocId and server from URL + - Immediately replace URL with `#/` (using replaceState) to clear sensitive data + - Look up project by indexDocId + - If found: navigate to local URL + - If not found: show connect dialog +- [x] Handle the file path redirect (if provided in shareable URL) + +### Phase 3: Connect Dialog for Shared Projects + +- [x] Create `ShareConnectDialog` component (or extend ProjectSelector) +- [x] Pre-fill indexDocId and server from shareable URL +- [x] User provides description (optional) +- [x] On confirm: create project entry, connect, navigate to local URL +- [x] On cancel: navigate to project selector + +### Phase 4: Share Dialog UI + +- [x] Create `ShareDialog` component (modal) + - Warning text about permanent access + - Read-only text field with shareable URL + - "Copy Link" button + - "Cancel" button +- [x] Add "Share" button to Editor header (opens ShareDialog) +- [x] Build shareable URL including: + - indexDocId (from project) + - server (from project) + - file (current file path) +- [x] Copy to clipboard using Clipboard API (with fallback) +- [ ] Show toast notification on successful copy (dialog auto-closes after copy) +- [x] Style the modal consistent with existing dialogs (ProjectSelector, NewFileDialog) + +### Phase 5: Edge Cases and Polish + +- [x] Handle URL with invalid indexDocId format (invalid formats fail at connection time - acceptable) +- [x] Handle connection failures gracefully (already implemented via setConnectionError) +- [x] Add loading state during share link resolution (already implemented via setIsConnecting) +- [x] Ensure no sensitive data in console logs (removed indexDocId from console.log) +- [ ] Test browser history behavior (back/forward with shareable links) - manual testing needed + +## Technical Details + +### ShareRoute Type +```typescript +export interface ShareRoute { + type: 'share'; + indexDocId: string; // Without 'automerge:' prefix + syncServer: string; // Always required in generated URLs + filePath?: string; // File to open (always included when copying) +} +``` + +### URL Examples +``` +// Full URL (always generated this way) +#/share/4XyZabc123...?server=wss%3A%2F%2Fsync.automerge.org&file=docs%2Fintro.qmd + +// When parsing, server defaults to wss://sync.automerge.org if somehow missing +``` + +### ShareDialog Component Props +```typescript +interface ShareDialogProps { + isOpen: boolean; + onClose: () => void; + shareableUrl: string; + onCopied?: () => void; // Callback after successful copy +} +``` + +### State Machine for Share Link Resolution + +``` +[URL with ShareRoute] + ↓ +[Clear URL immediately (replaceState to #/)] + ↓ +[Look up by indexDocId] + ↓ + ┌────┴────┐ + ↓ ↓ + [Found] [Not Found] + ↓ ↓ +[Navigate [Show Connect + to local Dialog] + URL] ↓ + ↓ [User confirms] + └────────→↓ + [Navigate to local URL] + [Connect to project] +``` + +## Design Decisions + +1. **Server in URLs**: Always include the server URL, even when it's the default. + - Simplifies the "connect to existing project" flow + - URLs are explicit and future-proof + +2. **File path in URL**: Always include the current file path. + - Recipients open directly to the relevant file + - They can still navigate to other files + +3. **Permanent access warning**: Show a modal dialog with friction before copying. + - Warning text: "Anyone with this link can access and edit this project permanently." + - User must explicitly click "Copy Link" in the modal + - Prevents accidental sharing + +4. **Clipboard permissions**: Use `navigator.clipboard.writeText()` with fallback to `document.execCommand('copy')` for older browsers/HTTP contexts. + +## Testing Strategy + +### Unit Tests (routing.ts) +- Parse shareable URLs with various parameter combinations +- Build shareable URLs from project data +- Edge cases: missing params, special characters, URL encoding + +### Integration Tests +- Share link resolution: existing project found +- Share link resolution: new project flow +- URL replacement (no sensitive data in history) +- Clipboard operations + +### Manual Testing +- Copy link in one browser, open in another (incognito) +- Copy link, close browser, reopen and paste +- Verify browser history doesn't contain indexDocId + +## Risks and Mitigations + +| Risk | Mitigation | +|------|------------| +| IndexDocId leaked via referrer header | Shareable URLs are hash-based (#/share/...) which browsers typically don't send in Referer headers | +| User bookmarks shareable URL before redirect | Replace URL immediately in synchronous code path | +| Clipboard API not available | Provide fallback mechanism | +| Server URL contains special characters | URL-encode the server parameter | +| User accidentally shares sensitive project | Modal dialog with warning adds friction before copying | +| User doesn't understand permanence of sharing | Clear warning text in modal: "permanently" | diff --git a/hub-client/changelog.md b/hub-client/changelog.md index ee979bb0..19d4162d 100644 --- a/hub-client/changelog.md +++ b/hub-client/changelog.md @@ -13,6 +13,10 @@ be in reverse chronological order (latest first). --> +### 2026-02-03 + +- [`d3a33885`](https://github.com/quarto-dev/kyoto/commits/d3a33885): Add shareable project URLs with security warnings for cross-device collaboration + ### 2026-02-02 - [`e9bb9c16`](https://github.com/quarto-dev/kyoto/commits/e9bb9c16): Fix vitest tests failing on fresh clone by resolving workspace packages to source diff --git a/hub-client/src/App.tsx b/hub-client/src/App.tsx index 745442f7..38bc4744 100644 --- a/hub-client/src/App.tsx +++ b/hub-client/src/App.tsx @@ -14,9 +14,21 @@ import { import type { ProjectFile } from './services/wasmRenderer'; import * as projectStorage from './services/projectStorage'; import { useRouting } from './hooks/useRouting'; -import type { Route } from './utils/routing'; +import type { Route, ShareRoute } from './utils/routing'; import './App.css'; +/** + * Data extracted from a shareable link, used to pre-fill the connect dialog. + */ +export interface PendingShareData { + /** The Automerge index document ID (without 'automerge:' prefix) */ + indexDocId: string; + /** The sync server URL */ + syncServer: string; + /** Optional file path to open after connecting */ + filePath?: string; +} + function App() { const [project, setProject] = useState(null); const [files, setFiles] = useState([]); @@ -25,6 +37,9 @@ function App() { const [fileContents, setFileContents] = useState>(new Map()); const [showSaveToast, setShowSaveToast] = useState(false); + // Pending share link data (when user visits a shareable URL for a project they don't have) + const [pendingShareData, setPendingShareData] = useState(null); + // Track if we've done the initial URL-based navigation const initialLoadRef = useRef(false); @@ -114,6 +129,61 @@ function App() { initialLoadRef.current = true; const loadFromUrl = async () => { + // Handle shareable link URLs + if (route.type === 'share') { + // SECURITY: Immediately clear the URL to prevent indexDocId from appearing + // in browser history, bookmarks, or being accidentally shared. + navigateToProjectSelector({ replace: true }); + + const shareRoute = route as ShareRoute; + // Normalize the indexDocId (add 'automerge:' prefix if not present) + const normalizedIndexDocId = shareRoute.indexDocId.startsWith('automerge:') + ? shareRoute.indexDocId + : `automerge:${shareRoute.indexDocId}`; + + // Check if we already have this project locally + const existingProject = await projectStorage.getProjectByIndexDocId(normalizedIndexDocId); + + if (existingProject) { + // Project exists locally - connect to it + setIsConnecting(true); + setConnectionError(null); + try { + const loadedFiles = await connect(existingProject.syncServer, existingProject.indexDocId); + setProject(existingProject); + setFiles(loadedFiles); + + const contents = new Map(); + for (const file of loadedFiles) { + const content = getFileContent(file.path); + if (content !== null) { + contents.set(file.path, content); + } + } + setFileContents(contents); + + // Navigate to the project (and optionally file) using local ID + if (shareRoute.filePath) { + navigateToFile(existingProject.id, shareRoute.filePath, { replace: true }); + } else { + navigateToProject(existingProject.id, { replace: true }); + } + } catch (err) { + setConnectionError(err instanceof Error ? err.message : String(err)); + } finally { + setIsConnecting(false); + } + } else { + // Project doesn't exist locally - show connect dialog with pre-filled data + setPendingShareData({ + indexDocId: shareRoute.indexDocId, + syncServer: shareRoute.syncServer, + filePath: shareRoute.filePath, + }); + } + return; + } + if (route.type === 'project' || route.type === 'file') { // URL specifies a project - try to load it const targetProject = await projectStorage.getProject(route.projectId); @@ -150,7 +220,7 @@ function App() { }; loadFromUrl(); - }, [route, navigateToProjectSelector]); + }, [route, navigateToProjectSelector, navigateToProject, navigateToFile]); // Intercept Ctrl+S / Cmd+S to prevent browser save dialog useEffect(() => { @@ -202,7 +272,10 @@ function App() { }); }, [project]); - const handleSelectProject = useCallback(async (selectedProject: ProjectEntry) => { + const handleSelectProject = useCallback(async (selectedProject: ProjectEntry, filePathOverride?: string) => { + // Clear any pending share data + setPendingShareData(null); + setIsConnecting(true); setConnectionError(null); @@ -221,14 +294,18 @@ function App() { } setFileContents(contents); - // Update URL to reflect the selected project - navigateToProject(selectedProject.id, { replace: true }); + // Update URL to reflect the selected project (and optionally a specific file) + if (filePathOverride) { + navigateToFile(selectedProject.id, filePathOverride, { replace: true }); + } else { + navigateToProject(selectedProject.id, { replace: true }); + } } catch (err) { setConnectionError(err instanceof Error ? err.message : String(err)); } finally { setIsConnecting(false); } - }, [navigateToProject]); + }, [navigateToProject, navigateToFile]); const handleDisconnect = useCallback(async () => { await disconnect(); @@ -295,8 +372,6 @@ function App() { // Update URL to reflect the new project navigateToProject(projectEntry.id, { replace: true }); - - console.log('Project created successfully:', result.indexDocId); } catch (err) { setConnectionError(err instanceof Error ? err.message : String(err)); } finally { @@ -304,6 +379,10 @@ function App() { } }, [navigateToProject]); + const handleClearPendingShare = useCallback(() => { + setPendingShareData(null); + }, []); + return ( <> {!project ? ( @@ -312,6 +391,8 @@ function App() { onProjectCreated={handleProjectCreated} isConnecting={isConnecting} error={connectionError} + pendingShareData={pendingShareData} + onClearPendingShare={handleClearPendingShare} /> ) : ( (''); + // Share dialog state + const [showShareDialog, setShowShareDialog] = useState(false); + // Editor drag-drop state for image insertion const [isEditorDragOver, setIsEditorDragOver] = useState(false); const pendingDropPositionRef = useRef(null); @@ -393,6 +397,18 @@ export default function Editor({ project, files, fileContents, onDisconnect, onC } }, [project.id]); + // Handle opening share dialog + const handleShare = useCallback(() => { + setShowShareDialog(true); + }, []); + + // Build shareable URL for the current file + const shareableUrl = buildShareableUrl( + project.indexDocId, + project.syncServer, + currentFile?.path + ); + // Handle opening new file dialog const handleNewFile = useCallback(() => { setPendingUploadFiles([]); @@ -607,6 +623,7 @@ export default function Editor({ project, files, fileContents, onDisconnect, onC currentFilePath={currentFile?.path ?? null} projectName={project.description} onChooseNewProject={onDisconnect} + onShare={handleShare} /> {unlocatedErrors.length > 0 && ( @@ -732,6 +749,13 @@ export default function Editor({ project, files, fileContents, onDisconnect, onC initialFiles={pendingUploadFiles} initialFilename={newFileInitialName} /> + + {/* Share project dialog */} + setShowShareDialog(false)} + />
); } diff --git a/hub-client/src/components/MinimalHeader.css b/hub-client/src/components/MinimalHeader.css index 765129f8..e8474bfe 100644 --- a/hub-client/src/components/MinimalHeader.css +++ b/hub-client/src/components/MinimalHeader.css @@ -59,3 +59,19 @@ border-color: #646cff; color: #646cff; } + +.header-right .share-btn { + padding: 4px 10px; + background: #646cff; + border: 1px solid #646cff; + border-radius: 4px; + color: #fff; + font-size: 12px; + cursor: pointer; + transition: all 0.15s; +} + +.header-right .share-btn:hover { + background: #5558dd; + border-color: #5558dd; +} diff --git a/hub-client/src/components/MinimalHeader.tsx b/hub-client/src/components/MinimalHeader.tsx index 4acc5091..3a76712f 100644 --- a/hub-client/src/components/MinimalHeader.tsx +++ b/hub-client/src/components/MinimalHeader.tsx @@ -11,12 +11,15 @@ interface MinimalHeaderProps { currentFilePath: string | null; projectName: string; onChooseNewProject: () => void; + /** Called when user wants to share the project */ + onShare?: () => void; } export default function MinimalHeader({ currentFilePath, projectName, onChooseNewProject, + onShare, }: MinimalHeaderProps) { return (
@@ -29,6 +32,11 @@ export default function MinimalHeader({
{projectName} + {onShare && ( + + )} diff --git a/hub-client/src/components/ProjectSelector.tsx b/hub-client/src/components/ProjectSelector.tsx index 6268465c..f36073aa 100644 --- a/hub-client/src/components/ProjectSelector.tsx +++ b/hub-client/src/components/ProjectSelector.tsx @@ -1,6 +1,7 @@ import { useState, useEffect, useCallback } from 'react'; import type { ProjectEntry } from '../types/project'; import type { UserSettings } from '../services/storage/types'; +import type { PendingShareData } from '../App'; import * as projectStorage from '../services/projectStorage'; import * as userSettingsService from '../services/userSettings'; import { @@ -12,11 +13,16 @@ import { import './ProjectSelector.css'; interface Props { - onSelectProject: (project: ProjectEntry) => void; + /** Called when a project is selected, with optional file path override from share link */ + onSelectProject: (project: ProjectEntry, filePathOverride?: string) => void; isConnecting?: boolean; error?: string | null; /** Called when a new project is created with scaffold files */ onProjectCreated?: (files: ProjectFile[], title: string, projectType: string, syncServer: string) => void; + /** Pre-filled data from a shareable link (indexDocId, syncServer, optional filePath) */ + pendingShareData?: PendingShareData | null; + /** Called when pending share data should be cleared (e.g., user cancels) */ + onClearPendingShare?: () => void; } // Curated color palette for user selection @@ -26,7 +32,14 @@ const COLOR_PALETTE = [ '#8BC34A', '#FF9800', '#FF5722', '#795548', ]; -export default function ProjectSelector({ onSelectProject, isConnecting, error: connectionError, onProjectCreated }: Props) { +export default function ProjectSelector({ + onSelectProject, + isConnecting, + error: connectionError, + onProjectCreated, + pendingShareData, + onClearPendingShare, +}: Props) { const [projects, setProjects] = useState([]); const [loading, setLoading] = useState(true); const [showConnectForm, setShowConnectForm] = useState(false); @@ -37,6 +50,8 @@ export default function ProjectSelector({ onSelectProject, isConnecting, error: const [syncServer, setSyncServer] = useState('wss://sync.automerge.org'); const [description, setDescription] = useState(''); const [formError, setFormError] = useState(null); + // Track file path from share link (to navigate after connect) + const [shareFilePath, setShareFilePath] = useState(undefined); // Create form state const [createProjectType, setCreateProjectType] = useState(''); @@ -95,6 +110,19 @@ export default function ProjectSelector({ onSelectProject, isConnecting, error: loadProjectChoices(); }, [loadProjects, loadUserSettings, loadProjectChoices]); + // Handle pending share data (from shareable URL) + useEffect(() => { + if (pendingShareData) { + // Pre-fill the connect form with share data + setIndexDocId(pendingShareData.indexDocId); + setSyncServer(pendingShareData.syncServer); + setShareFilePath(pendingShareData.filePath); + // Auto-show the connect form + setShowConnectForm(true); + setShowCreateForm(false); + } + }, [pendingShareData]); + const handleStartEditName = () => { if (userSettings) { setEditNameValue(userSettings.userName); @@ -175,17 +203,32 @@ export default function ProjectSelector({ onSelectProject, isConnecting, error: syncServer.trim(), description.trim() || undefined ); + + // Capture file path before clearing state + const filePathToNavigate = shareFilePath; + setIndexDocId(''); setDescription(''); + setShareFilePath(undefined); setShowConnectForm(false); await loadProjects(); - onSelectProject(project); + + // Pass the file path from share link (if any) to parent + onSelectProject(project, filePathToNavigate); } catch (err) { console.error('Failed to add project:', err); setFormError('Failed to add project. The document ID may already exist.'); } }; + const handleCancelConnect = () => { + setShowConnectForm(false); + setIndexDocId(''); + setShareFilePath(undefined); + // Clear pending share data if user explicitly cancels + onClearPendingShare?.(); + }; + const handleCreateProject = async (e: React.FormEvent) => { e.preventDefault(); setFormError(null); @@ -422,8 +465,12 @@ export default function ProjectSelector({ onSelectProject, isConnecting, error: {/* Connect to Project form */} {showConnectForm && (
-

Connect to Project

-

Enter the document ID of an existing Automerge project

+

{pendingShareData ? 'Connect to Shared Project' : 'Connect to Project'}

+

+ {pendingShareData + ? 'Someone shared this project with you. Add a name and connect.' + : 'Enter the document ID of an existing Automerge project'} +

- +
diff --git a/hub-client/src/components/ShareDialog.css b/hub-client/src/components/ShareDialog.css new file mode 100644 index 00000000..7ca0749b --- /dev/null +++ b/hub-client/src/components/ShareDialog.css @@ -0,0 +1,152 @@ +/* Share Dialog - uses common dialog-overlay from NewFileDialog.css */ + +.share-dialog { + background: #1e1e1e; + border: 1px solid #333; + border-radius: 12px; + width: 90%; + max-width: 520px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); +} + +.share-dialog .dialog-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px 20px; + border-bottom: 1px solid #333; +} + +.share-dialog .dialog-header h2 { + margin: 0; + font-size: 18px; + font-weight: 600; + color: #fff; +} + +.share-dialog .close-btn { + background: none; + border: none; + color: #888; + font-size: 24px; + cursor: pointer; + padding: 0; + line-height: 1; + transition: color 0.2s; +} + +.share-dialog .close-btn:hover { + color: #fff; +} + +.share-dialog .dialog-content { + padding: 20px; +} + +/* Warning box */ +.warning-box { + background: #3d3020; + border: 1px solid #5a4520; + border-radius: 8px; + padding: 16px; + margin-bottom: 20px; +} + +.warning-box .warning-icon { + display: inline-block; + font-size: 24px; + margin-bottom: 8px; + color: #f59e0b; +} + +.warning-box p { + margin: 0 0 8px; + color: #fbbf24; + font-size: 14px; + line-height: 1.5; +} + +.warning-box p:last-child { + margin-bottom: 0; +} + +.warning-box .warning-detail { + color: #d4a644; + font-size: 13px; +} + +/* URL field */ +.url-field { + margin-top: 16px; +} + +.url-field label { + display: block; + margin-bottom: 8px; + color: #ccc; + font-size: 14px; +} + +.url-field input { + width: 100%; + padding: 12px; + background: #2d2d2d; + border: 1px solid #444; + border-radius: 6px; + color: #888; + font-size: 13px; + font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; + box-sizing: border-box; + cursor: text; +} + +.url-field input:focus { + outline: none; + border-color: #646cff; + color: #ccc; +} + +/* Actions */ +.share-dialog .dialog-actions { + display: flex; + justify-content: flex-end; + gap: 12px; + padding: 16px 20px; + border-top: 1px solid #333; +} + +.share-dialog .cancel-btn { + padding: 10px 20px; + background: none; + border: 1px solid #444; + border-radius: 6px; + color: #888; + font-size: 14px; + cursor: pointer; + transition: all 0.2s; +} + +.share-dialog .cancel-btn:hover { + border-color: #666; + color: #ccc; +} + +.share-dialog .copy-btn { + padding: 10px 24px; + background: #646cff; + border: none; + border-radius: 6px; + color: #fff; + font-size: 14px; + font-weight: 500; + cursor: pointer; + transition: all 0.2s; +} + +.share-dialog .copy-btn:hover { + background: #5558dd; +} + +.share-dialog .copy-btn.copied { + background: #22c55e; +} diff --git a/hub-client/src/components/ShareDialog.tsx b/hub-client/src/components/ShareDialog.tsx new file mode 100644 index 00000000..183a86bb --- /dev/null +++ b/hub-client/src/components/ShareDialog.tsx @@ -0,0 +1,137 @@ +/** + * Share Dialog Component + * + * Modal dialog for sharing a project with a shareable URL. + * Displays a warning about permanent access and allows copying the link. + */ + +import { useState, useCallback, useRef, useEffect } from 'react'; +import './ShareDialog.css'; + +export interface ShareDialogProps { + isOpen: boolean; + shareableUrl: string; + onClose: () => void; + onCopied?: () => void; +} + +export default function ShareDialog({ + isOpen, + shareableUrl, + onClose, + onCopied, +}: ShareDialogProps) { + const [copied, setCopied] = useState(false); + const urlInputRef = useRef(null); + + // Reset copied state when dialog opens + useEffect(() => { + if (isOpen) { + setCopied(false); + } + }, [isOpen]); + + // Select all text when dialog opens + useEffect(() => { + if (isOpen && urlInputRef.current) { + setTimeout(() => { + urlInputRef.current?.select(); + }, 100); + } + }, [isOpen]); + + const handleCopyLink = useCallback(async () => { + try { + // Try modern Clipboard API first + if (navigator.clipboard && navigator.clipboard.writeText) { + await navigator.clipboard.writeText(shareableUrl); + } else { + // Fallback for older browsers or HTTP contexts + const textArea = document.createElement('textarea'); + textArea.value = shareableUrl; + textArea.style.position = 'fixed'; + textArea.style.left = '-9999px'; + document.body.appendChild(textArea); + textArea.select(); + document.execCommand('copy'); + document.body.removeChild(textArea); + } + + setCopied(true); + onCopied?.(); + + // Close dialog after a brief delay to show the success state + setTimeout(() => { + onClose(); + }, 500); + } catch (err) { + console.error('Failed to copy to clipboard:', err); + } + }, [shareableUrl, onCopied, onClose]); + + const handleKeyDown = useCallback( + (e: React.KeyboardEvent) => { + if (e.key === 'Escape') { + onClose(); + } else if (e.key === 'Enter') { + handleCopyLink(); + } + }, + [onClose, handleCopyLink] + ); + + if (!isOpen) return null; + + return ( +
+
e.stopPropagation()} + onKeyDown={handleKeyDown} + > +
+

Share Project

+ +
+ +
+
+ +

+ Anyone with this link can access and edit this project permanently. +

+

+ Only share with people you trust. This link cannot be revoked. +

+
+ +
+ + (e.target as HTMLInputElement).select()} + /> +
+
+ +
+ + +
+
+
+ ); +} diff --git a/hub-client/src/utils/routing.test.ts b/hub-client/src/utils/routing.test.ts index 63b22d19..e43f5571 100644 --- a/hub-client/src/utils/routing.test.ts +++ b/hub-client/src/utils/routing.test.ts @@ -1,13 +1,16 @@ /** * Tests for URL routing utilities. */ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { parseHashRoute, buildHashRoute, + buildShareableUrl, routesEqual, sameFile, + DEFAULT_SYNC_SERVER, type Route, + type ShareRoute, } from './routing'; describe('parseHashRoute', () => { @@ -114,6 +117,63 @@ describe('parseHashRoute', () => { }); }); }); + + describe('share routes', () => { + it('parses share route with minimal params', () => { + const result = parseHashRoute('#/share/4XyZabc123'); + expect(result).toEqual({ + type: 'share', + indexDocId: '4XyZabc123', + syncServer: DEFAULT_SYNC_SERVER, + }); + }); + + it('parses share route with server param', () => { + const result = parseHashRoute('#/share/4XyZabc123?server=wss%3A%2F%2Fmy-server.com'); + expect(result).toEqual({ + type: 'share', + indexDocId: '4XyZabc123', + syncServer: 'wss://my-server.com', + }); + }); + + it('parses share route with server and file params', () => { + const result = parseHashRoute( + '#/share/4XyZabc123?server=wss%3A%2F%2Fsync.automerge.org&file=docs%2Fintro.qmd' + ); + expect(result).toEqual({ + type: 'share', + indexDocId: '4XyZabc123', + syncServer: 'wss://sync.automerge.org', + filePath: 'docs/intro.qmd', + }); + }); + + it('parses share route with file param only (uses default server)', () => { + const result = parseHashRoute('#/share/4XyZabc123?file=index.qmd'); + expect(result).toEqual({ + type: 'share', + indexDocId: '4XyZabc123', + syncServer: DEFAULT_SYNC_SERVER, + filePath: 'index.qmd', + }); + }); + + it('decodes URL-encoded indexDocId', () => { + // bs58 can contain characters that need encoding + const result = parseHashRoute('#/share/abc%2B123'); + expect(result).toEqual({ + type: 'share', + indexDocId: 'abc+123', + syncServer: DEFAULT_SYNC_SERVER, + }); + }); + + it('returns project-selector when share route has no indexDocId', () => { + expect(parseHashRoute('#/share/')).toEqual({ type: 'project-selector' }); + expect(parseHashRoute('#/share')).toEqual({ type: 'project-selector' }); + }); + }); }); describe('buildHashRoute', () => { @@ -173,6 +233,41 @@ describe('buildHashRoute', () => { ).toBe('#/project/abc/file/my%20file.qmd'); }); }); + + describe('share routes', () => { + it('builds share route with server', () => { + const route: ShareRoute = { + type: 'share', + indexDocId: '4XyZabc123', + syncServer: 'wss://sync.automerge.org', + }; + const result = buildHashRoute(route); + expect(result).toBe('#/share/4XyZabc123?server=wss%3A%2F%2Fsync.automerge.org'); + }); + + it('builds share route with server and file', () => { + const route: ShareRoute = { + type: 'share', + indexDocId: '4XyZabc123', + syncServer: 'wss://sync.automerge.org', + filePath: 'docs/intro.qmd', + }; + const result = buildHashRoute(route); + expect(result).toBe( + '#/share/4XyZabc123?server=wss%3A%2F%2Fsync.automerge.org&file=docs%2Fintro.qmd' + ); + }); + + it('encodes indexDocId with special characters', () => { + const route: ShareRoute = { + type: 'share', + indexDocId: 'abc+123', + syncServer: 'wss://sync.automerge.org', + }; + const result = buildHashRoute(route); + expect(result).toBe('#/share/abc%2B123?server=wss%3A%2F%2Fsync.automerge.org'); + }); + }); }); describe('round-trip parsing', () => { @@ -186,6 +281,12 @@ describe('round-trip parsing', () => { { type: 'file', projectId: 'abc', filePath: 'index.qmd', anchor: 'intro' }, { type: 'file', projectId: 'abc', filePath: 'docs/api.qmd', anchor: 'methods' }, { type: 'file', projectId: 'abc', filePath: 'my file.qmd' }, + // Share routes + { type: 'share', indexDocId: '4XyZabc123', syncServer: 'wss://sync.automerge.org' }, + { type: 'share', indexDocId: '4XyZabc123', syncServer: 'wss://my-server.com' }, + { type: 'share', indexDocId: '4XyZabc123', syncServer: 'wss://sync.automerge.org', filePath: 'index.qmd' }, + { type: 'share', indexDocId: '4XyZabc123', syncServer: 'wss://sync.automerge.org', filePath: 'docs/intro.qmd' }, + { type: 'share', indexDocId: 'abc+123', syncServer: 'wss://sync.automerge.org' }, ]; for (const route of testCases) { @@ -197,6 +298,47 @@ describe('round-trip parsing', () => { } }); +describe('buildShareableUrl', () => { + // Mock window for node environment + const originalWindow = globalThis.window; + + beforeAll(() => { + // @ts-expect-error - mocking window in node environment + globalThis.window = { + location: { + origin: 'https://example.com', + pathname: '/hub/', + }, + }; + }); + + afterAll(() => { + // @ts-expect-error - restoring window + globalThis.window = originalWindow; + }); + + it('builds shareable URL with all params', () => { + const url = buildShareableUrl('4XyZabc123', 'wss://sync.automerge.org', 'docs/intro.qmd'); + expect(url).toBe( + 'https://example.com/hub/#/share/4XyZabc123?server=wss%3A%2F%2Fsync.automerge.org&file=docs%2Fintro.qmd' + ); + }); + + it('builds shareable URL without file path', () => { + const url = buildShareableUrl('4XyZabc123', 'wss://sync.automerge.org'); + expect(url).toBe( + 'https://example.com/hub/#/share/4XyZabc123?server=wss%3A%2F%2Fsync.automerge.org' + ); + }); + + it('strips automerge: prefix from indexDocId', () => { + const url = buildShareableUrl('automerge:4XyZabc123', 'wss://sync.automerge.org'); + expect(url).toBe( + 'https://example.com/hub/#/share/4XyZabc123?server=wss%3A%2F%2Fsync.automerge.org' + ); + }); +}); + describe('routesEqual', () => { it('returns true for equal project selector routes', () => { expect( @@ -245,6 +387,60 @@ describe('routesEqual', () => { routesEqual({ type: 'project-selector' }, { type: 'project', projectId: 'abc' }) ).toBe(false); }); + + it('returns true for equal share routes', () => { + expect( + routesEqual( + { type: 'share', indexDocId: 'abc', syncServer: 'wss://a.com' }, + { type: 'share', indexDocId: 'abc', syncServer: 'wss://a.com' } + ) + ).toBe(true); + }); + + it('returns false for different share route indexDocIds', () => { + expect( + routesEqual( + { type: 'share', indexDocId: 'abc', syncServer: 'wss://a.com' }, + { type: 'share', indexDocId: 'xyz', syncServer: 'wss://a.com' } + ) + ).toBe(false); + }); + + it('returns false for different share route servers', () => { + expect( + routesEqual( + { type: 'share', indexDocId: 'abc', syncServer: 'wss://a.com' }, + { type: 'share', indexDocId: 'abc', syncServer: 'wss://b.com' } + ) + ).toBe(false); + }); + + it('returns true for equal share routes with file paths', () => { + expect( + routesEqual( + { type: 'share', indexDocId: 'abc', syncServer: 'wss://a.com', filePath: 'x.qmd' }, + { type: 'share', indexDocId: 'abc', syncServer: 'wss://a.com', filePath: 'x.qmd' } + ) + ).toBe(true); + }); + + it('returns false for different share route file paths', () => { + expect( + routesEqual( + { type: 'share', indexDocId: 'abc', syncServer: 'wss://a.com', filePath: 'x.qmd' }, + { type: 'share', indexDocId: 'abc', syncServer: 'wss://a.com', filePath: 'y.qmd' } + ) + ).toBe(false); + }); + + it('returns false for share route vs project route', () => { + expect( + routesEqual( + { type: 'share', indexDocId: 'abc', syncServer: 'wss://a.com' }, + { type: 'project', projectId: 'abc' } + ) + ).toBe(false); + }); }); describe('sameFile', () => { diff --git a/hub-client/src/utils/routing.ts b/hub-client/src/utils/routing.ts index 487c5784..d6e6a0bb 100644 --- a/hub-client/src/utils/routing.ts +++ b/hub-client/src/utils/routing.ts @@ -6,6 +6,7 @@ * #/project/ → Project with default file * #/project//file/ → Specific file * #/project//file/#
→ Specific file + anchor + * #/share/?server=&file= → Shareable link (temporary) * * Security: We use the local IndexedDB project ID (a UUID) instead of * the indexDocId (Automerge DocumentId). The indexDocId acts like a bearer @@ -13,9 +14,15 @@ * * The local ID is only meaningful on the same browser/device, which means * URLs are not shareable across devices. This is intentional - sharing a - * project would require an explicit "share" flow with proper authorization. + * project requires an explicit "share" flow that generates a temporary + * shareable URL containing the indexDocId. When such a URL is visited, + * it should be immediately replaced with a local URL to prevent the + * sensitive indexDocId from appearing in browser history or bookmarks. */ +/** Default sync server URL used when not specified in shareable URLs */ +export const DEFAULT_SYNC_SERVER = 'wss://sync.automerge.org'; + // ============================================================================ // Types // ============================================================================ @@ -45,10 +52,31 @@ export interface FileRoute { anchor?: string; } +/** + * Route from a shareable link containing an Automerge document ID. + * + * SECURITY: This route type should only exist transiently during URL resolution. + * The URL should be immediately replaced with a local URL (project-selector, + * project, or file) to prevent the sensitive indexDocId from appearing in + * browser history or bookmarks. + * + * The indexDocId is stored WITHOUT the 'automerge:' prefix for URL brevity. + * It should be normalized (prefix added) before use with Automerge APIs. + */ +export interface ShareRoute { + type: 'share'; + /** bs58-encoded Automerge document ID (without 'automerge:' prefix) */ + indexDocId: string; + /** Sync server URL (defaults to DEFAULT_SYNC_SERVER if not in URL) */ + syncServer: string; + /** Optional file path to open after connecting */ + filePath?: string; +} + /** * Union of all possible routes. */ -export type Route = ProjectSelectorRoute | ProjectRoute | FileRoute; +export type Route = ProjectSelectorRoute | ProjectRoute | FileRoute | ShareRoute; // ============================================================================ // URL Parsing @@ -77,6 +105,14 @@ export function parseHashRoute(hash: string): Route { // Remove leading # if present let path = hash.startsWith('#') ? hash.slice(1) : hash; + // Extract query parameters (for share URLs) + let queryParams = new URLSearchParams(); + const queryIndex = path.indexOf('?'); + if (queryIndex !== -1) { + queryParams = new URLSearchParams(path.slice(queryIndex + 1)); + path = path.slice(0, queryIndex); + } + // Extract anchor (everything after the last # in the path portion) // Note: The anchor is after the hash fragment marker in the URL let anchor: string | undefined; @@ -94,6 +130,21 @@ export function parseHashRoute(hash: string): Route { // Split into segments const segments = path.split('/'); + // Parse share route: /share/ + if (segments[0] === 'share' && segments[1]) { + const indexDocId = decodeURIComponent(segments[1]); + const syncServer = queryParams.get('server') || DEFAULT_SYNC_SERVER; + const fileParam = queryParams.get('file'); + const filePath = fileParam ? decodeURIComponent(fileParam) : undefined; + + return { + type: 'share', + indexDocId, + syncServer, + ...(filePath && { filePath }), + }; + } + // Parse route based on segments if (segments[0] === 'project' && segments[1]) { const projectId = segments[1]; @@ -159,6 +210,16 @@ export function buildHashRoute(route: Route): string { const base = `#/project/${route.projectId}/file/${encodedPath}`; return route.anchor ? `${base}#${route.anchor}` : base; } + + case 'share': { + // Build shareable URL with query parameters + const params = new URLSearchParams(); + params.set('server', route.syncServer); + if (route.filePath) { + params.set('file', route.filePath); + } + return `#/share/${encodeURIComponent(route.indexDocId)}?${params.toString()}`; + } } } @@ -177,6 +238,41 @@ export function buildFullUrl(route: Route): string { return `${window.location.origin}${window.location.pathname}${hash}`; } +/** + * Build a shareable URL for a project. + * + * This URL contains the Automerge indexDocId and should be treated as sensitive. + * The recipient can use this URL to connect to the project. When they visit it, + * the app should immediately replace the URL with a local URL to prevent the + * sensitive data from appearing in browser history. + * + * @param indexDocId - The Automerge document ID (without 'automerge:' prefix) + * @param syncServer - The sync server URL + * @param filePath - Optional file path to open after connecting + * @returns Full shareable URL + * + * @example + * buildShareableUrl('4XyZabc123', 'wss://sync.automerge.org', 'docs/intro.qmd') + * // 'https://example.com/hub/#/share/4XyZabc123?server=wss%3A%2F%2Fsync.automerge.org&file=docs%2Fintro.qmd' + */ +export function buildShareableUrl( + indexDocId: string, + syncServer: string, + filePath?: string +): string { + // Remove 'automerge:' prefix if present (we store it without prefix in URLs) + const cleanIndexDocId = indexDocId.replace(/^automerge:/, ''); + + const route: ShareRoute = { + type: 'share', + indexDocId: cleanIndexDocId, + syncServer, + ...(filePath && { filePath }), + }; + + return buildFullUrl(route); +} + /** * Update the browser URL without triggering navigation. * @@ -234,6 +330,15 @@ export function routesEqual(a: Route, b: Route): boolean { a.anchor === bFile.anchor ); } + + case 'share': { + const bShare = b as ShareRoute; + return ( + a.indexDocId === bShare.indexDocId && + a.syncServer === bShare.syncServer && + a.filePath === bShare.filePath + ); + } } }